如何计算列表中跨列元素的平均值?

3

假设我有一个列表数组

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

我想计算列表中元素在列之间的平均值。我该怎么做?

也就是说,我如何得到一个包含最长列表平均值的最终数组:

[(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。

6个回答

6
您可以使用pandas的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
"""

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)

有一种更好的方法来掩盖“NAN”:np.ma.fix_invalid(C) - jamylak

1
使用 itertools.izip_longestitertools.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]

1

还有一种方式,使用cmpizip_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
注意,在Python 3中,cmp已经被删除。 - jamylak
1
如果您使用的是 Python 2.X,请将 sum(col) 更改为 float(sum(col)),或者使用 from __future__ import division,或者进行其他更改以确保除法不是整数除法。否则,在所有值都为整数时,通常会得到不正确的答案。 - Warren Weckesser

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]

0

你可以不使用任何外部库来完成它:

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]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接