作者|B. Chen 编译|VK 来源|Towards Data Science

Pandas DataFrame有一个内置方法sort_values(),可以根据给定的变量对值进行排序。该方法本身使用起来相当简单,但是它不适用于自定义排序,例如,

  • t恤尺寸:XS、S、M、L和XL

  • 月份:一月、二月、三月、四月等

  • 星期几:周一、周二、周三、周四、周五、周六和周日。

在本文中,我们将了解如何对Pandas DataFrame进行自定义排序。

请查看我的Github repo以获取源代码:https://github.com/BindiChen/machine-learning/blob/master/data-analysis/017-pandas-custom-sort/pandas-custom-sort.ipynb

问题

假设我们有一个关于服装店的数据集:

df = pd.DataFrame({'cloth_id': [1001, 1002, 1003, 1004, 1005, 1006],'size': ['S', 'XL', 'M', 'XS', 'L', 'S'],
})

我们可以看到,每一块布料都有一个尺寸值,数据应该按以下顺序排序:

  • XS代表特大号

  • S代表小号

  • M代表中号

  • L代表大号

  • XL为特大号

但是,当调用sort_values('size')时,将得到以下输出。

输出不是我们想要的,但它在技术上是正确的。实际上,sort_values()是按数字顺序对数值数据排序,对对象数据按字母顺序排序。

以下是两种常见的解决方案:

  1. 为自定义排序创建新列

  2. 使用CategoricalDtype将数据强制转换为具有有序性的类别类型

为自定义排序创建新列

在这个解决方案中,需要一个映射数据帧来表示一个自定义排序,然后根据映射创建一个新的列,最后我们可以按新列对数据进行排序。让我们通过一个例子来看看这是如何工作的。

首先,让我们创建一个映射数据帧来表示自定义排序。

df_mapping = pd.DataFrame({'size': ['XS', 'S', 'M', 'L', 'XL'],
})sort_mapping = df_mapping.reset_index().set_index('size')

之后,使用sort_mapping中的映射值创建一个新的列 size_num。

df['size_num'] = df['size'].map(sort_mapping['index'])

最后,按新的列大小对值进行排序。

df.sort_values('size_num')

这当然是我们的工作。但它创建了一个备用列,在处理大型数据集时效率可能会降低。

我们可以使用CategoricalDtype更有效地解决这个问题。

使用CategoricalDtype将数据强制转换为具有有序性的类别类型

CategoricalDtype是具有类别和顺序的分类数据的类型[1]。它对于创建自定义排序非常有用[2]。让我们通过一个例子来看看这是如何工作的。

首先,让我们导入CategoricalDtype。

from pandas.api.types import CategoricalDtype

然后,创建一个自定义类别类型cat_size_order

  • 第一个参数设置为['XS'、'S'、'M'、'L'、'XL']作为尺寸的唯一值。

  • 第二个参数ordered=True,将此变量视为有序。

cat_size_order = CategoricalDtype(['XS', 'S', 'M', 'L', 'XL'], ordered=True
)

然后,调用astype(cat_size_order)将大小数据强制转换为自定义类别类型。通过运行df['size'],我们可以看到size列已经被转换为一个类别类型,其顺序为[XS<S<M<L<XL]。

>>> df['size'] = df['size'].astype(cat_size_order)
>>> df['size']0     S
1    XL
2     M
3    XS
4     L
5     S
Name: size, dtype: category
Categories (5, object): [XS < S < M < L < XL]

最后,我们可以调用相同的方法对值进行排序。

df.sort_values('size')

这样效果更好。让我们来看看原理是什么。

使用cat的codes属性访问

现在size列已经被转换为category类型,我们可以使用.cat访问器以查看分类属性。在幕后,它使用codes属性来表示有序变量的大小。

让我们创建一个新的列代码,这样我们可以并排比较大小和代码值。

df['codes'] = df['size'].cat.codes
df

我们可以看到XS、S、M、L和XL的代码分别为0、1、2、3、4和5。codes是类别实际值。通过运行http://df.info(),我们可以看到实际上是int8。

>>> df.info()<class 'pandas.core.frame.DataFrame'>
RangeIndex: 6 entries, 0 to 5
Data columns (total 3 columns):#   Column    Non-Null Count  Dtype
---  ------    --------------  -----   0   cloth_id  6 non-null      int64   1   size      6 non-null      category2   codes     6 non-null      int8
dtypes: category(1), int64(1), int8(1)
memory usage: 388.0 bytes

按多个变量排序

接下来,让我们把事情变得更复杂一点。这里,我们将按多个变量对数据帧进行排序。

df = pd.DataFrame({'order_id': [1001, 1002, 1003, 1004, 1005, 1006, 1007],'customer_id': [10, 12, 12, 12, 10, 10, 10],'month': ['Feb', 'Jan', 'Jan', 'Feb', 'Feb', 'Jan', 'Feb'],'day_of_week': ['Mon', 'Wed', 'Sun', 'Tue', 'Sat', 'Mon', 'Thu'],
})

类似地,让我们创建两个自定义类别类型cat_day_of_week和cat_month,并将它们传递给astype()。

