更新
使用selected answer!它比这篇文章更新,不仅是在 pandas 中维护有序数据的官方方法,而且在各个方面都更好,包括功能/性能等。不要使用我在下面描述的 hacky 方法。
我只是写这个更新,因为人们一直在支持我的答案,但它肯定比接受的更糟糕:)
原帖
游戏有点晚了,但这里有一种方法可以创建一个函数,使用任意函数对 pandas Series、DataFrame 和多索引 DataFrame 对象进行排序。
我使用df.iloc[index] 方法,它按位置引用Series/DataFrame 中的一行(与按值引用的df.loc 相比)。使用它,我们只需要一个返回一系列位置参数的函数:
def sort_pd(key=None,reverse=False,cmp=None):
def sorter(series):
series_list = list(series)
return [series_list.index(i)
for i in sorted(series_list,key=key,reverse=reverse,cmp=cmp)]
return sorter
您可以使用它来创建自定义排序功能。这适用于安迪·海登回答中使用的数据框:
df = pd.DataFrame([
[1, 2, 'March'],
[5, 6, 'Dec'],
[3, 4, 'April']],
columns=['a','b','m'])
custom_dict = {'March':0, 'April':1, 'Dec':3}
sort_by_custom_dict = sort_pd(key=custom_dict.get)
In [6]: df.iloc[sort_by_custom_dict(df['m'])]
Out[6]:
a b m
0 1 2 March
2 3 4 April
1 5 6 Dec
这也适用于多索引 DataFrames 和 Series 对象:
months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
df = pd.DataFrame([
['New York','Mar',12714],
['New York','Apr',89238],
['Atlanta','Jan',8161],
['Atlanta','Sep',5885],
],columns=['location','month','sales']).set_index(['location','month'])
sort_by_month = sort_pd(key=months.index)
In [10]: df.iloc[sort_by_month(df.index.get_level_values('month'))]
Out[10]:
sales
location month
Atlanta Jan 8161
New York Mar 12714
Apr 89238
Atlanta Sep 5885
sort_by_last_digit = sort_pd(key=lambda x: x%10)
In [12]: pd.Series(list(df['sales'])).iloc[sort_by_last_digit(df['sales'])]
Out[12]:
2 8161
0 12714
3 5885
1 89238
对我来说,这感觉很干净,但它大量使用了 python 操作,而不是依赖于优化的 pandas 操作。我没有进行任何压力测试,但我想这可能会在非常大的 DataFrame 上变慢。不确定性能与添加、排序和删除列相比如何。任何加快代码速度的提示都将不胜感激!