如何按字符串索引上的自定义顺序对熊猫数据框进行排序

Posted

技术标签:

【中文标题】如何按字符串索引上的自定义顺序对熊猫数据框进行排序【英文标题】:How to sort pandas dataframe by custom order on string index 【发布时间】:2018-10-05 08:31:25 【问题描述】:

我有以下数据框:

import pandas as pd

# Create DataFrame
df = pd.DataFrame(
'id':[2967, 5335, 13950, 6141, 6169],\
 'Player': ['Cedric Hunter', 'Maurice Baker' ,\
            'Ratko Varda' ,'Ryan Bowen' ,'Adrian Caldwell'],\
 'Year': [1991 ,2004 ,2001 ,2009 ,1997],\
 'Age': [27 ,25 ,22 ,34 ,31],\
 'Tm':['CHH' ,'VAN' ,'TOT' ,'OKC' ,'DAL'],\
 'G':[6 ,7 ,60 ,52 ,81])


df.set_index('Player', inplace=True)

它显示:

Out[128]:

                 Age   G   Tm  Year     id
Player
Cedric Hunter     27   6  CHH  1991   2967
Maurice Baker     25   7  VAN  2004   5335
Ratko Varda       22  60  TOT  2001  13950
Ryan Bowen        34  52  OKC  2009   6141
Adrian Caldwell   31  81  DAL  1997   6169

我要做的是根据此列表以任意顺序对“播放器”索引进行排序(注意:不是字母顺序):

reorderlist = [ 'Maurice Baker', 'Adrian Caldwell','Ratko Varda' ,'Ryan Bowen' ,'Cedric Hunter']

我该怎么做?

【问题讨论】:

所以您希望它按照列表中的顺序排列 reorderlist? pandas 实现这一点的“正确”方式是像 R 一样允许分类作为索引;目前 pandas 没有,它给出了错误。 【参考方案1】:

只要reindex

df.reindex(reorderlist)
Out[89]: 
                 Age   G   Tm  Year     id
Player                                    
Maurice Baker     25   7  VAN  2004   5335
Adrian Caldwell   31  81  DAL  1997   6169
Ratko Varda       22  60  TOT  2001  13950
Ryan Bowen        34  52  OKC  2009   6141
Cedric Hunter     27   6  CHH  1991   2967

更新你有多个同名玩家的信息

out = df.iloc[pd.Categorical(df.index,reorderlist).argsort()]

【讨论】:

你好,我已经尝试过这个播放器作为记录器列表,但所有其他值都是 ara NAN。我想要和上面一样的值 当有同名玩家时,这不起作用。 @DiegoFMedina 检查更新【参考方案2】:

从 Pandas 1.1 开始,DataFrame.sort_values 有一个 key 参数,它需要一个可调用来控制排序。因此,您可以使用如下方法:

def sorter(column):
    reorder = [
        "Maurice Baker",
        "Adrian Caldwell",
        "Ratko Varda",
        "Ryan Bowen",
        "Cedric Hunter",
    ]
    # This also works:
    # mapper = name: order for order, name in enumerate(reorder)
    # return column.map(mapper)
    cat = pd.Categorical(column, categories=reorder, ordered=True)
    return pd.Series(cat)

df_sorted = df.sort_values(by="Player", key=sorter)

使用 pd.Categorical 和我在 cmets 中使用的 column.map 替代方案之间可能存在一些实际差异。例如,请参阅这些caveats。为了完整性,我将两者都展示。我还没有测试过这与当前使用df.reindex 的解决方案在性能方面的比较。当您也有 MultiIndex 时,最好的方法可能会有所不同。

【讨论】:

不是所有的英雄都穿斗篷!显然,有些人戴着围巾!【参考方案3】:

要在您的字符串列表上获得自定义排序顺序,请将其声明为分类并在排序中手动指定该顺序:

player_order = pd.Categorical([ 'Maurice Baker', 'Adrian Caldwell','Ratko Varda' ,'Ryan Bowen' ,'Cedric Hunter'],
              ordered=True)

这是因为 pandas 还不允许分类作为索引:df.set_index(keys=player_order, inplace=True)TypeError: unhashable type: 'Categorical'

因此,您需要使用 df.sort_index(level=player_order) 进行手动自定义排序

【讨论】:

请给出解决方案,而不是'...'点 @jean-loup:我已经在这里给出了解决方案,但要 200% 清楚:df.sort_index(level=player_order)

以上是关于如何按字符串索引上的自定义顺序对熊猫数据框进行排序的主要内容,如果未能解决你的问题,请参考以下文章

根据字符串+数字的索引对熊猫数据框进行排序

对唯一顺序索引的多索引熊猫数据框进行切片和赋值

如何按定义的时间间隔对熊猫数据框进行分组?

如何按索引级别和值对分组的多索引熊猫系列进行排序?

首先按最大负值对熊猫数据框的列进行排序

按字符串长度对熊猫系列中的列表进行排序