cat_day_of_week = CategoricalDtype(['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], ordered=True
)cat_month = CategoricalDtype(['Jan', 'Feb', 'Mar', 'Apr'], ordered=True,
)df['day_of_week'] = df['day_of_week'].astype(cat_day_of_week)
df['month'] = df['month'].astype(cat_month)

要按多个变量排序,我们只需要传递一个列表来代替sort_values()。例如,按monthday_of_week排序。

df.sort_values(['month', 'day_of_week'])

ustomer_idmonthday_of_week排序。

df.sort_values(['customer_id', 'month', 'day_of_week'])

就这样,谢谢你的阅读。

请在我的Github上导出笔记本以获取源代码:https://github.com/BindiChen/machine-learning/blob/master/data-analysis/017-pandas-custom-sort/pandas-custom-sort.ipynb

参考引用

  • [1] Pandas.CategoricalDtype API(https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.CategoricalDtype.html)
  • [2] Pandas Categorical CategoricalDtype tutorial (https://pandas.pydata.org/pandas-docs/stable/user_guide/categorical.html#categorical-categoricaldtype)

原文链接:https://towardsdatascience.com/how-to-do-a-custom-sort-on-pandas-dataframe-ac18e7ea5320

dataframe 排序_如何对Pandas DataFrame进行自定义排序相关推荐

  1. Pandas 根据category自定义排序

    Pandas 根据category自定义排序 import pandas as pddf = pd.DataFrame({"name": [*'abcde'], "num ...

  2. 自定义列_如何对Pandas DataFrame进行自定义排序

    Pandas DataFrame有一个内置方法sort_values(),可以根据给定的变量对值进行排序.该方法本身使用起来相当简单,但是它不适用于自定义排序,例如, t恤尺寸:XS.S.M.L和XL ...

  3. python交换两列的位置_如何更改 pandas dataframe 中两列的位置

    如何更改 pandas dataframe 中两列的位置: 把其中的某列移到第一列的位置. 原来的 df 是: df = pd.read_csv('I:/Papers/consumer/codeand ...

  4. python怎么画参数函数图像_详解pandas.DataFrame.plot() 画图函数

    首先看官网的DataFrame.plot( )函数 DataFrame.plot(x=None, y=None, kind='line', ax=None, subplots=False, share ...

  5. python dataframe索引转成列_如何将 Pandas DataFrame 的索引转换为列

    我们将介绍将 Pandas DataFrame 的索引转换为列的各种方法,例如 df.index,带有 rename_axis 的 reset_index 来重命名索引,以及 set_index. 我 ...

  6. python0不能做除数、怎么解决_浅谈pandas dataframe对除数是零的处理

    如下例 data2['营业成本率'] = data2['营业成本本年累计']/data2['营业收入本年累计']*100 但有营业收入本年累计为0的情况, 则营业成本率为inf,即无穷大,而需要在表中 ...

  7. python dataframe 查看为空值_Python pandas.DataFrame 找出有空值的行

    0.摘要 pandas中DataFrame类型中,找出所有有空值的行,可以使用.isnull()方法和.any()方法. 1.找出含有空值的行 方法:DataFrame[DataFrame.isnul ...

  8. python dataframe遍历_对Python中DataFrame按照行遍历的方法

    对Python中DataFrame按照行遍历的方法 在做分类模型时候,需要在DataFrame中按照行获取数据以便于进行训练和测试. import pandas as pd dict=[[1,2,3, ...

  9. pandas DataFrame 直接生成plot图片 pandas.DataFrame.plot()

    官方: Dataframe.plot(x=None, y=None, kind='line', ax=None, subplots=False,sharex=None, sharey=False, l ...

最新文章

  1. shiro 解决 跨域(仅端口不同) 登陆 问题
  2. esp8266 wifi模组入网案例
  3. 开启mapper接口扫描,添加分页插件
  4. 200806C阶段一结构体
  5. Oracle从软件安装到运行的全流程
  6. android NullPointerException (转)
  7. 阿里研究院入选中国企业智库系统影响力榜 1
  8. (C语言)验证哥德巴赫猜想,输入一个大于6的偶数,输出这个数能被分解为哪两个质数的和
  9. 使用Ecliplse时,对导入package的顺序进行设定
  10. 【Udacity笔记】What is Machine Learning?
  11. 计算机在数据处理方面的论文,数据挖掘论文3000字范文参考(2)
  12. Rwordseg包如何加载本地词典
  13. python多元假设检验_Python中假设检验的实现,python
  14. 比尔盖茨的十条“金玉良言”
  15. Fresco使用详情
  16. android 实现返回键执行home键方法
  17. 安卓手机手电筒不见了?
  18. 软件project师周兆熊给IT学子的倾情奉献
  19. 盛世昊通上市美国纳斯达克,汽车后市场再变亿万级存量市场
  20. VPD(Virtual Private Database)

热门文章

  1. 大数据可视化搭建存在哪些难题
  2. 服务器主动发送fin信号,tcp 服务器向客户端发送FIN
  3. php连接mysql数据没反应_php无法连接mysql数据库的正确解决方法
  4. python获取代码当前行数_Python实验室一段日志代码,获取当前调用的函数名和行号...
  5. oracle设置默认值为当前时间_把锁屏密码设置成当前时间,随时间永远变动!
  6. SWPU第二届天梯选拔赛暨蓝桥杯训练赛题解
  7. 计算机二级office试题27答案,2017年12月计算机二级MS Office习题答案(一)
  8. python import自定义模块方法
  9. 安装windowx64-mysql
  10. 20165334 《java程序设计》第5周学习总结