Numpy数组:如何逐行检查第一个X值是否有效?

问题描述 投票:0回答:2

问题描述

考虑以下两个示例数组:

arr = np.array([
    [5.0, 2.0, 1.0, np.nan, np.nan],
    [9.0, np.nan, np.nan, np.nan, 2.0],
    [4.0, 7.0, 4.0, np.nan, np.nan],
    [8.0, np.nan, np.nan, np.nan, np.nan],
    [np.nan, np.nan, np.nan, np.nan, np.nan],
    [np.nan, np.nan, np.nan, np.nan, 6.0]
])

amounts = np.array([
    3,
    1,
    2,
    3,
    0,
    5
])

对于数组arr中的每一行,我想检查行中的前X个条目是否不是NaN,但所有其他条目都是NaN。对于每一行,该量X是不同的,并且由数组amounts给出。

所以我的预期结果将是以下布尔数组:

array([ True, False, False, False,  True, False])

到目前为止尝试过

我设法提出以下工作代码:

result = []
for (row, amount) in zip(arr, amounts):
    if (~np.isnan(row)[:amount]).all() and np.isnan(row)[amount:].all():
        result.append(True)
    else:
        result.append(False)

result = np.array(result)
print(result)

虽然这段代码产生了理想的结果,但我觉得它仍然效率低下。我怀疑没有任何for循环的方法是可能的,但我还没有找到它。

有人能帮助找到这个问题的完全矢量化解决方案吗?

python numpy
2个回答
4
投票
a = np.array([[5.0, 2.0, 1.0, np.nan, np.nan],
              [9.0, np.nan, np.nan, np.nan, 2.0],
              [4.0, 7.0, 4.0, np.nan, np.nan],
              [8.0, np.nan, np.nan, np.nan, np.nan],
              [np.nan, np.nan, np.nan, np.nan, np.nan],
              [np.nan, np.nan, np.nan, np.nan, 6.0]])

b = np.array([3,1,2,3,0,5])

c = np.logical_not(np.isnan(a))
firstn = b == c.argmin(axis=1)
no_extras = b == c.sum(axis=1)
result = np.logical_and(firstn,no_extras)

创建一个非NaN值的布尔数组。

确保第一个n值符合标准;使用numpy.argmin()找到第一个NaN - 将其与counts数组进行比较。

确保NaN启动后没有任何非NaN值;将所有Trues在布尔数组中逐行求和,将其与counts数组进行比较。

and这两个结果。


2
投票

你可以尝试这样的smth:

# Values are column numbers
grid = np.tile(np.arange(arr.shape[1]), (arr.shape[0], 1))

# Mask
mask = grid < amounts.reshape((-1, 1))

# Comparison
np.all(~np.isnan(arr) == mask, axis=1)
© www.soinside.com 2019 - 2024. All rights reserved.