我有一个 Dataframe Pandas Dataframe 与下列:
df = pd.DataFrame([
['A2', 2],
['B1', 1],
['A1', 2],
['A2', 1],
['B1', 2],
['A1', 1]],
columns=['one','two'])
我希望首先按列'two'排序,然后按列'one'排序。对于第二次排序,我希望使用一个自定义排序规则,该规则将按字母字符[A-Z]
排序列'one',然后按尾随数字[0-100]
排序。因此,排序的结果将是:
one two
A1 1
B1 1
A2 1
A1 2
B1 2
A2 2
在使用如下排序规则之前,我已经对类似于列'one'的字符串列表进行了排序:
def custom_sort(value):
return (value[0], int(value[1:]))
my_list.sort(key=custom_sort)
如果我尝试通过Pandas排序来应用这个规则,我会遇到很多问题,包括:
- panda
DataFrame.sort_values()
函数接受一个键来排序,就像sort()函数一样,但是这个键函数应该是矢量化的(根据panda文档)。如果我尝试将排序键只应用到列“one”,我会得到错误**“TypeError:无法将序列转换为〈class 'int'〉"**
1.当使用pandasDataFrame.sort_values()
方法时,它会将排序键应用于传入的所有列。这将不起作用,因为我想首先使用本机数字排序按列“two”排序。
我应该如何按照上面提到的那样对DataFrame进行排序?
5条答案
按热度按时间oknwwptz1#
您可以将列
one
拆分为它的组成部分,将它们作为列添加到 Dataframe 中,然后使用列two
对它们进行排序。cpjpxq1n2#
使用
str.extract
创建一些临时列,这些列基于1)字母表(a-zA-Z]+)
和2)数字(\d+)
,然后删除它们:iaqfqrcu3#
解决方案之一是将两列都设为pd.categorical,并将期望的顺序作为参数“categories”传递。
但我有一些要求,我不能强制未知\意外的值,不幸的是,这是pd.Categorical正在做的。而且None不支持作为一个类别,并自动强制。
因此,我的解决方案是使用一个键按照自定义排序顺序对多个列进行排序:
输出:
请注意,此解决方案可能会很慢。
cotxawn74#
在panda〉= 1.1.0和natsort中,你也可以这样做:
rqmkfv5c5#
我已经创建了一个函数来解决多列使用key参数的问题,遵循@ Alexandria 的建议。它还处理了在创建时态列时不复制名称的问题。此外,它还可以对整个 Dataframe 进行排序,包括索引(使用index.names)。
它可以改进,但使用复制粘贴应该可以:
https://github.com/DavidDB33/pandas_helpers/blob/main/pandas_helpers/helpers.py