Pandas DataFrame 按分类列排序,但按特定类排序

Posted

技术标签:

【中文标题】Pandas DataFrame 按分类列排序,但按特定类排序【英文标题】:Pandas DataFrame sort by categorical column but by specific class ordering 【发布时间】:2017-01-06 11:43:33 【问题描述】:

我想使用 df_selected = df_targets.head(N) 根据特定列的条目选择 Pandas 数据框中的顶部条目。

每个条目都有一个target 值(按重要性顺序):

Likely Supporter, GOTV, Persuasion, Persuasion+GOTV  

不幸的是,如果我这样做了

df_targets = df_targets.sort("target")

按字母顺序排列(GOTV,Likely Supporter, ...)。

我希望有一个像 list_ordering 这样的关键字:

my_list = ["Likely Supporter", "GOTV", "Persuasion", "Persuasion+GOTV"] 
df_targets = df_targets.sort("target", list_ordering=my_list)

为了解决这个问题,我创建了一个字典:

dict_targets = OrderedDict()
dict_targets["Likely Supporter"] = "0 Likely Supporter"
dict_targets["GOTV"] = "1 GOTV"
dict_targets["Persuasion"] = "2 Persuasion"
dict_targets["Persuasion+GOTV"] = "3 Persuasion+GOTV"

,但这似乎是一种非 Python 的方法。

建议将不胜感激!

【问题讨论】:

你的意思是OrderedDict对吗? 阅读this part 的文档。 是的,OrderedDict 【参考方案1】:

我认为你需要 Categorical 和参数 ordered=True 然后按 sort_values 排序非常好:

检查Categorical的文档:

Ordered Categoricals可以根据类别的自定义顺序进行排序,可以有最小值和最大值。

import pandas as pd

df = pd.DataFrame('a': ['GOTV', 'Persuasion', 'Likely Supporter', 
                         'GOTV', 'Persuasion', 'Persuasion+GOTV'])

df.a = pd.Categorical(df.a, 
                      categories=["Likely Supporter","GOTV","Persuasion","Persuasion+GOTV"],
                      ordered=True)

print (df)
                  a
0              GOTV
1        Persuasion
2  Likely Supporter
3              GOTV
4        Persuasion
5   Persuasion+GOTV

print (df.a)
0                GOTV
1          Persuasion
2    Likely Supporter
3                GOTV
4          Persuasion
5     Persuasion+GOTV
Name: a, dtype: category
Categories (4, object): [Likely Supporter < GOTV < Persuasion < Persuasion+GOTV]
df.sort_values('a', inplace=True)
print (df)
                  a
2  Likely Supporter
0              GOTV
3              GOTV
1        Persuasion
4        Persuasion
5   Persuasion+GOTV

【讨论】:

谢谢! (我给了+1,但我是新手,所以可能暂时看不到它......)关于pd.Categorical 的一个问题。这应该是更大的 DataFrame 中的一列,但pd.Categorical 不是一个系列(它不会使用索引)我唯一的选择是用pd.Series 包装它并在那里应用索引吗? 如果我的回答有帮助,别忘了accept。谢谢。 我认为你需要Series,如果需要索引。More info about Categorical。 我有! (我上面提到我是新手;也就是说,在我得到 15 分之前你不会看到它……) 感谢您的参考。我认为对我的问题最pythonic的答案是:df["target"] = df["target"].astype("category", categories=["Likely Supporter","GOTV","Persuasion","Persuasion+GOTV"], ordered=True)。非常感谢!【参考方案2】:

我想这是最充分的一个,以防你面临某些情况: 这是您的首选订单...

my_order = ["Likely Supporter", "GOTV", "Persuasion", "Persuasion+GOTV"]

那么,就这样吧……

df['Column_to_update'].cat.reorder_categories(my_order, inplace= True)

它很灵活,不需要分配新的类别。但是... 您的专栏必须是 dtype = 'category' 否则将无法正常工作。

Read more here (Pandas documentation)

【讨论】:

【参考方案3】:

我之前的回答中显示的方法现在已弃用。

最好使用pandas.Categorical,如here所示。

所以:

list_ordering = ["Likely Supporter","GOTV","Persuasion","Persuasion+GOTV"]  
df["target"] = pd.Categorical(df["target"], categories=list_ordering) 

【讨论】:

【参考方案4】:

感谢 jerzrael 的输入和参考,

我喜欢这种切片解决方案:

list_ordering = ["Likely Supporter","GOTV","Persuasion","Persuasion+GOTV"]  

df["target"] = df["target"].astype("category", categories=list_ordering, ordered=True)

【讨论】:

您可以编辑您的答案而不是发布另一个答案

以上是关于Pandas DataFrame 按分类列排序,但按特定类排序的主要内容,如果未能解决你的问题,请参考以下文章

如何将列名排序到 Pandas Dataframe(分类数据)中的 bin 中

Pandas:将系列添加到按列排序的 DataFrame

如何在 Python 中按多列对 Pandas DataFrame 进行排序

Pandas 按值 1 对列进行分组并按频率排序

DataFrame的排序

pandas对dataframe进行排序:单数据列排序多数据列排序NA值排序位置排序算法