Python中DataFrame列去连续重复值时跳过NA的代码问题排查
问题:移除DataFrame连续重复值时elif条件未生效的原因
需求背景
需要移除DataFrame列中的连续重复数字,处理阶段如下:
- 原DataFrame:
| A | B | C |
|---|---|---|
| 12 | 14 | 16 |
| 15 | 16 | 17 |
| 15 | 16 | 18 |
| 15 | 18 | 20 |
- 首次处理后结果:
| A | B | C |
|---|---|---|
| 12 | 14 | 16 |
| 15 | 16 | 17 |
| na | na | 18 |
| 15 | 18 | 20 |
- 期望最终结果:
| A | B | C |
|---|---|---|
| 12 | 14 | 16 |
| 15 | 16 | 17 |
| na | na | 18 |
| na | 18 | 20 |
编写如下代码后,发现elif条件未生效,无法移除最后一行A列的15:
import math for i in df1.index: f_id = df1["f_secid"][i] b_id = df1["b_secid"][i] for j in range(len(f_data)-1): if j ==0: continue elif (f_data[f_id][j] == math.nan) & (f_data["f_id"][j+1] == f_data["f_id"][j-1]): f_data[f_id][j+1] = math.nan
核心问题分析
你的代码中elif条件完全不生效,主要是三个关键错误导致:
1. NaN的比较方式错误
Python中,math.nan和任何值(包括自身)用==比较的结果都是False,所以f_data[f_id][j] == math.nan这个判断永远为假,直接让整个elif条件不成立。正确判断NaN应该用pd.isna()(pandas数据)或math.isnan()(数值类型)。
2. 列名引用错误
代码里写的f_data["f_id"][j+1]和f_data["f_id"][j-1]是引用名为"f_id"的列,但根据上下文,你实际要操作的是变量f_id对应的列,应该写成f_data[f_id][j+1]和f_data[f_id][j-1]。这个错误会让你拿错列的数据做比较,逻辑完全偏离预期。
3. 循环范围与逻辑覆盖不全
你的循环是range(len(f_data)-1),意味着只会遍历到倒数第二行,根本不会处理最后一行的判断。而且你的条件是“当前行是NaN且下一行等于上一行”,但最后一行A列的15,它的上一行是NaN,需要判断的是“当前行等于上上行”,你的逻辑没覆盖这种场景。
修正方案
用pandas内置函数可以更高效实现需求,示例代码如下:
import pandas as pd # 构造示例DataFrame df = pd.DataFrame({ 'A': [12,15,15,15], 'B': [14,16,16,18], 'C': [16,17,18,20] }) # 第一步:移除直接连续重复的值(和上一行相同则设为NaN) df = df.mask(df.diff() == 0) # 第二步:处理“上一行是NaN,当前行等于上上行”的情况 for col in df.columns: for j in range(2, len(df)): if pd.isna(df[col].iloc[j-1]) and df[col].iloc[j] == df[col].iloc[j-2]: df[col].iloc[j] = pd.NA
执行后就能得到你期望的最终结果。
内容的提问来源于stack exchange,提问作者Dinesh Kumar
相关产品推荐
相关产品推荐

