首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >提高应用方法性能

提高应用方法性能
EN

Stack Overflow用户
提问于 2018-10-16 16:44:44
回答 2查看 141关注 0票数 2

我想通过我的df "cod_id“的变量进行分组,然后应用这个函数:

代码语言:javascript
复制
[df.loc[df['dt_op'].between(d, d + pd.Timedelta(days = 7)), 'quantity'].sum() \
                        for d in df['dt_op']]

从这个df开始:

代码语言:javascript
复制
print(df)
dt_op      quantity      cod_id
20/01/18      1            613
21/01/18      8            611
21/01/18      1            613 
...

对于这一条:

代码语言:javascript
复制
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
...

我尝试过:

代码语言:javascript
复制
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

但这不是一个有效的解决方案,因为它在计算上是slow

How can I improve its performance?即使是使用新代码/新函数,我也能做到这一点,这会导致产生相同的结果。

编辑:

原始数据集的子集,仅使用one产品(cod_id == 2),我尝试在“w-m”提供的代码上运行:

代码语言:javascript
复制
   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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-18 06:36:38

实现问题中的确切行为是困难的,因为pandas中有两个缺点:既没有groupby/ rolling /transform,也没有实现前瞻性的滚动稀疏日期(有关更多详细信息,请参阅其他答案)。

这个答案试图通过重新采样数据,填写所有日期,然后将quant_sums与原始数据连接起来,来解决这两个问题。

代码语言:javascript
复制
# Create a temporary df with all in between days filled in with zeros
filled = df.set_index("dt_op").groupby("cod_id") \
           .resample("D").asfreq().fillna(0) \
           .quantity.to_frame()

# Reverse and sum
filled["quant_sum"] = filled.reset_index().set_index("dt_op") \
                            .iloc[::-1] \
                            .groupby("cod_id") \
                            .rolling(7, min_periods=1) \
                            .quantity.sum().astype(int)

# Join with original `df`, dropping the filled days
result = df.set_index(["cod_id", "dt_op"]).join(filled.quant_sum).reset_index()
票数 0
EN

Stack Overflow用户

发布于 2018-10-16 17:12:01

编辑181017:由于pandas在稀疏时间序列 上的前向滚动功能,此方法不起作用,请参阅评论。

在执行pandas操作时,使用for循环可能是性能杀手。

行周围的for循环加上它们7天的时间增量可以替换为.rolling("7D")。为了获得前滚时间增量(当前日期+7天),我们按日期反转df,如here所示。

这样就不再需要定制函数了,您只需从groupby中获取.quantity.sum()即可。

代码语言:javascript
复制
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
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52831398

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档