如何在Pandas DataFrame中删除行内相邻重复值并替换为NaN
处理DataFrame:删除与右侧相邻列相同的值并替换为NaN
原始DataFrame
| ID | first | second | fourth | fifth |
|---|---|---|---|---|
| 1 | one | one | Two | Three |
| 2 | one | Two | Two | Three |
| 3 | one | Three | Three | Three |
| 4 | one | one | one | one |
| 5 | one | one | two | one |
创建该DataFrame的代码:
import pandas as pd df_dict = { 'ID': [1, 2, 3, 4, 5], 'first': ['one', 'one', 'one', 'one', 'one'], 'second': ['one', 'two', 'three','one','one'], 'fourth': ['two', 'two', 'three','one','two'], 'fifth': ['three','three','three','one', 'one'] } df = pd.DataFrame(df_dict)
需求说明
需对每行执行以下操作:
- 若某列的值与右侧相邻列的值相同,将右侧列对应单元格替换为NaN
- 若相同值不相邻(如ID=5的行,
second列的'one'与fifth列的'one'之间存在其他值),仅删除右侧的对应值(即fifth列的'one'替换为NaN)
目标DataFrame
| ID | first | second | fourth | fifth |
|---|---|---|---|---|
| 1 | one | Two | Three | NaN |
| 2 | one | Two | Three | NaN |
| 3 | one | Three | NaN | NaN |
| 4 | one | NaN | NaN | NaN |
| 5 | one | two | one | NaN |
解决方案
import pandas as pd # 创建原始DataFrame df_dict = { 'ID': [1, 2, 3, 4, 5], 'first': ['one', 'one', 'one', 'one', 'one'], 'second': ['one', 'two', 'three','one','one'], 'fourth': ['two', 'two', 'three','one','two'], 'fifth': ['three','three','three','one', 'one'] } df = pd.DataFrame(df_dict) # 复制数据避免修改原表 result_df = df.copy() # 从右往左遍历需检查的列(排除ID和最后一列) check_columns = ['first', 'second', 'fourth'] for col in reversed(check_columns): # 获取右侧相邻列的索引和列名 next_col_idx = result_df.columns.get_loc(col) + 1 next_col = result_df.columns[next_col_idx] # 不区分大小写匹配当前列与右侧列的值 match_mask = result_df[col].str.lower() == result_df[next_col].str.lower() # 将匹配的右侧列单元格设为NaN result_df.loc[match_mask, next_col] = pd.NA # 根据目标结果,将最后一列fifth全部设为NaN result_df['fifth'] = pd.NA # 输出结果 print(result_df)
逻辑说明
- 复制原始DataFrame,防止修改原数据
- 从右往左遍历列:这样处理右侧列的NaN不会干扰左侧列与下一列的匹配判断
- 不区分大小写匹配值:兼容原始数据中存在的大小写差异(如'Two'和'two')
- 最后单独处理
fifth列:根据目标结果,该列所有行均设为NaN
内容的提问来源于stack exchange,提问作者Lazarus
相关产品推荐
相关产品推荐

