Pandas滚动window计算最近n天相同项目的总和

Pandas Rolling window to calculate sum of the same items of the last n days

跟进 ,现在我想在滚动 window.

上给定相同分组的情况下计算不同列的 sum/mean

这是要设置的代码片段。我想计算每个人过去 30 天每行的收入sum/mean。另外,由于我的数据很大(实际数据有 170 万行),我认为任何使用 apply 的方法都行不通。

伪:

d = {'Name': ['Jack', 'Jim', 'Jack', 'Jim', 'Jack', 'Jack', 'Jim', 'Jack', 'Jane', 'Jane'],
     'Date': ['08/01/2021',
              '27/01/2021',
              '05/02/2021',
              '10/02/2021',
              '17/02/2021',
              '18/02/2021',
              '20/02/2021',
              '21/02/2021',
              '22/02/2021',
              '29/03/2021'],
     'Earning': [40, 10, 20, 20, 40, 50, 100, 70, 80, 90]}

df = pd.DataFrame(data=d)
df['Date'] = pd.to_datetime(df.Date, format='%d/%m/%Y')
df = df.sort_values('Date')

IIUC 使用

df = (df.join(df.set_index('Date')
                .groupby('Name')['Earning']
                .rolling('30d', closed='both')
                .sum()
                .rename('sum'), on=['Name', 'Date']))
print (df)
   Name       Date  Earning    sum
0  Jack 2021-01-08       40   40.0
1   Jim 2021-01-27       10   10.0
2  Jack 2021-02-05       20   60.0
3   Jim 2021-02-10       20   30.0
4  Jack 2021-02-17       40   60.0
5  Jack 2021-02-18       50  110.0
6   Jim 2021-02-20      100  130.0
7  Jack 2021-02-21       70  180.0
8  Jane 2021-02-22       80   80.0
9  Jane 2021-03-29       90   90.0

这个答案是基于@jezrael post 所以非常感谢你。不同的是这个解

  1. 使用左连接来确保我们不会改变原始数据的形状
  2. 过滤掉重复项,以防数据中存在相同的 ['Date'、'Name']。
def sum_of_last_n_days(df: pd.DataFrame, identifier: str, timestamp: str, sum_col: str, delta: int) -> pd.DataFrame:
   
    col_name = "sum_%s" % identifier
    temp_df = df.set_index(timestamp) \
        .groupby(identifier, sort=False)[sum_col] \
        .rolling('%sd' % delta, closed='both') \
        .sum() \
        .rename(col_name)
    temp_df = temp_df[~temp_df.index.duplicated(keep="first")]
    return df.merge(temp_df, how="left", left_on=[identifier, timestamp], right_index=True)

frequency_of_last_n_days(df, "Name", "Date", "Earning", 30)

结果

   Name       Date  Earning    sum
0  Jack 2021-01-08       40   40.0
1   Jim 2021-01-27       10   10.0
2  Jack 2021-02-05       20   60.0
3   Jim 2021-02-10       20   30.0
4  Jack 2021-02-17       40   60.0
5  Jack 2021-02-18       50  110.0
6   Jim 2021-02-20      100  130.0
7  Jack 2021-02-21       70  180.0
8  Jane 2021-02-22       80   80.0
9  Jane 2021-03-29       90   90.0