所以我在订购我的Dataframe时遇到了一些麻烦,我尝试过使用this问题,但还没有设法让它工作。我所拥有的是Dataframe nudf
,如此:
date level_1 0
0 2016-10-01 00:00:00 0.0 74.00
1 2016-10-01 00:30:00 0.5 72
2 2016-10-01 01:00:00 1.0 70
3 2016-10-01 01:30:00 1.5 64
4 2016-10-01 02:00:00 2.0 63
5 2016-10-01 02:30:00 2.5 60
... ... ... ...
19003 2017-09-31 21:30:00 21.5 129
19004 2017-09-31 22:00:00 22.0 118
19005 2017-09-31 22:30:00 22.5 106
19006 2017-09-31 23:00:00 23.0 84
19007 2017-09-31 23:30:00 23.5 76
我想要做的是按外部月订单排序:
[4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3]
这是过去12个月,也就是上个月。我想忽略年份,并按照上面的顺序订购每个月的行块。
例如,给定以下行:
0 2016-02-01 00:00:00 0.0 74.00
1 2016-02-01 00:30:00 0.5 72
2 2016-03-01 01:00:00 1.0 70
3 2016-03-01 01:30:00 1.5 64
4 2017-04-01 02:00:00 2.0 63
5 2017-04-01 02:30:00 2.5 60
结果应为:
4 2017-04-01 02:00:00 2.0 63
5 2017-04-01 02:30:00 2.5 60
0 2016-02-01 00:00:00 0.0 74.00
1 2016-02-01 00:30:00 0.5 72
2 2016-03-01 01:00:00 1.0 70
3 2016-03-01 01:30:00 1.5 64
我试过了:
nudf['month'] = nudf.apply(lambda row: row.date.month, axis=1)
nudf.month = nudf.month.astype("category")
nudf.month.cat.set_categories([x.month for x in reversed(_get_last_x_months(12))], inplace=True)
nudf.sort_values(["month"], inplace=True)
但是不保持日期和小时的顺序。
答案 0 :(得分:3)
您可以使用单独的,argsort
和iloc
另外,请注意我使用kind='mergesort'
因为mergesort
是一个“稳定”的排序算法,并且会保持等价行的相对顺序。
mcats = [4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3]
nudf.iloc[pd.Categorical(nudf.date.dt.month, mcats, True).argsort(kind='mergesort')]
date level_1 0
4 2017-04-01 02:00:00 2.0 63.0
5 2017-04-01 02:30:00 2.5 60.0
0 2016-02-01 00:00:00 0.0 74.0
1 2016-02-01 00:30:00 0.5 72.0
2 2016-03-01 01:00:00 1.0 70.0
3 2016-03-01 01:30:00 1.5 64.0
您也可以添加列
mcats = [4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3]
nudf = nudf.assign(month=pd.Categorical(nudf.date.dt.month, mcats, True))
nudf.sort_values('month', kind='mergesort')
date level_1 0 month
4 2017-04-01 02:00:00 2.0 63.0 4
5 2017-04-01 02:30:00 2.5 60.0 4
0 2016-02-01 00:00:00 0.0 74.0 2
1 2016-02-01 00:30:00 0.5 72.0 2
2 2016-03-01 01:00:00 1.0 70.0 3
3 2016-03-01 01:30:00 1.5 64.0 3
如果我们尝试按月按日期排序,我们不需要指定稳定的排序,只需按两列排序
mcats = [4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3]
nudf = nudf.assign(month=pd.Categorical(nudf.date.dt.month, mcats, True))
nudf.sort_values(['month', 'date'])
或者代替argsort
答案,我们可以使用np.lexsort
返回基于多个数组的排序排列。
mcats = [4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3]
nudf.iloc[np.lexsort(
[nudf.date, pd.Categorical(nudf.date.dt.month, mcats, True)]
)]
答案 1 :(得分:1)
您可以使用%
完成排序。但要获得所需的输出,请先按日期时间排序。
nudf.sort_values(by='date', inplace=True)
mcats = [x.month for x in reversed(_get_last_x_months(12))]
#[4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3]
nudf['m_fake'] = (nudf.date.dt.month+(12-mcats[0]))%12
nudf.sort_values(by='m_fake')
# date val1 val2 m_fake
#4 2017-04-01 02:00:00 2.0 63 0
#5 2017-04-01 02:30:00 2.5 60 0
#0 2016-02-01 00:00:00 0.0 74 10
#1 2016-02-01 00:30:00 0.5 72 10
#2 2016-03-01 01:00:00 1.0 70 11
#3 2016-03-01 01:30:00 1.5 64 11
答案 2 :(得分:1)
您可以使用map
更改值并重新排序列
# creates an int value based on the date using .dt.month (must be a date type)
df['month_value'] = df['date'].dt.month
# creates a dictionary that will remap the values
new_order = {4:1, 5:2, 6:3, 7:4, 8:5, 9:6, 10:7, 11:8, 12:9, 1:10, 2:11, 3:12}
# creates a new column based on the mapping
df['new_value'] = df['month_value'].map(new_order)
# sorts the values based on the new column
df.sort_values(by='new_value')
date month_value new_value
4 2017-04-01 4 1
5 2017-04-01 4 1
0 2016-02-01 2 11
1 2016-02-01 2 11
2 2016-03-01 3 12
3 2016-03-01 3 12