2013-09-06 3 views
1

У меня есть большой массив, но с аналогичной структурой в:Скользящее среднее из списка списков в Python

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

Что бы быть лучшим, наиболее эффективным способом приема скользящее среднее из 5 элементов без сплющивание массива. т.е.

значение можно было бы быть (0 + 1 + 2 + 3 + 4)/5 = 2

значение два будет (1 + 2 + 3 + 4 + 5)/5 = 3

значение три будет (2 + 3 + 4 + 5 + 6)/5 = 4

Благодаря

+0

выглядит как '% 5' было бы полезно где-то, но я не Гуру Питона. – John

+0

Есть ли конкретная причина, по которой вы не хотите сгладить массив? – Daniel

ответ

0

псевдокод (хотя это, вероятно, выглядеть немного как 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 

Возможно, вы можете немного улучшить, не добавляя все пять номеров каждый раз.

0

Примечание: Этот ответ не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 
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) 
0

«Наилучшее» решение будет зависеть от Причина Почему вы не хотите сгладить массив в первую очередь. Если данные являются смежными в памяти, используя Stride трюки является эффективным способом для вычисления скользящего среднего без явного уплощения массива:

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.]) 
Смежные вопросы