基于其他行Pandas更新一行的列

问题描述 投票:0回答:2

我有一个如下数据框:

Time   col1  col2  col3 
2      a     x     10
3      b     y     11
1      a     x     10
6      c     z     12
20     c     x     13
23     a     y     24
14     c     x     13     
16     b     y     11
...

并且想要根据其他数据帧行向每行数据帧添加一列,这是数据帧:

Time   col1  col2  col3 cumVal
2      a     x     10   2
3      b     y     11   1
1      a     x     10   2
6      c     z     12   1
20     c     x     13   2
23     a     y     24   1
14     c     x     13   2
16     b     y     11   1
...

我试一试:

df['cumVal'] = 0
for index, row in df.iterrows():
   min1 = row['Time']-10
   max1 = row['Time']+10
   ndf = df[(df.col1 == row.col1)&(df.col2 == row.col2)& (df.col3 == 
   row.col3)]
   df.iloc[index]['cumVal'] = len(ndf.query('@min1 <= Time <= @max1'))

但它很慢,任何人都可以更改我的代码以获得更快?

python pandas
2个回答
1
投票

您可以在'col1','col2'和'col3'以及每组的groupby中使用transform,使用np.subtract作为outer的ufunc来计算该组的'Time'列中的值之间的所有差异,然后使用np.abs在轴= 0下低于10和np.sum,您可以计算每个值在+/- 10内的值。

import numpy as np
df['cumVal'] = (df.groupby(['col1','col2','col3'])['Time']
                  .transform(lambda x: (np.abs(np.subtract.outer(x, x))<=10).sum(0)))
print (df)
   Time col1 col2  col3  cumVal
0   2.0    a    x  10.0     2.0
1   3.0    b    y  11.0     1.0
2   1.0    a    x  10.0     2.0
3   6.0    c    z  12.0     1.0
4  20.0    c    x  13.0     2.0
5  23.0    a    y  24.0     1.0
6  14.0    c    x  13.0     2.0
7  16.0    b    y  11.0     1.0

0
投票

它应该提供更好的性能:

df['cumVal'] = 0
for index, row in df.iterrows():
   min1 = row['Time']-10
   max1 = row['Time']+10
   ndf = df[(df.Time>min1)&(df.Time<max1)&(df.col1 == row.col1)&(df.col2 == row.col2)& (df.col3 == 
   row.col3)]
   df.iloc[index]['cumVal'] = len(ndf)
© www.soinside.com 2019 - 2024. All rights reserved.