我从一个accelorometer获得了一些数据,我试图平滑这些值。我遇到的问题是我的数据框包含大约。因此,下面显示的1,000,000行并运行平滑功能需要几分钟(我在jupyter中运行它)
def smoothing(df, alpha, length):
df['x'][0] = df['x'][0] * alpha
for i in range(1,length):
df['x'][i] = df['x'][i-1]+alpha*(df['x'][i] - df['x'][i-1])
return df
我的问题是,无论如何通过使用矢量化,pandas.apply或类似方法来增强或加速此计算。请注意,我自己尝试过使用这些方法,但没有任何运气,因为我未能产生正确的结果。我努力的部分是获得前一行的结果,我不确定如何例如使用.shift()来获得与 smoothing 函数
相同的功能以下是一些示例数据:
x_list = [21,42,49,8,0,-57,-137, -135,-177, -181]
data = pd.DataFrame(x_list, columns=['x'])
smoothing(data, 0.02, len(x_list))
预期结果:
x
0 0
1 0
2 0
3 0
4 0
5 -1
6 -3
7 -5
8 -8
9 -11
答案 0 :(得分:2)
您可以在全局变量的帮助下使用apply来存储计算值以获得所需的输出,即
store = 0
def m(x):
global store
if x == data['x'][0]:
store = 0.2*x
return store
else :
store = (store+alpha*(x - store))
return store
data['x'].apply(m)
输出:
0 4.200000 1 11.760000 2 19.208000 3 16.966400 4 13.573120 5 -0.541504 6 -27.833203 7 -49.266563 8 -74.813250 9 -96.050600 Name: x, dtype: float64
%%timeit data['x'].apply(m) 1000 loops, best of 3: 478 µs per loop n = pd.concat([data['x']]*10000).reset_index(drop=True) # in function condtion shld be n[0] instead of data['x'][0] n.apply(m) 1 loop, best of 3: 2.18 s per loop
答案 1 :(得分:2)
这是numba方式,它比OP中的功能快得多(10,000行快约20,000倍,并且不是错字!):
from numba import njit
@njit
def smoothing_numba(x,alpha):
x[0] = x[0] * alpha
for i in range(1,len(x)):
x[i] = x[i-1] + alpha * ( x[i] - x[i-1] )
return x
smoothing_numba(data.x.values,0.02)
如果您将@njit
装饰器从上述代码中删除,则您将拥有标准的numpy功能。结果比numba慢约150倍,但仍比原始功能快150倍。
以下是10,000行的时间。
np.random.seed(123)
data = pd.DataFrame(np.random.randn(10000), columns=['x'])
%timeit smoothing(data, 0.02, len(data))
1 loop, best of 3: 995 ms per loop
%timeit smoothing_numba(data.x.values, 0.02)
10000 loops, best of 3: 41.8 µs per loop
在这样的情况下,循环是不可避免的,从将pandas函数转换为numpy / numba函数看到显着的加速肯定并不罕见。另请注意,numba设计为与numpy配合使用,因此一旦将函数从pandas转换为numpy,使用@njit
进行装饰以增加速度通常是微不足道的。