【问题标题】:Pandas DataFrame sort by categorical column but by specific class orderingPandas DataFrame 按分类列排序,但按特定类排序
【发布时间】: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

标签: python pandas dataframe sorting categorical-data


【解决方案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)
      

      【讨论】:

      • 您可以编辑您的答案而不是发布另一个答案
      猜你喜欢
      • 2018-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-29
      • 2017-01-09
      • 2020-12-14
      • 1970-01-01
      相关资源
      最近更新 更多