不是一个特别的潘达西解决方案,但听起来你想做一些类似的事情df['rv'] = np.nan
for i in range(len(df)):
j = i
s = 0
while j >= 0 and s < 5:
s += df['distance'].loc[j]
j -= 1
if s >= 5:
df['rv'].loc[i] = df['velocity'][j+1:i+1].mean()
更新:既然回答了这个问题,OP表示他们需要一个“有效的Pandas解决方案(例如,没有循环)”。如果我们认为这意味着他们想要比上述更高性能的东西,那么,也许讽刺的是,考虑到这个评论,首先想到的优化是避免数据帧,除非需要:
^{pr2}$
此外,正如@JohnE建议的那样,numba很快就可以用于进一步的优化。虽然它在上面的第一个解决方案上没有多大作用,但是第二个解决方案可以用一个现成的@numba.jit来装饰,从而带来立竿见影的好处。将所有三种解决方案pd.DataFrame({'velocity': 50*np.random.random(10000), 'distance': 5*np.random.rand(10000)})
我得到以下结果:Method Benchmark
-
Original data frame based 4.65 s ± 325 ms
Pure numpy array based 80.8 ms ± 9.95 ms
Jitted numpy array based 766 µs ± 52 µs
即使是看起来很无辜的mean也足以摆脱numba;如果我们摆脱它,转而使用@numba.jit
def numba_example():
l = len(df)
a = np.empty(l)
d = df['distance'].values
v = df['velocity'].values
for i in range(l):
j = i
s = 0
while j >= 0 and s < 5:
s += d[j]
j -= 1
if s >= 5:
for k in range(j+1, i+1):
a[i] += v[k]
a[i] /= (i-j)
df['rv'] = a
然后基准降低到158µs±8.41µs
现在,如果您碰巧更了解df['distance']的结构,while循环可能会进一步优化。(例如,如果值恰好总是远远小于5,则从其尾部减去累计和将更快,而不是重新计算所有值。)