在pandas数据框中自定义排序

在pandas数据框中自定义排序

我有python pandas数据帧,其中一列包含月份名称。

如何使用字典进行自定义排序,例如:

custom_dict = {'March':0, 'April':1, 'Dec':3}



汪汪一只猫
浏览 1482回答 3
3回答

慕标琳琳

Pandas 0.15引入了分类系列,它允许更清晰的方式来执行此操作:首先使月份列成为分类,并指定要使用的顺序。In [21]: df['m'] = pd.Categorical(df['m'], ["March", "April", "Dec"])In [22]: df  # looks the same!Out[22]:    a  b      m0  1  2  March1  5  6    Dec2  3  4  April现在,当您对月份列进行排序时,它将根据该列表进行排序:In [23]: df.sort("m")Out[23]:    a  b      m0  1  2  March2  3  4  April1  5  6    Dec注意:如果列表中没有值,它将转换为NaN。那些感兴趣的人的答案较旧您可以创建一个中间系列,并set_index在其上:df = pd.DataFrame([[1, 2, 'March'],[5, 6, 'Dec'],[3, 4, 'April']], columns=['a','b','m'])s = df['m'].apply(lambda x: {'March':0, 'April':1, 'Dec':3}[x])s.sort()In [4]: df.set_index(s.index).sort()Out[4]:     a  b      m0  1  2  March1  3  4  April2  5  6    Dec正如评论的那样,在较新的大熊猫中,Series有一种replace更优雅的方法:s = df['m'].replace({'March':0, 'April':1, 'Dec':3})稍有不同的是,如果字典外有一个值,它就不会上升(它只会保持不变)。

海绵宝宝撒

游戏有点晚了,但是这里有一种方法可以创建一个使用任意函数对pandas Series,DataFrame和multiindex 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您可以使用它来创建自定义排序功能。这适用于Andy Hayden的答案中使用的数据框: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  m0  1  2  March2  3  4  April1  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    8161New York  Mar    12714           Apr    89238Atlanta   Sep    5885sort_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    81610   127143    58851   89238对我来说,这感觉很干净,但它大量使用python操作,而不是依赖于优化的pandas操作。我没有做任何压力测试,但我想这可能会在非常大的DataFrame上变慢。不确定性能与添加,排序,然后删除列的比较。有关加速代码的任何提示将不胜感激!

萧十郎

import pandas as pd custom_dict = {'March':0,'April':1,'Dec':3}df = pd.DataFrame(...) # with columns April, March, Dec (probably alphabetically)df = pd.DataFrame(df, columns=sorted(custom_dict, key=custom_dict.get))返回包含March,April,Dec列的DataFrame
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python