Python 使用字典作为排序标准对数据帧进行排序

Python 使用字典作为排序标准对数据帧进行排序,python,pandas,sorting,dictionary,Python,Pandas,Sorting,Dictionary,有一个类似的问题,但不完全是我要找的 我想根据字典对数据帧进行排序,字典指定要排序的列以及每列的顺序 例如: df = +-------+-------+-----------+------+ | Index | Time | Month | Year | +-------+-------+-----------+------+ | 0 | 13:00 | January | 2018 | | 1 | 14:30 | March | 2015 | |

有一个类似的问题,但不完全是我要找的

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

例如:

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'}
编辑:(谢谢@Jon Clements)

在Python3.6中,声明
sort\u dict
的键顺序将与指定的相同,但是,在3.6之前,dict文本不一定保持顺序。例如,在3.5中,声明sort_dict的结果是
{'Month':'singressing','Time':'singressing','Year':'degressing'}
。。。这将是一个不同的迭代顺序-因此不同的排序结果

如果需要始终保持相同的顺序,则可以通过构造函数使用
orderedict
Series
——顺序不取决于python的版本

一种可能的解决方案是创建helper
系列
,然后将索引转换为列表,并同时传递参数
升序
填充布尔列表:

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
编辑:(谢谢@Jon Clements)

在Python3.6中,声明
sort\u dict
的键顺序将与指定的相同,但是,在3.6之前,dict文本不一定保持顺序。例如,在3.5中,声明sort_dict的结果是
{'Month':'singressing','Time':'singressing','Year':'degressing'}
。。。这将是一个不同的迭代顺序-因此不同的排序结果

如果需要始终保持相同的顺序,则可以通过构造函数使用
orderedict
Series
——顺序不取决于python的版本

一种可能的解决方案是创建helper
系列
,然后将索引转换为列表,并同时传递参数
升序
填充布尔列表:

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\u dict
键顺序将按照指定的顺序,但是,在3.6之前,dict文本不一定保持顺序。。。如。。。在3.5中,声明
sort_dict
的结果是
{'Month':升序','Time':升序','Year':降序'}
。。。这将是一个不同的迭代顺序-因此不同的排序结果。你也不需要做那个序列。。。假设命令的顺序是正确的<代码>df.sort_值(列表(sort_dict),升序=[s=='s'升序's in sort_dict.values()])很好谢谢@JonClements的警告。您如何允许用户指定顺序而不必在
.sort\u values
调用中指定?@Zack您可以使用
orderedict
,这样在它上面进行迭代就可以保留插入顺序,但用户可能无论如何都必须使用2元组。。。所以我不太确定你的一般方法有什么优势。没有办法将字典锁定在当前的顺序吗?应该在这里警告OP,以
dict开始可能会导致问题。。。在3.6。。。声明
sort\u dict
键顺序将按照指定的顺序,但是,在3.6之前,dict文本不一定保持顺序。。。如。。。在3.5中,声明
sort_dict
的结果是
{'Month':升序','Time':升序','Year':降序'}
。。。这将是一个不同的迭代顺序-因此不同的排序结果。你也不需要做那个序列。。。假设命令的顺序是正确的<代码>df.sort_值(列表(sort_dict),升序=[s=='s'升序's in sort_dict.values()])
很好谢谢@JonClements的警告。您如何允许用户指定顺序而不必在
.sort\u values
调用中指定?@Zack您可以使用
orderedict
,这样在它上面进行迭代就可以保留插入顺序,但用户可能无论如何都必须使用2元组。。。所以我不太确定你的一般方法有什么优势。没有办法把字典锁定在当前的顺序吗?