加速使用前几行结果的行操作
Speeding up a row operation that uses the result of previous rows
我有一些来自加速度计的数据,我试图在其中平滑这些值。我遇到的问题是我的数据框包含大约。 1,000,000 行和 运行 smoothing 函数因此需要几分钟(我在 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
您可以在全局变量的帮助下使用 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
这是 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
装饰以提高速度。
我有一些来自加速度计的数据,我试图在其中平滑这些值。我遇到的问题是我的数据框包含大约。 1,000,000 行和 运行 smoothing 函数因此需要几分钟(我在 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
您可以在全局变量的帮助下使用 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
这是 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
装饰以提高速度。