Pandas df.apply结果异常:不符合条件的行被误加入列表
df.apply筛选非NaN行异常的原因分析
问题重现
你编写了以下代码,意图通过df.apply将第3列之后非NaN值数量大于1的行加入列表df111:
import numpy as np df111=[] def getNoNaN(row_in,dflist): if np.sum(~pd.isna(row_in[3:])) > 1: dflist.append(row_in) dftest.apply(axis=1,func=getNoNaN,dflist=df111) df111[0]
但实际结果中,df111的第一行第3列之后非NaN值数量仅为1,却被错误加入列表。
核心原因分析
1. 非标准空值导致统计错误
最可能的原因是数据中存在pd.isna无法识别的空值类型:
- 若单元格是空字符串
""、字符串类型的"NaN"、或者None(在object类型列中),pd.isna()会返回False,此时~pd.isna()会将这些值判定为非NaN,导致np.sum()统计出的数量比实际预期多。 - 例如某行第3列之后有1个有效数值+1个空字符串,
np.sum(~pd.isna(row_in[3:]))会计算为2,满足>1的条件,从而被错误加入列表。
2. 切片范围与预期不符
如果你的"第3列"是1-based索引(即Excel式的列编号),那么代码中row_in[3:]对应的是0-based的第4列及以后,相当于跳过了真正的第3列。此时统计的列范围错误,可能把原本不属于统计范围的列计入,导致数量统计超标。
验证方法
可以在函数中加入调试代码,直接查看每一行的统计结果和对应内容:
def getNoNaN(row_in,dflist): non_nan_count = np.sum(~pd.isna(row_in[3:])) # 打印行索引、统计数量、对应列内容 print(f"行{row_in.name}:非NaN数量={non_nan_count},内容={row_in[3:].tolist()}") if non_nan_count > 1: dflist.append(row_in)
同时可以检查数据中的空值类型:
# 统计第3列之后的空字符串数量 print(dftest.iloc[:,3:].eq("").sum()) # 查看第3列之后的单元格类型分布 print(dftest.iloc[:,3:].applymap(type).value_counts())
内容的提问来源于stack exchange,提问作者Jiangnan Crayon Shin-chan
相关产品推荐
相关产品推荐

