gpt4 book ai didi

python - 在 Pandas 中有效地聚合重新采样的日期时间集合

转载 作者:太空狗 更新时间:2023-10-29 21:48:10 24 4
gpt4 key购买 nike

给定以下数据集作为 pandas 数据框 df:

index(as DateTime object) |  Name        |  Amount    |  IncomeOutcome
---------------------------------------------------------------
2019-01-28 | Customer1 | 200.0 | Income
2019-01-31 | Customer1 | 200.0 | Income
2019-01-31 | Customer2 | 100.0 | Income
2019-01-28 | Customer2 | -100.0 | Outcome
2019-01-31 | Customer2 | -100.0 | Outcome

我们执行以下步骤:

grouped = df.groupby("Name", "IncomeOutcome")
sampled_by_month = grouped.resample("M")
aggregated = sampled_by_month.agg({"MonthlyCount": "size", "Amount": "sum"})

所需的输出应如下所示:

Name       |  IncomeOutcome   |  Amount    |  MonthlyCount
------------------------------------------------------------
Customer1 | Income | 400.0 | 2
Customer2 | Income | 100.0 | 1
Customer2 | Outcome | -200.0 | 2

最后一步表现很差,可能与Pandas Issue #20660有关我的第一个意图是将所有 datetime 对象转换为 int64,这给我留下了一个问题,即如何按月对转换后的数据进行重新采样。

关于这个问题有什么建议吗?

提前致谢

最佳答案

也许我们可以通过仅在单个列(“金额”,感兴趣的列)上进行重采样来优化您的解决方案。

(df.groupby(["Name", "IncomeOutcome"])['Amount']
.resample("M")
.agg(['sum','size'])
.rename({'sum':'Amount', 'size': 'MonthlyCount'}, axis=1)
.reset_index(level=-1, drop=True)
.reset_index())

Name IncomeOutcome Amount MonthlyCount
0 Customer1 Income 400.0 2
1 Customer2 Income 100.0 1
2 Customer2 Outcome -200.0 2

如果这仍然太慢,那么我认为问题可能是 resample within groupby 减慢了速度。也许您可以尝试通过单个 groupby 调用按所有 3 个谓词进行分组。对于日期重采样,请尝试 pd.Grouper

(df.groupby(['Name', 'IncomeOutcome', pd.Grouper(freq='M')])['Amount']
.agg([ ('Amount', 'sum'), ('MonthlyCount', 'size')])
.reset_index(level=-1, drop=True)
.reset_index())

Name IncomeOutcome Amount MonthlyCount
0 Customer1 Income 400.0 2
1 Customer2 Income 100.0 1
2 Customer2 Outcome -200.0 2

性能方面,这应该会更快。


性能

让我们尝试设置一个更通用的 DataFrame 以进行测试。

# Setup
df_ = df.copy()
df1 = pd.concat([df_.reset_index()] * 100, ignore_index=True)
df = pd.concat([
df1.replace({'Customer1': f'Customer{i}', 'Customer2': f'Customer{i+1}'})
for i in range(1, 98, 2)], ignore_index=True)
df = df.set_index('index')

df.shape
# (24500, 3)

%%timeit 
(df.groupby(["Name", "IncomeOutcome"])['Amount']
.resample("M")
.agg(['sum','size'])
.rename({'sum':'Amount', 'size': 'MonthlyCount'}, axis=1)
.reset_index(level=-1, drop=True)
.reset_index())

%%timeit
(df.groupby(['Name', 'IncomeOutcome', pd.Grouper(freq='M')])['Amount']
.agg([ ('Amount', 'sum'), ('MonthlyCount', 'size')])
.reset_index(level=-1, drop=True)
.reset_index())

1.71 s ± 85.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
24.2 ms ± 1.82 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

关于python - 在 Pandas 中有效地聚合重新采样的日期时间集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54477866/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com