numpy 数组中第一个 nan 序列的结尾

Con*_*ist 6 python arrays numpy

我有一个二维 numpy 数组,其中某些行可能有 nan。我想根据以下规定选择这些数组的行中是否出现 nan:

  • 如果一行不以 nan 开头,则该数组的结果将为 -1。
  • 如果一行以 nan 开头,则结果将是从该行开头开始的连续不间断的 nan 序列中最后一个 nan 的索引。

做到这一点的最佳方法是什么?在我的实际工作中,我将处理具有数百万行的 numpy 数组。

作为一个例子,让我们考虑下面的数组:

import numpy as np

arr = np.array([[1,11,np.nan,111,1111],
               [np.nan, np.nan, np.nan, 2, 22],
               [np.nan, np.nan, 3, 33, np.nan],
               [4, np.nan, np.nan, 44, 444],
               [np.nan, 5, 55, np.nan, 555],
               [np.nan, np.nan, np.nan, np.nan, np.nan]])
Run Code Online (Sandbox Code Playgroud)

这里的预期结果将是result = [-1, 2, 1, -1, 0, 4]

下面是我尝试过的成功代码。但是,我想要一个更优化的解决方案。

result = []

for i in range(arr.shape[0]):
    if np.isnan(arr[i])[0] == False:
        result += [-1]
    elif np.all(np.isnan(arr[i])):
        result += [arr.shape[1]-1]
    else:
        result += [np.where(np.isnan(arr[i]) == False)[0][0] - 1]
Run Code Online (Sandbox Code Playgroud)

moz*_*way 4

您可以添加一列非 nan with hstack,检查哪些值是 nan with isnan,并获取第一个非 nan with 的位置argmin

out = np.isnan(np.hstack([arr, np.ones((arr.shape[0], 1))])).argmin(axis=1)-1
Run Code Online (Sandbox Code Playgroud)

或者不使用串联并使用来修复值为 nan 的where情况:all

tmp = np.isnan(arr)

out = np.where(tmp.all(axis=1), arr.shape[1], tmp.argmin(axis=1))-1
Run Code Online (Sandbox Code Playgroud)

输出:

out = array([-1,  2,  1, -1,  0,  4])
Run Code Online (Sandbox Code Playgroud)