Pandas中逻辑相似的代码为何生成不同DataFrame?
代码逻辑差异分析
三个代码的核心差异体现在NaN值处理和字符串匹配规则上,具体拆解如下:
代码1:精确筛选,排除NaN
df = df[(df['column_name'] == 'NORMAL')]
- 逻辑:只保留
column_name值完全等于'NORMAL'的行 - 细节:
- 字符串必须是精确匹配,像'NORMAL_XYZ'、'ABNORMAL'这类包含但不等于的行都会被过滤
- NaN值与任何字符串比较都返回
False,所以所有NaN行都会被排除
代码2:删除不等于的行,但保留NaN
(注:你写的代码有语法错误,少了一个闭合括号,修正后应为)
df = df.drop(df[(df['column_name'] != 'NORMAL')].index)
- 逻辑:删除
column_name值不等于'NORMAL'的行 - 细节:
- 同样是精确比较,但
!=对NaN值返回NaN,pandas布尔索引会忽略NaN对应的行,所以这些NaN行不会被删除,会留在结果里 - 仅删除明确不等于'NORMAL'的非NaN行
- 同样是精确比较,但
代码3:删除不包含子串的行,保留NaN和包含匹配的行
df = df.drop(df[(~df['column_name'].str.contains('NORMAL'))].index)
- 逻辑:删除
column_name值不包含'NORMAL'子串的行 - 细节:
- 模糊匹配,只要字符串里有'NORMAL'就会保留,比如'MY_NORMAL'、'NORMALTEST'这类行都会留下
str.contains对NaN值返回NaN,取反后还是NaN,同样不会被纳入删除范围,所以NaN行被保留
结果差异原因
你看到代码2和3结果一致,大概率是因为你的数据里没有包含'NORMAL'但不等于的行,此时“不等于'NORMAL'”和“不包含'NORMAL'”的范围重合;但两者都会保留NaN行,而代码1会排除NaN行,所以和代码1结果不同。
让代码2/3匹配代码1结果的修正方法
- 代码2修正(同时删除不等于和NaN的行):
df = df.drop(df[(df['column_name'] != 'NORMAL') | df['column_name'].isna()].index) - 代码3修正(精确匹配+删除NaN行):
# 方法1:直接复用代码2的修正逻辑 df = df.drop(df[(df['column_name'] != 'NORMAL') | df['column_name'].isna()].index) # 方法2:用正则精确匹配子串 df = df.drop(df[(~df['column_name'].str.contains('^NORMAL$', regex=True)) | df['column_name'].isna()].index)
内容的提问来源于stack exchange,提问作者Daniel Bento
相关产品推荐
相关产品推荐

