"Unsparsing" 具有给定掩码的 numpy 数组

"Unsparsing" numpy Arrays with Given Masks

假设有两个数组,vals 包含值,masks 包含布尔值,指示是否使用 valsnan 中的值。目标是构建一个长度与 masks 相同的数组 ret,其中包含 vals 对应位置的值到 masks 中的 True 个条目。

例如,假设

vals = np.array([1, 2])
masks = [True, False, False, True]

那么ret,return的值,应该是

array([1, None, None, 2], dtype=object)

使用循环显然很容易做到这一点:

import numpy as np

def unsparse(vals, masks):
    vals_i = 0
    ret = []
    for m in masks:
        if m:
            ret.append(vals[vals_i])
            vals_i += 1
        else:
            ret.append(None)
    return np.array(ret)

>> unsparse(np.array([1, 2]), [True, False, False, True])
array([1, None, None, 2], dtype=object)

有没有一种不用循环而且更简洁的方法?

你可以这样做 -

out = np.empty(masks.shape,dtype=object)
out[masks] = vals[:masks.sum()] 

请注意,:masks.sum()vals 中选择前 N 个元素,其中 N 是掩码中 TRUE 个元素的数量。

如果保证 TRUE 元素的数量与 vals 中的元素数量相同,那么你可以简单地做 -

out[masks] = vals 

样本运行-

In [34]: vals = np.array([1, 2, 6, 8, 9])
    ...: masks = np.array([True, False, False, True, False, True])
    ...: 

In [35]: out = np.empty(masks.shape,dtype=object)
    ...: out[masks] = vals[:masks.sum()]
    ...: 

In [36]: out
Out[36]: array([1, None, None, 2, None, 6], dtype=object)