数据读取、类型推断、groupby聚合和链式赋值是pandas四大易错点:需显式指定encoding与sep;object列常因混入none/嵌套结构导致;groupby注意dropna与min_count;禁用inplace,统一用赋值+copy。

发现数据不一致时,先确认 pandas.read_csv 的编码和分隔符
很多“数据读出来就错”的问题,其实卡在第一行——read_csv 默认用 utf-8,但 Windows 记事本保存的 CSV 往往是 gbk 或 gb2312;默认分隔符是逗号,可实际文件可能是制表符、分号,甚至中文顿号。不显式指定,pandas 就会硬拆,字段错位、数值变字符串、空值变 NaN 都是常态。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 用文本编辑器(如 VS Code)打开原始文件,右下角看真实编码和换行符类型
- 优先试
encoding='gbk'和sep='\t',再根据报错信息调整 - 加
verbose=True和warn_bad_lines=True(旧版)或on_bad_lines='warn'(2.0+),让 pandas 吐出哪几行解析异常 - 别依赖
encoding='utf-8-sig'一招鲜——它只解决 BOM 头,对乱码无感
df.dtypes 显示 object 却不是字符串?检查是否混入了 None、np.nan 或嵌套结构
当某列本该是数字或日期,却显示 object 类型,大概率是这列里藏了非标数据:空字符串、None、字典、列表,甚至整行是 NaN。pandas 为保安全,自动降级为 object,后续 .str 或 .dt 操作全失效。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 用
df['col'].apply(type).value_counts()直接看每行是什么类型 -
df['col'].isna().sum()和df['col'].apply(lambda x: isinstance(x, (list, dict))).sum()分别统计缺失和嵌套数量 - 别急着
astype(str)——这会让np.nan变成字符串'nan',后续清洗更难 - 真要转字符串,用
df['col'].astype('string')(pandas 1.0+),它原生支持pd.NA,不会污染数据
用 df.groupby().agg() 出结果为空或聚合失效?重点查 dropna 和 min_count
groupby 聚合后某组没结果,常见原因不是数据少,而是默认 dropna=True 把含 NaN 的组整个踢掉了;或者用 sum()、mean() 时,整组全是 NaN,结果返回 NaN 而非 0,看着像“丢了数据”。
Python v2.4版chm格式的中文手册,内容丰富全面,不但是一本手册,你完全可以把她作为一本Python的入门教程,教你如何使用Python解释器、流程控制、数据结构、模板、输入和输出、错误和异常、类和标准库详解等方面的知识技巧。同时后附的手册可以方便你的查询。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 加参数
dropna=False,确保空值也参与分组(尤其 categorical 列) - 数值聚合加
min_count=1,比如.sum(min_count=1),避免全空组返回NaN - 聚合函数传字典时,注意键是列名、值是函数名或列表:
{'amount': ['sum', 'mean']},别写成{'amount': sum}——后者会报TypeError: cannot convert the series to <class></class> - 如果 groupby 键本身含
NaN,pandas 默认把它归为单独一组,但显示为NaN行——用df.groupby(..., dropna=False).size()才能看见它
复盘脚本跑一次就过,换数据就崩?必须隔离 inplace=True 和链式赋值
最隐蔽的坑是:你改着改着,发现某列突然变 None,或者 SettingWithCopyWarning 冒出来又消失,最后查半天发现是 df.drop(columns=['x'], inplace=True) 后,又写了 df['y'] = df['z'] * 2——而 df 其实是另一个 DataFrame 的视图,修改直接失效或引发未定义行为。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 彻底禁用
inplace=True:统一用df = df.drop(...)、df = df.fillna(...) - 链式操作务必用括号包住,比如
df = df.query('a > 0').assign(b=lambda x: x.a * 2),别拆成两行赋值 - 对副本操作前,显式调用
.copy(),尤其是从大表切片后:subset = df[df.flag == 1].copy() - 用
df._mgr.blocks(不推荐但有效)或df.values.base is None粗略判断是否视图——不过更稳的方式是:只要不确定,就 copy
数据复盘不是比谁写得快,是比谁漏得少。类型推断、空值传播、视图/副本边界——这些地方不出错,后面所有计算才真正可信。









