2013-06-11 4 views
3

Скажем, у меня есть массив списковКак вычислить среднее значение элементов в списке по столбцам?

B = [[1,2,3],[1,2,3,4],[1,2]] 

и я хочу, чтобы вычислить среднее значение элементов в списках поперек coloumns. Как мне это сделать?

т.е.

Как получить окончательный массив средних значений, равный длинный список:

[(1+1+1)/3,(2+2+2)/3,(3+3)/2,4/1] = [1,2,3,4] 

Я попытался:

final_array = np.array([mean(a) for a in zip(*(B))]) 

Но это дает мне массив только как длинный как мой самый короткий список. Это маска пригодится? Мои извинения, если массив списков заставляет вас съеживаться, я все еще привык к Python.

ответ

1

Еще один способ, с помощью cmp и izip_longest

from itertools import izip_longest 
[float(sum(col))/sum(cmp(x,0) for x in col) for col in izip_longest(*B, fillvalue=0)] 

это предполагает, что значения положительны.

+1

Замечание 'cmp' ушло в Python 3 – jamylak

+0

Это не сработает, если в списке есть 0. –

+0

Спасибо. Отсюда и предостережение. –

4

Вам понадобится внести свой список с некоторым количеством дозорных значений (я использовал NaN), а затем создаю маскированный массив с этим часовым. Когда у вас есть маскированный массив, вы можете вычислить среднее значение без каких-либо проблем.

>>> import numpy as np 
>>> B = [[1,2,3],[1,2,3,4],[1,2]] 
>>> 
>>> maxlen = max(len(x) for x in B) 
>>> C = np.array([l+[np.nan]*(maxlen-len(l)) for l in B]) 
>>> C 
array([[ 1., 2., 3., nan], 
     [ 1., 2., 3., 4.], 
     [ 1., 2., nan, nan]]) 
>>> dat = np.ma.fix_invalid(C) 
>>> np.mean(dat,axis=0) 
masked_array(data = [1.0 2.0 3.0 4.0], 
      mask = [False False False False], 
     fill_value = 1e+20) 
+0

Есть лучший способ замаскировать 'NAN':' np.ma.fix_invalid (C) ' – jamylak

+0

@jamylak - Да, это может быть немного чище ... – mgilson

1

Использование itertools.izip_longest и itertools.takewhile:

>>> from itertools import takewhile, izip_longest 
def means(lis): 
    fill = object() 
    for item in izip_longest(*lis,fillvalue = fill): 
     vals = list(takewhile(lambda x : x!=fill , item)) 
     yield sum(vals)/float(len(vals)) 
...   
>>> lis = [[1,2,3],[1,2,3,4],[1,2]] 
>>> lis.sort(key = len, reverse = True) #reverse sort the list based on length of items 
>>> list(means(lis)) 
[1.0, 2.0, 3.0, 4.0] 
0
B = [[1,2,3],[1,2,3,4],[1,2]] 
data = {} 
max_len = 0 

for alist in B: 
    length = len(alist) 
    max_len = length if (length > max_len) else max_len 

    for i in range(length): 
     data.setdefault(i, []).append(alist[i]) 


results = [] 

for i in range(max_len): 
    vals = data[i] 
    results.append(sum(vals)/len(vals)) 

print results 

--output:-- 
[1, 2, 3, 4] 
6

Вы можете его помощью DataFrame панд.

from pandas import DataFrame 

B = [[1,2,3],[1,2,3,4],[1,2]] 
df = DataFrame(B) 
df.mean(axis=0) 
"""" 
df 
    0 1 2 3 
0 1 2 3 NaN 
1 1 2 3 4 
2 1 2 NaN NaN 

df.mean(axis=0) 
0 1 
1 2 
2 3 
3 4 
""" 
+0

+1 Лучший ответ (хотя OP, похоже, хочет только numpy) – jamylak

0

Вы можете сделать это без какой-либо внешней LIBS:

B = [[1,2,3],[1,2,3,4],[1,2]] 
#compute max length of sub list 
maxLen = max([len(x) for x in B]) 
#new list with number of empty lists equals to number of columns 
transList = [[] for i in range(maxLen)] 
#transforming list to new structure 
for row in B: 
    for col in row: 
     transList[col-1].append(col) 
#transList = [[1, 1, 1], [2, 2, 2], [3, 3], [4]] from now one its simple to get mean of the elements ;) 
meanB = [float(sum(i))/len(i) for i in transList] 

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

  • Нет связанных вопросов^_^