3

我有一个大的 ndarray X(大致为 (1e3, 1e3, 1e3)),我想在其中进行X包含和不包含第 0 轴的特定元素(对于第 1 轴和第 2 轴的每个元素)的操作。即有 (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掩码元素数组的情况下做到这一点?例如,是否可以为掩码构造一个稀疏矩阵?

4

1 回答 1

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
于 2017-06-07T15:06:42.483 回答