获取排序的 numpy 矩阵或 pandas 数据帧的最后一个非 nan 索引

Pau*_*aul 5 python numpy pandas

给定一个 numpy 数组(或 pandas 数据框),如下所示:

import numpy as np

a = np.array([
[1,      1,      1,    0.5, np.nan, np.nan, np.nan],
[1,      1,      1, np.nan, np.nan, np.nan, np.nan],
[1,      1,      1,    0.5,   0.25,  0.125,  0.075],
[1,      1,      1,   0.25, np.nan, np.nan, np.nan],
[1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
[1,      1,    0.5,    0.5, np.nan, np.nan, np.nan]
])
Run Code Online (Sandbox Code Playgroud)

我希望最有效地检索每行中的最后一个非 nan 值,因此在这种情况下,我将寻找一个返回如下内容的函数:

np.array([3,
          2,
          6,
          3,
          0,
          3])
Run Code Online (Sandbox Code Playgroud)

我可以尝试np.argmin(a, axis=1) - 1,但这至少有两个不良属性 - 对于不以nan(dealbreaker) 结尾的行,它会失败,并且它不会“惰性求值”,并且一旦达到给定行中的最后一个非 nan 值就会停止(这并不像“它必须是正确的”条件那么重要)。

我想有一种方法可以用 来做到这一点np.where,但除了评估每行的所有元素之外,我看不到一种明显优雅的方法来重新排列输出以获取每行中的最后一个索引:

>>> np.where(np.isnan(a))
(array([0, 0, 0, 1, 1, 1, 1, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5]),
 array([4, 5, 6, 3, 4, 5, 6, 4, 5, 6, 1, 2, 3, 4, 5, 6, 4, 5, 6]))
Run Code Online (Sandbox Code Playgroud)

Dou*_*ugR 7

该解决方案不需要对数组进行排序。它只返回沿轴 1 的最后一个非 nan 项。

(~np.isnan(a)).cumsum(1).argmax(1)
Run Code Online (Sandbox Code Playgroud)


ayh*_*han 4

pandas.Series 有一个last_valid_index方法:

pd.DataFrame(a.T).apply(pd.Series.last_valid_index)
Out: 
0    3
1    2
2    6
3    3
4    0
5    3
dtype: int64
Run Code Online (Sandbox Code Playgroud)