为 activity 识别优化低通滤波器平滑代码
optimizing low pass filter smoothing code for activity recognition
我正在尝试对加速度计数据(使用 x 加速度 (ax)、y 加速度 (ay)、z 加速度 (az))实施低通滤波器
我计算出我的 alpha 为 0.2
沿x方向的直流分量使用公式计算
new_ax[n] = (1-alpha)*new_ax[n-1] + (alpha * ax[n])
我可以针对具有几千条记录的小型数据集进行计算。但是我有一个包含一百万条记录的数据集,使用下面的代码需要很长时间才能 运行 。如果能帮助我改进时间复杂度的代码,我将不胜感激。
### df is a pandas dataframe object
n_ax = []
seq = range(0, 1000000, 128)
for w in range(len(seq)):
prev_x = 0
if w+1 <= len(seq):
subdf = df[seq[w]:seq[w+1]]
for i in range(len(subdf)):
n_ax.append((1-alpha)*prev_x + (alpha*subdf.ax[i]))
prev_x = n_ax[i]
首先你似乎不需要
if w+1 <= len(seq):
w 变量不会超过 len(seq)。
所以要减少处理时间,只需使用 numpy 模块:
import numpy;
在这里你会发现比内置列表快得多的数组和方法。例如,与其循环遍历 numpy 数组中的每个元素来进行一些处理,不如直接在数组上应用 numpy 函数,并在几秒钟而不是几小时内获得结果。例如:
data = numpy.arange(0, 1000000, 128);
shiftData = numpy.arange(128, 1000000, 128);
result = (1-alpha)*data[:-1] + shiftdata;
查看一些关于 numpy 的教程。我使用这个模块来处理图像数据,相比之下,循环遍历列表需要我 2 周的时间来处理 5000 多张图像,而使用 numpy 类型最多需要 2 分钟。
假设您使用的是 python 2.7.
- 使用 xrange。
- 在循环内计算
len(seq)
是没有必要的,因为它的值不会改变。
- 访问
seq
它并不是真正需要的,因为您可以即时计算它。
- 你并不真的需要
if
语句,因为在你的代码中它总是计算为真(w in range(len(seq))
意味着 w
最大值将是 len(seq)-1
) .
- 您为获得
subdf
而进行的切片并不是真正必要的,因为您可以直接访问 df(并且切片会创建一个新列表)。
查看下面的代码。
n_ax = []
SUB_SAMPLE = 128
SAMPLE_LEN = 1000000
seq_len = SAMPLE_LEN/SUB_SAMPLE
for w in xrange(seq_len):
prev_x = 0
for i in xrange(w*SUB_SAMPLE,(w+1)*SUB_SAMPLE):
new_x = (1-alpha)*prev_x + (alpha*df.ax[i])
n_ax.append(new_x)
prev_x = new_x
我想不出任何其他明显的优化。如果这仍然很慢,也许您应该考虑将 df
数据复制到 python 本机数据类型。如果这些都是浮点数,使用 python array
可以提供很好的性能。
如果你仍然需要更好的性能,你可以尝试使用 multiprocessing
模块的并行性,或者编写一个 C 模块,在内存中获取一个数组并进行计算,然后用 [=21= 调用它] python图书馆。
我正在尝试对加速度计数据(使用 x 加速度 (ax)、y 加速度 (ay)、z 加速度 (az))实施低通滤波器
我计算出我的 alpha 为 0.2
沿x方向的直流分量使用公式计算
new_ax[n] = (1-alpha)*new_ax[n-1] + (alpha * ax[n])
我可以针对具有几千条记录的小型数据集进行计算。但是我有一个包含一百万条记录的数据集,使用下面的代码需要很长时间才能 运行 。如果能帮助我改进时间复杂度的代码,我将不胜感激。
### df is a pandas dataframe object
n_ax = []
seq = range(0, 1000000, 128)
for w in range(len(seq)):
prev_x = 0
if w+1 <= len(seq):
subdf = df[seq[w]:seq[w+1]]
for i in range(len(subdf)):
n_ax.append((1-alpha)*prev_x + (alpha*subdf.ax[i]))
prev_x = n_ax[i]
首先你似乎不需要
if w+1 <= len(seq):
w 变量不会超过 len(seq)。
所以要减少处理时间,只需使用 numpy 模块:
import numpy;
在这里你会发现比内置列表快得多的数组和方法。例如,与其循环遍历 numpy 数组中的每个元素来进行一些处理,不如直接在数组上应用 numpy 函数,并在几秒钟而不是几小时内获得结果。例如:
data = numpy.arange(0, 1000000, 128);
shiftData = numpy.arange(128, 1000000, 128);
result = (1-alpha)*data[:-1] + shiftdata;
查看一些关于 numpy 的教程。我使用这个模块来处理图像数据,相比之下,循环遍历列表需要我 2 周的时间来处理 5000 多张图像,而使用 numpy 类型最多需要 2 分钟。
假设您使用的是 python 2.7.
- 使用 xrange。
- 在循环内计算
len(seq)
是没有必要的,因为它的值不会改变。 - 访问
seq
它并不是真正需要的,因为您可以即时计算它。 - 你并不真的需要
if
语句,因为在你的代码中它总是计算为真(w in range(len(seq))
意味着w
最大值将是len(seq)-1
) . - 您为获得
subdf
而进行的切片并不是真正必要的,因为您可以直接访问 df(并且切片会创建一个新列表)。
查看下面的代码。
n_ax = []
SUB_SAMPLE = 128
SAMPLE_LEN = 1000000
seq_len = SAMPLE_LEN/SUB_SAMPLE
for w in xrange(seq_len):
prev_x = 0
for i in xrange(w*SUB_SAMPLE,(w+1)*SUB_SAMPLE):
new_x = (1-alpha)*prev_x + (alpha*df.ax[i])
n_ax.append(new_x)
prev_x = new_x
我想不出任何其他明显的优化。如果这仍然很慢,也许您应该考虑将 df
数据复制到 python 本机数据类型。如果这些都是浮点数,使用 python array
可以提供很好的性能。
如果你仍然需要更好的性能,你可以尝试使用 multiprocessing
模块的并行性,或者编写一个 C 模块,在内存中获取一个数组并进行计算,然后用 [=21= 调用它] python图书馆。