0

只是一个例子......我有一个 5M 行的数据框,里面装满了跑步者,并记录了他们在任何一天跑了多少英里。如果某位跑者一天不跑,则没有 0 条目。

赛跑者 英里
一个 1 3
一个 3 4
一个 8 4
一个 9 2

我正在尝试获取他们在过去 7 个日历日(不包括当前行)以及接下来的 7 个日历日(包括当前行)中运行了多少的字段。

赛跑者 英里 最后 7 个 下一个 7
一个 1 3 无效的 7
一个 3 4 3 10
一个 8 4 7 6
一个 9 2 10 2

我认为可以得到单行的答案。

例如,第 1 行的下一个 7...

df.loc[(df['Runner'] == 'A') & (df['day'] >= 1) & (df['day'] < 1+7)]['Miles'].sum ()

我只是不确定如何以有效的方式将这种类型的东西应用于每一行。到目前为止我看到的方法只使用同一行的数据。有什么帮助吗?

4

1 回答 1

0

您可以使用滚动总和。

假设最大天数是 20

max_day = 20

这些是所有跑步者和所有日子的名单

import numpy as np
runners = df['Runner'].unique()
days = np.arange(1, max_day)

然后我们可以得到一个完整的runner和day组合列表

all_combos = [(r, d) for r in runners for d in days]

在以下 4 行代码的第一行中,我们将零填充回去,然后在第二行中,我们按 runner 对数据进行分组,在第三行中,我们将滚动求和应用于Miles要求至少只有 1 条记录来执行sum. 您可以调整此参数。最后一行负责格式。

rollingsum = df.set_index(['Runner', 'Day']).reindex(all_combos).fillna(0)\
    .groupby('Runner')\
    ['Miles'].rolling(7, min_periods=1).sum()\
    .droplevel(1).rename('rs').reset_index()

我们只需要对 7 天求和一次,并通过分配两个新的移位Day列来替换原始列来移动“last-7-day”和“next-7-day”的记录,然后合并结果。

df.merge(
    rollingsum.assign(Day = rollingsum['Day']+1).rename(columns={'rs': 'last_7_days'}),
    on = ['Runner', 'Day'],
    how = 'left'
).merge(
    rollingsum.assign(Day = rollingsum['Day']-6).rename(columns={'rs': 'next_7_days'}),
    on = ['Runner', 'Day'],
    how = 'left'
)

  Runner  Day  Miles  last_7_days  next_7_days
0      A    1      3          NaN          7.0
1      A    3      4          3.0         10.0
2      A    8      4          7.0          6.0
3      A    9      2          8.0          2.0
于 2022-02-26T12:33:24.753 回答