【问题标题】:Efficient memory usage with numpy masked arrays使用 numpy 掩码数组有效地使用内存
【发布时间】:2017-11-09 00:25:15
【问题描述】:

我有一个大的 ndarray X(大致为 (1e3, 1e3, 1e3)),我想在其中对 X 进行操作,包括但不包括第 0 轴的特定元素(对于第 1 和第第二轴)。即有 (1e3, 1e3) 元素,我想(有时)屏蔽或屏蔽。

最简单的做法是构造一个掩码数组,例如,

Z = np.zeros_like(X, dtype=bool)
# assume `inds` is some indexing array which will target
#    the particular (1e3 x 1e3) elements I'm interested in
Z[inds] = True
Y = np.ma.masked_array(X, mask=Z)

但这会使用额外的千兆字节内存来存储掩码数组。 有没有办法在不构造第二个 10^9 元素掩码数组的情况下做到这一点?例如,是否可以为掩码构造一个稀疏矩阵?

【问题讨论】:

  • 不; scipy.sparse 没有实现任何类型的屏蔽。而np,ma 不能使用sparse 矩阵。请记住,np.ma 在进行计算时,要么用无害的值(例如 0s、1s)填充掩码值,要么在没有掩码值的情况下将数组压缩为 1d。如果合适,您可以直接实施这些步骤。
  • @hpaulj 谢谢!这很有帮助。对于像np.ma.std 这样的函数,它如何处理掩码值?如果没有axis 参数,那么大概数组被展平了……但是如果有axis 参数怎么办——它既不能展平,也不能填充0,对吧?
  • 看来我们需要研究一下numpy/ma/core.pynp.ma.std 使用 ma std 方法,它使用 var,它使用 mean,而后者又使用 sumcountma.sum 使用 filled(0)。看起来count~mask 上使用sum - 即计算每个轴的未屏蔽值。
  • @hpaulj 哎呀......但是好吧,是的,这个想法是有道理的!

标签: python arrays numpy memory masked-array


【解决方案1】:

如果您只想获取“干净”的切片,而不是仅从某些“行”中获取一些元素,那么您可以使用数字索引而不是掩码。

例如:

arr = np.array([[[1,2,3,4], [5,6,7,8]], [[9,8,9,8], [7,6,7,6]]])
sub_idx = np.array([0,2])
sub_arr = arr[:, :, sub_idx]

这是arr的子集的副本,即最后一维中的第0个和第2个“切片”:

array([[[1, 3],
        [5, 7]],

       [[9, 9],
        [7, 7]]])

请注意,定义要使用哪些索引的数组只是一维的,这大大降低了它的内存需求。 (当然,在您的情况下,副本仍会占用大量内存。)

另请注意,这会为您提供一份副本,因此您对结果 (sub_arr) 所做的任何更改都不会显示在原始数组中。为此,您必须将数组复制回来:

sub_arr[:] = 0 # Manipulate the values
arr[sub_idx] = sub_arr

【讨论】:

  • 嗯,是的,我想我可以只存储这些子数组值,实际上将它们归零并根据需要替换它们......这不适用于所有情况(即有时你真的想要忽略元素而不是让它为零;例如计算标准偏差或其他东西)---但它可能适用于我的情况,感谢您的建议
  • 我并不是说您必须将它们设置为零 - 这只是我操作子数组的示例。
  • 当然,但是,我认为有些问题没有可用的填充值。
猜你喜欢
  • 1970-01-01
  • 2015-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-01
  • 2020-05-24
  • 2014-12-22
  • 1970-01-01
相关资源
最近更新 更多