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 中