删除DataFrame中name或toy列含NaN/空值行时代码出错,请求排查
问题:删除
name或toy列含NaN的行时代码不符合预期 先看创建DataFrame的代码:
import pandas as pd import numpy as np df = pd.DataFrame(dict( age=[5, 6, np.nan], born=[pd.NaT, pd.Timestamp('1939-05-27'), pd.Timestamp('1940-04-25')], name=['Alfred', 'Batman', np.nan], toy=[np.nan, 'Batmobile', 'Joker']))
我的需求是删除name列或toy列包含NaN/空字符串的行,预期仅返回第2行,但尝试以下代码后结果不符合预期:
df[~df[['name', 'toy']].isna()]
请问这段代码哪里出错了?
分析与解决方法
你的代码核心问题是:~df[['name', 'toy']].isna()返回的是和原DataFrame同形状的布尔DataFrame,而非一维的行筛选条件。用它索引原DataFrame时,pandas会保留所有布尔值为True的单个元素,导致结果出现大量NaN,而非仅保留符合条件的整行。
要实现需求,需要先把多列的布尔判断合并成一维的行级筛选条件:
正确写法一(取反+any)
先判断每行是否存在name或toy为NaN的情况,再取反得到“两行都不为NaN”的行:
df[~df[['name', 'toy']].isna().any(axis=1)]
正确写法二(直接用all)
直接判断每行的name和toy都不为NaN:
df[df[['name', 'toy']].notna().all(axis=1)]
两种写法都会返回你预期的结果:
age born name toy 1 6.0 1939-05-27 Batman Batmobile
额外处理空字符串
如果需要同时过滤空字符串(比如''),可以先把空字符串转为NaN再执行筛选:
# 替换空字符串为NaN df[['name', 'toy']] = df[['name', 'toy']].replace('', np.nan) # 执行筛选 df[df[['name', 'toy']].notna().all(axis=1)]
内容的提问来源于stack exchange,提问作者Bogaso
相关产品推荐
相关产品推荐

