30 天滚动窗口中的行数

Posted

技术标签:

【中文标题】30 天滚动窗口中的行数【英文标题】:Number of rows in a rolling window of 30 days 【发布时间】:2021-07-08 00:28:18 【问题描述】:

我有一个示例数据框

Account     Date         Amount 
10          2020-06-01   100
10          2020-06-11   500
10          2020-06-21   600
10          2020-06-25   900
10          2020-07-11   1000
10          2020-07-15   600
11          2020-06-01   100
11          2020-06-11   200
11          2020-06-21   500
11          2020-06-25   1500
11          2020-07-11   2500
11          2020-07-15   6700

我想获取每个帐户每隔 30 天的行数,即

Account     Date         Amount 
10          2020-06-01   1
10          2020-06-11   2
10          2020-06-21   3
10          2020-06-25   4
10          2020-07-11   4
10          2020-07-15   4
11          2020-06-01   1
11          2020-06-11   2
11          2020-06-21   3
11          2020-06-25   4
11          2020-07-11   4
11          2020-07-15   4

我已经尝试过 Grouper 和重新采样,但这些给了我每 30 天的计数,而不是滚动计数。 提前致谢!

【问题讨论】:

【参考方案1】:
def get_rolling_amount(grp, freq):
    return grp.rolling(freq, on="Date", closed="both").count()


df["Date"] = pd.to_datetime(df["Date"])
df["Amount"] = df.groupby("Account").apply(get_rolling_amount, "30D").values
print(df)

打印:

    Account       Date Amount
0        10 2020-06-01      1
1        10 2020-06-11      2
2        10 2020-06-21      3
3        10 2020-06-25      4
4        10 2020-07-11      4
5        10 2020-07-15      4
6        11 2020-06-01      1
7        11 2020-06-11      2
8        11 2020-06-21      3
9        11 2020-06-25      4
10       11 2020-07-11      4
11       11 2020-07-15      4

【讨论】:

为什么 rolling("30D") 有效?更具体地说,为什么你可以传递一个字符串? @jch Pandas 支持“时间字符串”,因此“30D”表示 30 天。来源:github.com/pandas-dev/pandas/blob/v1.2.4/pandas/core/…【参考方案2】:

您可以使用组内广播来检查 X 天内有多少行。

import pandas as pd

def within_days(s, days):
    arr = ((s.to_numpy() >= s.to_numpy()[:, None]) 
           & (s.to_numpy() <= (s + pd.offsets.DateOffset(days=days)).to_numpy()[:, None])).sum(axis=0)
    return pd.Series(arr, index=s.index)

df['Amount'] = df.groupby('Account')['Date'].apply(within_days, days=30)

    Account       Date  Amount
0        10 2020-06-01       1
1        10 2020-06-11       2
2        10 2020-06-21       3
3        10 2020-06-25       4
4        10 2020-07-11       4
5        10 2020-07-15       4
6        11 2020-06-01       1
7        11 2020-06-11       2
8        11 2020-06-21       3
9        11 2020-06-25       4
10       11 2020-07-11       4
11       11 2020-07-15       4

【讨论】:

【参考方案3】:
df = df.resample('30D').agg('date':'count','Amount':'sum')

这将按计数聚合“日期”列,获取您想要的数据。

但是,由于您需要先将日期设置为重新采样的索引,因此您可以创建一个包含零的“虚拟”列:

df['dummy'] = pd.Series(np.zeros(len(df))

【讨论】:

以上是关于30 天滚动窗口中的行数的主要内容,如果未能解决你的问题,请参考以下文章

Node.js:计算文件中的行数

作业-- 统计文本文件中的字符数单词数行数

为不同时间段的每个相关记录计算 db 中的行数

以有限的行数滚动 UITextView 中的内容

在 Pyspark 中查找给定时间窗口中的行数

SQL 窗口函数 - 自上次 Max 以来的行数