对多个列进行分组并根据日期列应用移动功能

时间:2019-02-28 10:46:24

标签: python pandas

假设我有这个数据集:

Store_id    Order_id    Date    Order_value
1   1   01/01/2018  1
1   4   02/01/2018  0
1   5   02/01/2018  2
1   6   02/01/2018  1
1   8   03/01/2018  2
1   9   03/01/2018  NA
2   2   01/01/2018  3
2   3   01/01/2018  2
2   7   02/01/2018  NA
2   10  03/01/2018  1
2   11  03/01/2018  2
2   12  03/01/2018  NA

我想应用移动函数(例如移动平均值)来检索每个商店和日期的汇总值。

例如,在移动平均值的情况下(窗口= 2且min_periods = 1,不包括NA),我希望获得以下信息:

Store_id    Date    Orders_value
1   01/01/2018  1
1   02/01/2018  1
1   03/01/2018  1.25
2   01/01/2018  2.5
2   02/01/2018  2.5
2   03/01/2018  1.5

为方便起见,它是通过以下方式计算的:

Store_id    Date    Orders_value
1   01/01/2018  (1)/1
1   02/01/2018  (1+2+0+1)/4
1   03/01/2018  (NA+2+1+2+0)/5
2   01/01/2018  (2+3)/2
2   02/01/2018  (NA+2+3)/3
2   03/01/2018  (NA+2+1+NA)/4

并且因为我不计算资产净值,所以就是这样:

Store_id    Date    Orders_value
1   01/01/2018  (1)/1
1   02/01/2018  (1+2+0+1)/4
1   03/01/2018  (2+1+2+0)/4
2   01/01/2018  (2+3)/2
2   02/01/2018  (2+3)/2
2   03/01/2018  (2+1)/2

给出您在上面看到的结果。

如何使用pandas来做到这一点?

举一个简短的例子,例如我想要在日期03/01/2018的商店1取该商店在02/01/2018和03/01/2018(对于2号窗口)。

因此,这就是我要在日期03/01/2018上对商店1进行的操作:

( Orders_value(Order_1_value + Order_2_value + ... + Order_n_value , 03/01/2018) + Orders_value(Order_1_value + Order_2_value + ... + Order_m_value , 02/01/2018) ) / (n + m) =

# n & m in Order_n_value & Order_m_value refers to the number of the order for this day at this store - not at the order id of the particular order

= ( Orders_value(Order_1_value, 03/01/2018) + Orders_value(Order_2_value, 03/01/2018) +  Orders_value(Order_1_value, 02/01/2018) + Orders_value(Order_2_value, 02/01/2018) + Orders_value(Order_3_value, 03/01/2018) ) / (2 + 3)

= ( NA + 2 + 1 + 2 + 0 ) / 5

= ( 2 + 1 + 2 + 0) / 4 # NAs not counted in

= 1.25

类似地,我想对每个商店的所有日期执行相同的操作。

正如我说过的,我想对自己的移动函数(超出pandas的移动平均)执行相同的操作,因此最好提供对任何自定义函数均有效的解决方案。

请记住,我最近问了一个非常类似的问题(GroupBy on multiple columns and apply moving function),因此如果您需要一些启发,可以看看一下。

2 个答案:

答案 0 :(得分:2)

知道了!您需要使用time-aware rolling

df.Date = pd.to_datetime(df.Date, dayfirst=True)
temp_df = df.set_index('Date').groupby('Store_id')['Order_value'].rolling(
        '2d', min_periods=1).mean().reset_index()
temp_df.groupby(['Store_id', 'Date']).last()


                Order_value
Store_id    
      Date  
1   2018-01-01          1.00
    2018-01-02          1.00
    2018-01-03          1.25
2   

    2018-01-01          2.50
    2018-01-02          2.50
    2018-01-03          1.50

您还可以将mean替换为apply并使用自定义功能。

答案 1 :(得分:-1)

我不太想从您的问题中找出您的需要,但是如果您正在寻找所有 是一种将自定义功能应用于熊猫滚动窗口的简单方法,请尝试以下操作:

import pandas as pd
df = pd.DataFrame(data=myData)
df['newColumnName'] = df['DataColumnName'].rolling(window=2).apply(lambda x: myFunction(x))