【问题标题】:Moving average of a list of lists in python [closed]python中列表列表的移动平均值[关闭]
【发布时间】:2013-09-06 14:48:54
【问题描述】:

我有一个大数组,但结构类似于:

[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]

使数组变平的情况下,获取 5 个元素的滚动平均值的最佳、最有效的方法是什么。 即

值 1 为 (0+1+2+3+4)/5=2

值 2 为 (1+2+3+4+5)/5=3

值三将是 (2+3+4+5+6)/5=4

谢谢

【问题讨论】:

  • 似乎% 5 在某处有用,但我不是 Python 专家。
  • 您是否有特殊原因不想展平阵列?

标签: python numpy average


【解决方案1】:

执行此操作的“最佳”方法可能是将数组视图提交给uniform_filter。我不确定这是否会破坏您的“无法展平阵列”,但如果不以某种方式重塑阵列,所有这些方法都会比以下方法慢得多:

import numpy as np
import scipy.ndimage.filters as filt

arr=np.array([[0,1,2,3,4],
[5,6,7,8,9],
[10,11,12,13,14],
[15,16,17,18,19]])

avg =  filt.uniform_filter(arr.ravel(), size=5)[2:-2]

print avg
[ 2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17]

print arr.shape  #Original array is not changed.
(4, 5)

【讨论】:

    【解决方案2】:

    伪代码(虽然它可能看起来有点像 Python):

    for i = 0 to 15:
        sum = 0
        for j from 0 to 4:
            // yourLists[m][n] is the nth element of your mth list (zero-indexed)
            sum = sum + yourLists [ (i + j) / 5 ] [ (i + j) % 5 ]
        next j
        print i, sum/5
    next i
    

    你可能会做得更好一点,不要每次都添加所有五个数字。

    【讨论】:

      【解决方案3】:

      “最佳”解决方案将取决于为什么您一开始不想展平阵列的原因。如果数据在内存中是连续的,则使用步幅技巧是一种无需显式展平数组即可计算滚动平均值的有效方法:

      In [1]: a = np.arange(20).reshape((4, 5))
      
      In [2]: a
      Out[2]: 
      array([[ 0,  1,  2,  3,  4],
             [ 5,  6,  7,  8,  9],
             [10, 11, 12, 13, 14],
             [15, 16, 17, 18, 19]])
      
      In [3]: from numpy.lib.stride_tricks import as_strided
      
      In [4]: s = a.dtype.itemsize
      
      In [5]: aa = as_strided(a, shape=(16,5), strides=(s, s))
      
      In [6]: np.average(aa, axis=1)
      Out[6]: 
      array([  2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.,  11.,  12.,
              13.,  14.,  15.,  16.,  17.])
      

      【讨论】:

        【解决方案4】:

        注意:此答案不是numpy 特定的。

        如果列表的列表可以展平,这会更简单。

        from itertools import tee
        
        def moving_average(list_of_list, window_size):
            nums = (n for l in list_of_list for n in l)
            it1, it2 = tee(nums)
            window_sum = 0
            for _ in range(window_size):
                window_sum += next(it1)
            yield window_sum / window_size
            for n in it1:
                window_sum += n
                window_sum -= next(it2)
                yield window_sum / window_size
        

        【讨论】:

          猜你喜欢
          • 2016-06-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多