Numpy:对“不规则”的3D数组在一个维度上求平均值

3
假设我有一个N*M*X维度的数组"data",其中N和M是固定的,但X是每个条目data[n][m]都不同。
(编辑:为了澄清,我只是在用于读取数据的3D python列表上使用了np.array(),因此numpy数组的维度为N*M,其条目为可变长度列表)
现在,我想计算X维度上的平均值,以便留下一个N*M维度的数组。使用带有axis参数的np.average/mean无法实现,所以我现在的方法就是遍历N和M,并将手动计算的平均值附加到新列表中,但这种做法感觉不太“pythonic”。
avgData=[]
for n in data:
    temp=[]
    for m in n:
        temp.append(np.average(m))
    avgData.append(temp)

在这里我有没有漏掉什么显而易见的东西?我正在尝试更新我的Python技能,所以有趣/多样的回复是非常欢迎的!:)

谢谢!


3
数据是如何存储的?NumPy没有提供任何方法来处理不规则数组(就 NumPy 而言,X 始终是一个常量),所以您必须使用一些方式来填充这些值或者使用掩码数组等方法。 - mgilson
@mgilson编辑了这个问题。我只有一个3D Python列表,并对其调用np.array()。那么,我想它是一个由列表对象组成的2D数组? - Samuel Neugber
如果你不知道数据的布局,我们又怎么知道呢?你可以使用数组的.shape.dtype属性来检查。 - Hannes Ovrén
2个回答

4

What about using np.vectorize:

do_avg = np.vectorize(np.average)
data_2d = do_avg(data)

2
data = np.array([[1,2,3],[0,3,2,4],[0,2],[1]]).reshape(2,2)
avg=np.zeros(data.shape)
avg.flat=[np.average(x) for x in data.flat]
print avg
#array([[ 2.  ,  2.25],
#       [ 1.  ,  1.  ]])

这仍然遍历数据元素(这没有违反Python的规范)。但由于datashapeaxes没有特殊之处,因此我只使用了data.flat。使用numpy时,最好将值分配给现有数组的元素,而不是将其附加到Python list中。
有快速的数字方法可用于处理numpy数组,但大多数(如果不是全部)都使用简单的数字dtypes。在这里,数组元素是object(列表或数组),numpy必须借助通常的Python迭代和列表操作。
对于这个小例子,这个解决方案比Zwicker的vectorize稍微快一点。对于更大的data,两种解决方案需要的时间大致相同。

有趣!我考虑使用reshape,但不太清楚如何使用。我并不是说迭代元素不符合Python的风格,只是有一种比使用for循环更清晰的解决方案。 - Samuel Neugber
无论是在编译函数中、隐藏在 Python 函数中还是显式地,总会有一个循环。如果第三维不是崎岖不平的,那么它就是一个真正的三维数组,你可以简单地在第三维上求平均值。我应该深入研究 vectorize,看看它如何隐藏循环。 - hpaulj

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