为 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图书馆。