2014-01-03 3 views
2

Предполагая массив (1-d), можно ли вычислить среднее значение для заданных групп разного размера без цикла? ВместоNumPy: вычислять среднее из некоторых элементов в массиве

avgs = [One_d_array[groups[i]].mean() for i in range(len(groups))] 

Что-то вроде

avgs = np.mean(One_d_array, groups) 

В основном я хочу, чтобы это сделать:

M = np.arange(10000) 
np.random.shuffle(M) 
M.resize(100,100) 
groups = np.random.randint(1, 10, 100) 

def means(M, groups): 
    means = [] 
    for i, label in enumerate(groups): 
     means.extend([M[i][groups == j].mean() for j in set(p).difference([label])]) 
    return means 

Это работает на

%timeit means(M, groups) 
100 loops, best of 3: 12.2 ms per loop 

Увеличение скорости в 10 раз или около того будет быть уже отличным

ответ

1

Видите ли вы петлю или нет, существует цикл.
Вот один из способов, но петля просто скрыта в вызове map:

In [10]: import numpy as np 

In [11]: groups = [[1,2],[3,4,5]] 

In [12]: map(np.mean, groups) 
Out[12]: [1.5, 4.0] 
+0

Я думаю, вы как раз правильно. Однако есть ли способ сделать вычисление среднего быстрее? Это узкое место в нескольких функциях, с которыми я имею дело. – embert

+0

Массив NumPy может быть быстрым, когда вы применяете NumPy-функции, такие как 'np.mean', к одному большому массиву. NumPy может быть не очень быстрым, если вам нужно вызвать 'np.mean' на множество небольших массивов. Если вы не можете упорядочить свои данные в одном большом массиве (возможно, потому, что строки имеют разную длину), вам может быть лучше использовать простые списки Python, чем множество небольших массивов NumPy. (Трудно сказать - вам нужно ориентироваться на 'timeit'.) – unutbu

+0

Если вы снова и снова вычисляете среднее значение« групп »(с небольшими изменениями в« группах »между итерациями), тогда было бы разумно вести текущие итоги суммы каждого элемента в 'группах'. Таким образом, вы можете обновить итоговые значения как изменения «групп», и легко и быстро вычислить новые средства. – unutbu

0

Другой скрытый цикл является использование np.vectorize:

>>> x = np.array([1,2,3,4,5]) 
>>> groups = [[0,1,2], [3,4]] 
>>> np.vectorize(lambda group: np.mean(x[group]), otypes=[float])(groups) 
array([ 2. , 4.5])