Python Pandas - 通过保持特定顺序对值进行排序

时间:2018-02-15 11:14:40

标签: python pandas sorting

我试图通过将索引保持在特定的顺序来对值进行排序。

from random import randint
import pandas as pd
days = ["Tuesday", "Thursday", "Monday", "Wednesday"]
a = pd.DataFrame({"Value": [randint(0, 9) for i in range(len(days)*5)],
                  "Year": [y for i in range(len(days)) for y in range(2014,2019)]}, 
                  index=[day for day in days for i in range(5)])
myorder = ["Monday", "Tuesday", "Wednesday", "Thursday"]
a.index = pd.CategoricalIndex(a.index, categories=myorder, ordered=True)
a = a.sort_index()

通过应用a.sort_index(),我得到了我的具体订单。但是,Year的值是随机的。如果我们天真地a.sort_values(["Year"]),它会再次修改index顺序。如何通过保留我的初始Year订单来对index值进行排序?

2 个答案:

答案 0 :(得分:4)

您需要从索引创建列并一起排序:

a = a.reset_index().sort_values(['index','Year']).set_index('index').rename_axis(None)

或者从列创建MultiIndex并一起排序:

a = (a.set_index('Year', append=True)
      .sort_index()
      .reset_index(level=1)
      .reindex(columns=a.columns))

print (a)
           Value  Year
Monday         7  2014
Monday         3  2015
Monday         2  2016
Monday         5  2017
Monday         4  2018
Tuesday        6  2014
Tuesday        0  2015
Tuesday        0  2016
Tuesday        9  2017
Tuesday        2  2018
Wednesday      6  2014
Wednesday      7  2015
Wednesday      5  2016
Wednesday      5  2017
Wednesday      5  2018
Thursday       3  2014
Thursday       2  2015
Thursday       8  2016
Thursday       7  2017
Thursday       7  2018

答案 1 :(得分:4)

非分类方法,按自定义index订单排序&同时Year

orderdic = dict(zip(myorder, range(len(myorder))))

a = a.assign(order=a.index.to_series().map(orderdic))\
      .sort_values(['order', 'Year']).drop('order', 1)

#            Value  Year
# Monday         2  2014
# Monday         4  2015
# Monday         8  2016
# Monday         8  2017
# Monday         7  2018
# Tuesday        5  2014
# Tuesday        4  2015
# Tuesday        0  2016
# Tuesday        1  2017
# Tuesday        3  2018
# Wednesday      2  2014
# Wednesday      8  2015
# Wednesday      4  2016
# Wednesday      3  2017
# Wednesday      4  2018
# Thursday       7  2014
# Thursday       4  2015
# Thursday       7  2016
# Thursday       2  2017
# Thursday       1  2018