在给定外部订单

时间:2018-04-06 15:00:49

标签: python pandas datetime

所以我在订购我的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)

但是不保持日期和小时的顺序。

3 个答案:

答案 0 :(得分:3)

您可以使用单独的enter image description hereargsortiloc
另外,请注意我使用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