如何删除DataFrame中每行的最后一个非NaN值?
问题描述
现有如下DataFrame:
| a1 | a2 | a3 | Last_Not_NaN_Value |
|---|---|---|---|
| 1 | NaN | NaN | 1 |
| 0 | 0 | NaN | 0 |
| NaN | 5 | NaN | 5 |
已通过以下代码获取到每行的最后一个非NaN值:
data.ffill(axis=1).iloc[:, -1]
现在需要将原DataFrame中对应的这些最后一个非NaN值替换为NaN(即移除这些值)。
解决方案
可以通过定位每行最后一个非NaN值的位置,再将对应位置设为NaN,以下是两种可行的实现方式:
方法一:布尔掩码批量替换
import pandas as pd import numpy as np # 示例数据(已有目标data可跳过此步) data = pd.DataFrame({ 'a1': [1, 0, np.nan], 'a2': [np.nan, 0, 5], 'a3': [np.nan, np.nan, np.nan] }) # 获取每行最后一个非NaN值的列名 last_valid_cols = data.notna().cumsum(axis=1).idxmax(axis=1) # 生成标记需要替换位置的布尔掩码 mask = pd.DataFrame([data.columns == col for col in last_valid_cols], index=data.index, columns=data.columns) # 将标记位置的值设为NaN data[mask] = np.nan
方法二:遍历行定位替换
这种方式逻辑更直观,适合快速理解:
import pandas as pd import numpy as np data = pd.DataFrame({ 'a1': [1, 0, np.nan], 'a2': [np.nan, 0, 5], 'a3': [np.nan, np.nan, np.nan] }) # 获取每行最后一个非NaN值的列索引 last_valid_pos = data.notna().apply(lambda row: row.last_valid_index(), axis=1) # 遍历每行,将对应位置设为NaN for idx, col in last_valid_pos.items(): if col is not None: # 避免整行都是NaN的情况报错 data.loc[idx, col] = np.nan
执行后原DataFrame会更新为:
| a1 | a2 | a3 |
|---|---|---|
| NaN | NaN | NaN |
| 0 | NaN | NaN |
| NaN | NaN | NaN |
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

