2013-08-30 5 views
4

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

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

  1. Использование numpy.array_split функции():

    import numpy as np 
    no_splits = 3 #Or any number user defines 
    no_items = int(np.random.random(1)*100) # To get a variable number of items 
    pre_array = np.random.random(no_items) 
    mean_array = np.mean(np.array_split(pre_array,no_splits)) 
    #This is efficient but gives an error if len(pre_array)%no_splits != 0 
    
  2. перечисление (pre_array) альтернатива:

    mean_array = [np.mean(pre_array[i-no_splits+1:i]) for i, x in enumerate(pre_array) if i%no_splits == 0 and i != 0] 
    

Это нормально, но зажимает последние значения, если i% no_splits! = 0. В идеале я бы создал последнее значение, которое является средним из оставшихся при сохранении кода.

Каждое из этих работ для моих целей, но я не уверен, являются ли они наиболее эффективными для больших массивов.

Спасибо заранее!

+0

ли вы имеете в виду вы хотите усреднить '0 1 2' и' 1 2 3' ... * или * '0 1 2' и '3 4 5' ... от' 0 1 2 3 4 ... '? – Daniel

+0

Привет @Ophion Мне нужен последний, ваш ответ, если я понял и правильно его испробовал, использует средний метод движущегося окна, длина массива которого совпадает с исходным массивом. Я хотел бы, чтобы длина была равна len (new_array) = original_array/no_splits округленная. – Matt

+0

Я обновил свой ответ, пожалуйста, дайте мне знать, если это то, что вы ищете. – Daniel

ответ

4

Использование uniform_filter:

>>> import scipy.ndimage.filters as filter 

>>> a=np.arange(5,dtype=np.double) 
>>> filter.uniform_filter(a,size=3) 
array([ 0.33333333, 1.  , 2.  , 3.  , 3.66666667]) 

#What this is actually doing 
>>> np.mean([0,0,1]) #ind0 
0.33333333333333331 
>>> np.mean([0,1,2]) #ind1 
1.0 
>>> np.mean([1,2,3]) #ind2 
2.0 

Может быть использован с любым размер окна.

>>> filter.uniform_filter(a,size=5) 
array([ 0.8,  1.2,  2. ,  2.8,  3.2]) 

Опасность здесь заключается в том, что аккумулятор будет любым типом массива.


Group тремя затем взять среднее:

def stride_mean(arr,stride): 
    extra = arr.shape[0]%stride 
    if extra==0: 
     return np.mean(arr.reshape(-1,stride),axis=1) 
    else: 
     toslice = arr.shape[0]-extra 
     first = np.mean(arr[:toslice].reshape(-1,stride),axis=1) 
     rest = np.mean(arr[toslice:]) 
     return np.hstack((first,rest)) 

print pre_array 
[ 0.50712539 0.75062019 0.78681352 0.35659332] 

print stride_mean(pre_array,3) 
[ 0.6815197 0.35659332] 
+0

Вторая часть - это то, о чем просит ОП. – lmjohns3

1
no_splits = 3 
no_items = 100 
a = np.random.rand(no_items) 

no_bins = no_splits + no_items % no_splits 
b = np.empty((no_bins,), dtype=a.dtype) 
endpoint = no_items//no_splits 

b[:no_splits] = np.mean(a[:endpoint*no_splits].reshape(-1, endpoint), 
         axis=-1) 
b[no_splits:] = np.mean(a[endpoint*no_splits:]) 
>>> b 
array([ 0.49898723, 0.49457975, 0.45601632, 0.5316093 ]) 
+0

Я не уверен, что это дает мне то, что я хотел - если есть 100 предметов len (b) = 34, при этом последняя точка является средним значением для одного элемента. В массиве = [0, 1, 2, 3, 4, 5, 6] Я хочу, чтобы новый массив был [средний [0 1 2], средний [3 4 5], средний [6]]. Спасибо за помощь! – Matt

Смежные вопросы