【问题标题】:Is there a good way to do "moving" calculations on numpy arrays?有没有一种对 numpy 数组进行“移动”计算的好方法?
【发布时间】:2017-06-13 17:14:30
【问题描述】:

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

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

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

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

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

正如我所说,使用 for 循环很容易,但这似乎像 numpy 之类的东西应该能够很容易地完成,所以我想在我乱丢代码的结构不是最优的之前先问问专业人士。

【问题讨论】:

  • 很遗憾,这需要一个具体的例子来回答。
  • @J.C.Leitão。这个问题与这个无关。 OP 正试图放弃使用原始 Python 并改用 numpy。
  • 你玩过np.cumsumnp.cumprod这样的函数吗?
  • @MadPhysicist 是不是伪代码不够具体?我相信我对我的目标的解释非常透彻。我只是想知道 numpy 是否有内置的方式来做我在 sudo 代码中所做的事情。
  • @hpaulj 我在某些应用程序中使用过 cumsum,但尝试将它用于测量运动信息(例如标准偏差)的东西我认为它并没有真正起作用。

标签: python arrays numpy indexing


【解决方案1】:

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

你也可以用pd.rolling_apply(data, lambda x: np.mean(x), window=10)提供自己的聚合函数,和上一个一样。

【讨论】:

  • 虽然 Pandas 肯定不会被淘汰,但现在我真的特别想知道 numpy。这确实看起来正是我最终想要做的,谢谢你的提示!
  • 我接受了这个答案,尽管它并不完全符合最初的问题。 @Mad Physicist 的回答是针对特定问题的一个很好的解决方案。但是,如果您希望在一个项目中应用多种不同的流程算法,则此解决方案的适用性要大得多。 Pandas 值得单独使用这个功能。
【解决方案2】:

有点低级,但您可以通过将数据与您选择的窗口进行交叉关联来过滤数据。移动平均窗口是一堆窗口除以有多少窗口。请注意,相关具有各种“模式”,并且起点/终点的有效性各不相同。

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)

【讨论】:

    【解决方案3】:

    不使用卷积的最简单的纯 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))
    

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-25
      • 1970-01-01
      • 1970-01-01
      • 2014-09-15
      • 2013-12-09
      • 1970-01-01
      • 2019-08-13
      • 1970-01-01
      相关资源
      最近更新 更多