python - 提高应用方法的性能
问题描述
我想按我的df“cod_id”的变量分组,然后应用这个函数:
[df.loc[df['dt_op'].between(d, d + pd.Timedelta(days = 7)), 'quantity'].sum() \
for d in df['dt_op']]
从这个df移动:
print(df)
dt_op quantity cod_id
20/01/18 1 613
21/01/18 8 611
21/01/18 1 613
...
对此:
print(final_df)
n = 7
dt_op quantity product_code Final_Quantity
20/01/18 1 613 2
21/01/18 8 611 8
25/01/18 1 613 1
...
我试过:
def lookforward(x):
L = [x.loc[x['dt_op'].between(row.dt_op, row.dt_op + pd.Timedelta(days=7)), \
'quantity'].sum() for row in x.itertuples(index=False)]
return pd.Series(L, index=x.index)
s = df.groupby('cod_id').apply(lookforward)
s.index = s.index.droplevel(0)
df['Final_Quantity'] = s
print(df)
dt_op quantity cod_id Final_Quantity
0 2018-01-20 1 613 2
1 2018-01-21 8 611 8
2 2018-01-21 1 613 1
但这不是一个有效的解决方案,因为它的计算速度很慢;
我怎样才能提高 它的性能?即使使用导致相同结果的新代码/新功能,我也会实现它。
编辑:
原始数据集的子集,只有一个产品(cod_id == 2),我尝试在“wm”提供的代码上运行:
print(df)
cod_id dt_op quantita final_sum
0 2 2017-01-03 1 54.0
1 2 2017-01-04 1 53.0
2 2 2017-01-13 1 52.0
3 2 2017-01-23 2 51.0
4 2 2017-01-26 1 49.0
5 2 2017-02-03 1 48.0
6 2 2017-02-27 1 47.0
7 2 2017-03-05 1 46.0
8 2 2017-03-15 1 45.0
9 2 2017-03-23 1 44.0
10 2 2017-03-27 2 43.0
11 2 2017-03-31 3 41.0
12 2 2017-04-04 1 38.0
13 2 2017-04-05 1 37.0
14 2 2017-04-15 2 36.0
15 2 2017-04-27 2 34.0
16 2 2017-04-30 1 32.0
17 2 2017-05-16 1 31.0
18 2 2017-05-18 1 30.0
19 2 2017-05-19 1 29.0
20 2 2017-06-03 1 28.0
21 2 2017-06-04 1 27.0
22 2 2017-06-07 1 26.0
23 2 2017-06-13 2 25.0
24 2 2017-06-14 1 23.0
25 2 2017-06-20 1 22.0
26 2 2017-06-22 2 21.0
27 2 2017-06-28 1 19.0
28 2 2017-06-30 1 18.0
29 2 2017-07-03 1 17.0
30 2 2017-07-06 2 16.0
31 2 2017-07-07 1 14.0
32 2 2017-07-13 1 13.0
33 2 2017-07-20 1 12.0
34 2 2017-07-28 1 11.0
35 2 2017-08-06 1 10.0
36 2 2017-08-07 1 9.0
37 2 2017-08-24 1 8.0
38 2 2017-09-06 1 7.0
39 2 2017-09-16 2 6.0
40 2 2017-09-20 1 4.0
41 2 2017-10-07 1 3.0
42 2 2017-11-04 1 2.0
43 2 2017-12-07 1 1.0
解决方案
编辑 181017:由于 pandas目前不支持稀疏时间序列上的前向滚动功能,此方法不起作用,请参阅评论。
在执行 pandas 操作时,使用 for 循环可能会成为性能杀手。
围绕行的 for 循环加上 7 天的 timedelta 可以替换为.rolling("7D")
. 为了获得前滚时间增量(当前日期 + 7 天),我们反转df
按日期,如下所示。
然后不再需要自定义函数,您可以.quantity.sum()
从 groupby 中获取。
quant_sum = df.sort_values("dt_op", ascending=False).groupby("cod_id") \
.rolling("7D", on="dt_op").quantity.sum()
cod_id dt_op
611 2018-01-21 8.0
613 2018-01-21 1.0
2018-01-20 2.0
Name: quantity, dtype: float64
result = df.set_index(["cod_id", "dt_op"])
result["final_sum"] = quant_sum
result.reset_index()
cod_id dt_op quantity final_sum
0 613 2018-01-20 1 2.0
1 611 2018-01-21 8 8.0
2 613 2018-01-21 1 1.0
推荐阅读
- android - Android - Tab and mobile compatible codes (supported screens
- ios - Xcode PDFKit form automatic calculation
- dns - 代客:找不到 DNS 地址
- arangodb - Push/Pull Value(s) to Array in ArangoJS
- typescript - Simplify async-await with array iteration in Typescript
- python-3.x - parse xml with lxml
- c - Crashing issue, might be due to a for loop
- android - 侦听器中的 PrintWriter 崩溃应用程序
- amazon-web-services - How do I write unit test aws-sdk-go-v2 dynamodb implementation
- wpf - 如何将 XAML 主窗口中的网格用于 WPF 中的另一个类?