优化用于活动识别的低通滤波器平滑代码

时间:2015-11-04 10:23:16

标签: python numpy pandas scipy accelerometer

我正在尝试在加速度计数据上实现低通滤波器(使用x加速度(ax),y加速度(ay),z加速度(az))

我计算出我的alpha为0.2

沿x方向的DC分量使用公式

计算

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]

2 个答案:

答案 0 :(得分:1)

首先,你似乎不需要

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分钟。

答案 1 :(得分:0)

假设您使用的是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模块,在内存中获取一个数组并进行计算,并用ctypes python调用它图书馆。