gpt4 book ai didi

python - 来自大型掩码数组的 Numpy 平均值

转载 作者:太空宇宙 更新时间:2023-11-03 11:29:37 25 4
gpt4 key购买 nike

从大型掩码数组中获取平均值的合适方法是什么?通常我只会调用 .mean() 但对于非常大的数组,这对我来说失败了。

考虑创建一个包含一百万个元素的数组,所有元素的值为 500,例如:

a = np.ones(1000000, dtype=np.int16) * 500

然后创建一个随机掩码并将两者组合到一个新的掩码数组中:

mask = np.random.randint(0, 2, a.size)
b = np.ma.masked_array(a, mask=mask)

数组b继承了dtype,也是一个int16

b 中获取平均值可以用不同的方式完成,但都给出相同的结果。但是 non-ma 函数忽略了掩码,不应使用。

print(np.average(b), np.mean(b), np.ma.average(b), np.ma.mean(b))
(500.0, 500.0, 500.0, 500.0)

但如果我将原始数组大小从一百万增加到一千万,结果将变为:

print(np.average(b), np.mean(b), np.ma.average(b), np.ma.mean(b))
(500.0, -359.19365132075774, -359.19365132075774, -359.19365132075774)

现在只有 np.average 似乎 是正确的,但如前所述,忽略掩码并计算整个数组的平均值,这可以在更改一些例如,使用 b[b.mask] = 1000 屏蔽值。不过,我希望 np.mean 做同样的事情。

将掩码数组 b 转换为 float32 结果:

b = b.astype(np.float32)
print(np.average(b), np.mean(b), np.ma.average(b), np.ma.mean(b))
(511.18945, 510.37895680000003, 510.37895680000003, 510.37895680000003)

并将掩码数组 b 转换为 float64(根据文档默认情况下应该这样做)导致:

b = b.astype(np.float64)
print(np.average(b), np.mean(b), np.ma.average(b), np.ma.mean(b))
(500.0, 500.0, 500.0, 500.0)

因此转换为 float64 似乎可行,但我宁愿避免这种情况,因为它会增加内存占用量。

在测试其中的一些内容时,我还注意到,如果大小为一百万但错误的结果,则在非屏蔽数组 (a) 上调用 np.ma.average 会给出正确的结果当它是一千万时,而 np.ma.mean 对于两种尺寸都是正确的。

谁能解释一下这个例子中 dtype 和数组的 size 之间的关系?当这种情况发生时以及如何正确处理它对我来说有点神秘。

所有这些都是在 64 位 Win 7 机器上的 Numpy 1.8.1 中完成的。通过 conda 安装。

这是一个复制我所做的事情的笔记本:

http://nbviewer.ipython.org/gist/RutgerK/69b60da73f464900310a

最佳答案

this can be shown when changing some of the masked values with b[b.mask] = 1000 for example. I would expect np.mean to do the same though.

这是不正确的,b.mask 在有屏蔽值的地方为 True。当您为屏蔽值分配新值时,您正在取消屏蔽它们,因此有效地使数组中的所有值有效,您可以改用 b[np.invert(b.mask)]

所以这应该可行:

import numpy as np

a = np.ones(10000000, dtype=np.int64) * 500

mask = np.random.randint(0, 2, a.size)
b = np.ma.masked_array(a, mask=mask)

b[np.invert(b.mask)] = 1000
print(np.average(b), np.mean(b), np.ma.average(b), np.ma.mean(b))

除了 np.average 之外,这将为您提供正确的值。

除此之外,当您得到负值/不正确的值时,这是因为您得到了整数溢出。使用 dtype=np.int64 应该可以解决它,

编辑:另一种选择是将 Python 整数与 dtype=object 一起使用,而不是固定宽度的整数,但这会更慢,此更改使 np .average 崩溃,但其余方法正常工作。

编辑 2: 正如评论中所说,在这种情况下没有必要增加数组元素的大小,我们可以调用 np.mean(b, dtype =np.float64) 以便 np.mean 使用更大的累加器来避免溢出。

关于python - 来自大型掩码数组的 Numpy 平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24363107/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com