有没有一个好方法可以做到"移动" numpy数组的计算?

时间:2017-06-13 17:14:31

标签: python arrays numpy indexing

我正在开发一个数据处理项目,我通常希望将1D numpy数组作为输入,输出一个等长数组,通过处理一定数量的输入元素生成元素。 这是一个使用for循环解决的相对简单的问题,但是我想知道numpy是否有内置的方法来做这个,我认为这会明显更快。

为了说明我的目标,想象一次生成一个向量(B)1元素,并让生成的当前元素为元素N(表示为B [N])。

假设我希望B是一个向量,其元素对应于向量A中元素的简单移动平均值。 我希望能够说的是

B[i] = AVG(A[(i-N):i]) #N <= i < len(A) 

这里我是运行的任何底层循环的迭代索引,AVG是一个通用函数,它计算传递给它的数字组的平均值。

正如我所说的那样,使用for循环很容易,但这看起来像numpy这样的东西应该能够很容易地完成,所以我想在我丢弃我的代码之前我会问专业人员结构。

3 个答案:

答案 0 :(得分:1)

查看Pandas中的standard moving window functions。例如,窗口大小为10的移动平均线为pd.rolling_mean(data, window=10)

您还可以使用pd.rolling_apply(data, lambda x: np.mean(x), window=10)提供自己的聚合函数,该函数与前一个函数相同。

答案 1 :(得分:1)

有点低级别,但您可以通过将数据与您选择的窗口进行交叉关联来过滤数据。移动平均窗口是一堆被分割的,但是有很多。请注意,相关性具有各种“模式”,并且起点/终点的有效性会发生变化。

import numpy as np
import scipy.signal as signal
import matplotlib.pyplot as plt

window_size = 10
window = np.ones(window_size) / window_size
x = np.random.rand(100)

x_filt = signal.correlate(x, window, mode='same')

f, ax = plt.subplots()
ax.plot(x)
ax.plot(x_filt)

答案 2 :(得分:0)

不使用卷积的最简单的纯粹numpy解决方案是使用np.cumsum的解决方案。基本思想是从索引i - N到索引i(包括两者)的元素总和是累计总和i,减去累计总和i - N - 1 。规范化只是N本身:

s = np.cumsum(A)
B = (s[N:] - s[:-N]) / N

目前尚不清楚您是否希望BA的长度相同。如果是这样,您可以使用np.concatenatenp.r_将累积总和的前N个值添加到B

B = np.concatenate((s[:N] / np.arange(N), (s[N:] - s[:-N]) / N))

OR

B = np.r_[s[:N] / np.arange(N), (s[N:] - s[:-N]) / N]

写完之后,我意识到@Jaime对基本相同的问题here有一个非常相似的答案。我将保留我的答案,因为它正确地规范了数组的初始部分,我不相信Jaime的答案。