计算不同长度的三维数组的均值
我有一个三维数组,尺寸是 n * d * m。不过,n 的大小是可以变化的。它看起来像这样:
[[[1,1,3], [[3,2,1], [[4,3,2],
[3,4,2]], [3,4,2], [5,2,3]]]
[4,5,3]],
我需要计算所有数据点的平均值。我之前使用了 scipy.stats.mean
这个函数,但它报错说维度不匹配。因此,我在考虑把数组填充到最大的 n 使得它的尺寸一致,像这样:
[[[ 1, 1, 3], [[3,2,1], [[ 4, 3, 2],
[ 3, 4, 2], [3,4,2], [ 5, 2, 3],
[NaN,NaN,NaN]], [4,5,3]], [NaN,NaN,NaN]]]
但我不知道这是否是最好的解决办法,或者我该如何用 NaN 来计算平均值。
有没有什么建议呢?
3 个回答
0
看起来你遇到的问题是因为你的对象是一个包含二维数组的列表,而不是一个三维的numpy数组,所以所有的numpy数组函数都无法正常工作。
一个解决办法是把这个列表展开,然后分别计算平均值。在你的情况下,可以这样做:
In [23]: import numpy as np
In [24]: L = np.array([[[1,1,3],[3,4,2]],
[[3,2,1],[3,4,2],[4,5,3]],[[4,3,2],[5,2,3]]])
In [28]: Lsum = ( np.sum(L[0]) + np.sum(L[1]) + np.sum(L[2]) )
In [29]: Lmean = Lsum.astype(float) \
/ ( np.size(L[0]) + np.size(L[1]) + np.size(L[2]) )
In [46]: Lmean
Out[46]: 2.8571428571428572
这个过程可以放在一个循环里,以便处理不同的第三维度...
0
假设你的数组实际上是 [[[1,1,3],[3,4,2]],[[3,2,1],[3,4,2],[4,5,3]],[[4,3,2],[5,2,3]]]
,因为你提到你有一个三维数组,那么可以通过循环来计算平均值:
>>> l = [[[1,1,3],[3,4,2]],[[3,2,1],[3,4,2],[4,5,3]],[[4,3,2],[5,2,3]]]
>>> s = 0; n=0;
>>> for i in l: #First loop traverses through the first dimension
for j in i: #Traverses through the second dimension
s += sum(j)
n += len(j)
>>> print("Average is ", s/n)
Average is 2.85714
2
你可以使用掩码数组:
>>> from numpy import ma, nan
>>> a = ma.array([[1,1,3], [3,4,2], [nan,nan,nan]], mask=[[0,0,0],[0,0,0],[1,1,1]])
>>> b = ma.array([[3,2,1], [3,4,2], [4,5,3]])
>>> c = ma.array([[4,3,2], [5,2,3], [nan,nan,nan]], mask=[[0,0,0],[0,0,0],[1,1,1]])
>>> X = ma.array([a, b, c])
然后在任何一个方向上计算平均值时,会忽略被掩盖的值:
>>> X.mean(axis=0)
masked_array(data =
[[2.66666666667 2.0 2.0]
[3.66666666667 3.33333333333 2.33333333333]
[4.0 5.0 3.0]],
mask =
[[False False False]
[False False False]
[False False False]],
fill_value = 1e+20)
>>> X.mean(axis=1)
masked_array(data =
[[2.0 2.5 2.5]
[3.33333333333 3.66666666667 2.0]
[4.5 2.5 2.5]],
mask =
[[False False False]
[False False False]
[False False False]],
fill_value = 1e+20)
>>> X.mean(axis=2)
masked_array(data =
[[1.66666666667 3.0 --]
[2.0 3.0 4.0]
[3.0 3.33333333333 --]],
mask =
[[False False True]
[False False False]
[False False True]],
fill_value = 1e+20)