【问题标题】:Sort dataframe using dictionary as sort criteria使用字典作为排序标准对数据框进行排序
【发布时间】:2019-09-24 02:05:54
【问题描述】:

有一个类似的问题here,但不是我要找的。​​p>

我想根据指定要排序的列以及每列的顺序的字典对数据框进行排序。

例子:

df =
+-------+-------+-----------+------+
| Index | Time  |   Month   | Year |
+-------+-------+-----------+------+
|     0 | 13:00 | January   | 2018 |
|     1 | 14:30 | March     | 2015 |
|     2 | 12:00 | November  | 2003 |
|     3 | 10:15 | September | 2012 |
|     4 | 13:30 | October   | 2012 |
|     5 | 06:25 | June      | 2012 |
|     6 | 07:50 | August    | 2019 |
|     7 | 09:20 | May       | 2015 |
|     8 | 22:30 | July      | 2016 |
|     9 | 23:05 | April     | 2013 |
|    10 | 21:10 | April     | 2008 |
+-------+-------+-----------+------+

sort_dict = {'Month': 'Ascending', 'Year': 'Descending', 'Time': 'Ascending'}

df.sort_values(by=sort_dict)

df = 
+-------+-------+-----------+------+
| Index | Time  |   Month   | Year |
+-------+-------+-----------+------+
|     0 | 13:00 | January   | 2018 |
|     1 | 14:30 | March     | 2015 |
|     9 | 23:05 | April     | 2013 |
|    10 | 21:10 | April     | 2008 |
|     7 | 09:20 | May       | 2015 |
|     5 | 06:25 | June      | 2012 |
|     8 | 22:30 | July      | 2016 |
|     6 | 07:50 | August    | 2019 |
|     3 | 10:15 | September | 2012 |
|     4 | 13:30 | October   | 2012 |
|     2 | 12:00 | November  | 2003 |
+-------+-------+-----------+------+

感谢任何帮助!

列索引也可以:

sort_dict = {2: 'Ascending', 3: 'Descending', 1: 'Ascending'}

【问题讨论】:

    标签: python pandas sorting dictionary


    【解决方案1】:

    编辑:(感谢@Jon Clements)

    在 python 3.6 中声明 sort_dict 键顺序将按照指定的顺序,但是,在 3.6 之前,dict 文字不一定会保留顺序。例如。在 3.5 中,声明 sort_dict 最终是 {'Month': 'Ascending', 'Time': 'Ascending', 'Year': 'Descending'}... 这将是一个不同的迭代顺序 - 因此不同的排序结果。

    如果需要总是相同的顺序,可以通过构造函数使用 OrderedDictSeries - 顺序不取决于 python 的版本。

    一种可能的解决方案是创建助手Series,然后将索引转换为列表并传递参数ascending 填充布尔列表:

    s = pd.Series(sort_dict)
    print (s)
    Month     Ascending
    Year     Descending
    Time      Ascending
    dtype: object
    
    df = df.sort_values(by=s.index.tolist(), ascending = (s == 'Ascending'))
    print (df)
            Time      Month  Year
    Index                        
    9      23:05      April  2013
    10     21:10      April  2008
    6      07:50     August  2019
    0      13:00    January  2018
    8      22:30       July  2016
    5      06:25       June  2012
    1      14:30      March  2015
    7      09:20        May  2015
    2      12:00   November  2003
    4      13:30    October  2012
    3      10:15  September  2012
    

    【讨论】:

    • 应该在这里警告 OP 以 dict 开头可能会导致问题...在 3.6... 声明 sort_dict 密钥顺序将按照指定的顺序,但是,之前到 3.6,dict 文字不一定会保留顺序...例如...在 3.5 中,声明 sort_dict 最终是 {'Month': 'Ascending', 'Time': 'Ascending', 'Year': 'Descending'}... 这将是一个不同的迭代顺序 - 因此不同的排序结果。
    • 你也不需要制作那个系列......假设字典的顺序是正确的......df.sort_values(list(sort_dict), ascending=[s == 'Ascending' for s in sort_dict.values()])很好
    • 感谢@JonClements 的警告。您如何允许用户指定订单而不必在.sort_values 调用中指定?
    • @Zack 您可以使用OrderedDict 以便对其进行迭代以保留插入顺序,但是构建用户可能无论如何都必须使用2元组......所以我不太确定你的一般方法有什么优势。
    • 有没有办法按当前顺序锁定字典?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-05
    • 2014-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多