在其他列定义的窗口内累计应用[英] Cumulative apply within window defined by other columns

本文是小编为大家收集整理的关于在其他列定义的窗口内累计应用的处理方法,想解了在其他列定义的窗口内累计应用的问题怎么解决?在其他列定义的窗口内累计应用问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我正在尝试将函数累积应用于位于由"开始"和"完成"列定义的窗口内的值.所以,"开始"和"结束"定义了值是"活动"的时间间隔;对于每一行,我想获得当时所有"活动"值的总和.

这是一个"蛮力"示例,它可以满足我的需求 - 是否有更优雅、更快或更节省内存的方法?

df = pd.DataFrame(data=[[1,3,100], [2,4,200], [3,6,300], [4,6,400], [5,6,500]],
    columns=['start', 'finish', 'val'])
df['dummy'] = 1
df = df.merge(df, on=['dummy'], how='left')
df = df[(df['start_y'] <= df['start_x']) & (df['finish_y'] > df['start_x'])]
val = df.groupby('start_x')['val_y'].sum()

原来df是:

  start  finish  val
0   1      3     100
1   2      4     200
2   3      6     300
3   4      6     400
4   5      6     500

我追求的结果是:

1   100
2   300
3   500
4   700
5   1200

推荐答案

使用numpy boardcast,可惜还是O(n*m)解,但应该比groupby快.到目前为止,基于我的测试 Pir 的解决方案性能是最好的

s1=df['start'].values
s2=df['finish'].values
np.sum(((s1<=s1[:,None])&(s2>=s2[:,None]))*df.val.values,1)
Out[44]: array([ 100,  200,  300,  700, 1200], dtype=int64)
<小时>

一些时间

#df=pd.concat([df]*1000)
%timeit merged(df)
1 loop, best of 3: 5.02 s per loop
%timeit npb(df)
1 loop, best of 3: 283 ms per loop
% timeit PIR(df)
100 loops, best of 3: 9.8 ms per loop
<小时>
def merged(df):
    df['dummy'] = 1
    df = df.merge(df, on=['dummy'], how='left')
    df = df[(df['start_y'] <= df['start_x']) & (df['finish_y'] > df['start_x'])]
    val = df.groupby('start_x')['val_y'].sum()
    return val

def npb(df):
    s1 = df['start'].values
    s2 = df['finish'].values
    return np.sum(((s1 <= s1[:, None]) & (s2 >= s2[:, None])) * df.val.values, 1)

本文地址:https://www.itbaoku.cn/post/1727854.html