Ben*_*Ben 7 python performance numpy pandas
给出以下数据集作为pandas dataframe 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
Run Code Online (Sandbox Code Playgroud)
我们执行以下步骤:
grouped = df.groupby("Name", "IncomeOutcome")
sampled_by_month = grouped.resample("M")
aggregated = sampled_by_month.agg({"MonthlyCount": "size", "Amount": "sum"})
Run Code Online (Sandbox Code Playgroud)
所需的输出应如下所示:
Name | IncomeOutcome | Amount | MonthlyCount
------------------------------------------------------------
Customer1 | Income | 400.0 | 2
Customer2 | Income | 100.0 | 1
Customer2 | Outcome | -200.0 | 2
Run Code Online (Sandbox Code Playgroud)
最后一步执行得非常糟糕,可能与Pandas问题相关#20660 我的第一个目的是将所有日期时间对象转换为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
Run Code Online (Sandbox Code Playgroud)
如果这仍然太慢,那么我认为问题可能是resample存在于其中的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
Run Code Online (Sandbox Code Playgroud)
在性能方面,这应该更快。
性能
让我们尝试设置一个更通用的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)
Run Code Online (Sandbox Code Playgroud)
%%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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
240 次 |
| 最近记录: |