我有一个Pandas数据框,我试图用组的平均值替换每个组中的值。在我的计算机上,行df["signal"].groupby(g).transform(np.mean)
大约需要10秒才能运行,N
和N_TRANSITIONS
设置为以下数字。
有没有更快的方法来实现相同的结果?
import pandas as pd
import numpy as np
from time import time
np.random.seed(0)
N = 120000
N_TRANSITIONS = 1400
# generate groups
transition_points = np.random.permutation(np.arange(N))[:N_TRANSITIONS]
transition_points.sort()
transitions = np.zeros((N,), dtype=np.bool)
transitions[transition_points] = True
g = transitions.cumsum()
df = pd.DataFrame({ "signal" : np.random.rand(N)})
# here is my bottleneck for large N
tic = time()
result = df["signal"].groupby(g).transform(np.mean)
toc = time()
print toc - tic
答案 0 :(得分:4)
pd.Series(np.repeat(grp.mean().values, grp.count().values))
答案 1 :(得分:3)
当前方法,使用transform
In [44]: grp = df["signal"].groupby(g)
In [45]: result2 = df["signal"].groupby(g).transform(np.mean)
In [47]: %timeit df["signal"].groupby(g).transform(np.mean)
1 loops, best of 3: 535 ms per loop
使用结果的'广播'
In [43]: result = pd.concat([ Series([r]*len(grp.groups[i])) for i, r in enumerate(grp.mean().values) ],ignore_index=True)
In [42]: %timeit pd.concat([ Series([r]*len(grp.groups[i])) for i, r in enumerate(grp.mean().values) ],ignore_index=True)
10 loops, best of 3: 119 ms per loop
In [46]: result.equals(result2)
Out[46]: True
我认为您可能需要在广播结果上设置返回的索引(它恰好在这里工作,因为它是默认索引</ p>
result = pd.concat([ Series([r]*len(grp.groups[i])) for i, r in enumerate(grp.mean().values) ],ignore_index=True)
result.index = df.index