获取每行倒数第二列不为空的列

Chr*_*her 2 python indexing pandas

我试图获取每行倒数第二个非空列,其中空值可以位于任何列中。诸如此类的解决方案不起作用,因为 null 可以在任何地方:Pandas 选择倒数第二列,该列也不是 nan

不是理想的解决方案: 我能够用以下代码解决它,但必须有一种更简洁的方法来编写它。对于任何反馈,我们都表示感谢。

data = [[1, 10, np.nan, np.nan], [2, 15, 13, np.nan], [9, 14, np.nan, np.nan]] 
df = pd.DataFrame(data, columns = ['a', 'b', 'c', 'd']) 

df['count_nulls'] = len(df.columns) - df.apply(lambda x: x.count(), axis=1)
df['count_nonnull'] = df.apply(lambda x: x.count(), axis=1)-1
df['new_index'] = np.where(df['count_nonnull']==1, 1, 
                             np.where(df['count_nonnull']==0,0, df['count_nonnull'] - 1))
df['value'] = df.values[np.arange(len(df)), df['new_index']-1]
df
Run Code Online (Sandbox Code Playgroud)

ank*_*_91 6

您可以检查notna并执行相反的操作cumsumaxis=1然后获取返回 2. 的第一列并使用以下方法获取其值df.lookup

u = df.notna().iloc[:,::-1].cumsum(axis=1)
df['value'] = df.lookup(df.index,u.eq(2).dot(u.columns+',').str.split(',').str[0])
Run Code Online (Sandbox Code Playgroud)
print(df)

   a   b     c   d  value
0  1  10   NaN NaN      1
1  2  15  13.0 NaN     15
2  9  14   NaN NaN      9
Run Code Online (Sandbox Code Playgroud)

以下评论已lookup被弃用,可以使用:

u = df.notna().iloc[:,::-1].cumsum(axis=1)
v = u.eq(2).dot(u.columns+',').str.split(',').str[0]
df['value'] = df.stack().loc[pd.MultiIndex.from_arrays((v.index,v))].to_numpy()
Run Code Online (Sandbox Code Playgroud)

其他部分可以不用apply来解决,或者嵌套np.where

df.assign(
    count_nulls=df.isna().sum(1),
    count_non_null=df.notna().sum(1),
    new_index=lambda df: np.select(
        [df.count_non_null == 1, df.count_non_null == 0], 
         [1, 0], 
         df.count_non_null - 1))
Run Code Online (Sandbox Code Playgroud)

  • 我猜这不是 pandas 版本 1.2;查找似乎已[已弃用](https://pandas.pydata.org/docs/whatsnew/v1.2.0.html#deprecations)。 (2认同)

Cyt*_*rak 5

您可以pandas.DataFrame.apply,pandas.DataFrame.dropna并访问倒数第二个元素。

>>> df.apply(lambda x:x.dropna().iloc[-2], axis=1)
0     1.0
1    15.0
2     9.0
Run Code Online (Sandbox Code Playgroud)