为了账号安全,请及时绑定邮箱和手机立即绑定

在pandas数据框中自定义排序

在pandas数据框中自定义排序

汪汪一只猫 2019-08-08 14:59:19
在pandas数据框中自定义排序我有python pandas数据帧,其中一列包含月份名称。如何使用字典进行自定义排序,例如:custom_dict = {'March':0, 'April':1, 'Dec':3}
查看完整描述

3 回答

?
慕标琳琳

TA贡献1830条经验 获得超9个赞

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})

稍有不同的是,如果字典外有一个值,它就不会上升(它只会保持不变)。


查看完整回答
反对 回复 2019-08-08
?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

游戏有点晚了,但是这里有一种方法可以创建一个使用任意函数对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上变慢。不确定性能与添加,排序,然后删除列的比较。有关加速代码的任何提示将不胜感激!


查看完整回答
反对 回复 2019-08-08
?
萧十郎

TA贡献1815条经验 获得超13个赞

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


查看完整回答
反对 回复 2019-08-08
  • 3 回答
  • 0 关注
  • 1481 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信