刚开始我也觉得Pandas有啥难的,不就一个表格库嘛。结果第一个项目直接翻车,数据量才10万行,代码跑得跟PPT似的,还动不动报错。踩过的坑真不少。
先来看第一个坑:读取CSV文件时,默认参数能坑死人。
我记得是处理电商订单数据,文件里乱码、空行、多余分隔符全都有。默认的pd.read_csv()就像个没导航的司机,遇到奇怪数据就抛锚——我一开始搞错了,直接encoding='utf-8',结果第一列全是乱码,盯着屏幕看了半小时才发现是BOM头在作祟。
正确写法是这样的:
“python
import pandas as pd
df = pd.read_csv('orders.csv', encoding='utf-8-sig',
skipinitialspace=True,
na_values=['', 'N/A', 'NULL'],
dtype={'order_id': str, 'price': float})
`
这里encoding=’utf-8-sig’真是用血泪换来的。dtype参数更关键,你不指定的话,Pandas可能把order_id读成int,然后遇到字母"ABC123"直接报错——当时气得我差点很沮丧。
对了,这个设计真的反人类,但习惯了就好。另一个坑是数据清洗,官方文档写得跟谜语似的,什么dropna、fillna,全是大白话,但实际组合起来就懵了。
`python
import pandas as pd
import numpy as np
df['age'] = pd.to_numeric(df['age'], errors='coerce')
df = df[(df['age'] >= 0) & (df['age'] <= 120)]
df['email'] = df['email'].str.strip().str.lower()
df = df[df['email'].str.contains('@', na=False)]
`
这里errors=’coerce’是关键,它把非法字符串变成NaN,而不是让程序崩溃。我见过有人用循环逐行判断,跑了20万行花了3分钟,换成这个写法从3.2秒降到0.8秒——真的好用。还有个技巧:str.strip()和str.lower()连用,省去很多正则匹配的麻烦。
顺便说一下,处理缺失值时别死磕fillna。比如填充中位数而不是平均值,因为数据可能有异常值,中位数更鲁棒。代码很简单:
`python`
df['salary'].fillna(df['salary'].median(), inplace=True)
接下来是聚合操作。我刚开始写Python时,老是写循环来分组求和,结果被同事嘲笑。Pandas的groupby才是正解。
假设你有销售数据,想按月份和产品统计销量和收入:
`python
df['month'] = pd.to_datetime(df['date']).dt.month
monthly_stats = df.groupby(['month', 'product']).agg(
total_sales=('quantity', 'sum'),
total_revenue=('price', 'sum'),
avg_price=('price', 'mean')
).reset_index()
print(monthly_stats.head())
`
这里reset_index()我经常忘,导致结果变成多层索引,取数据时特别绕。还有,agg里可以用字典传多个函数,比分开写快很多。实测10万行数据,这个写法比循环快50倍以上。
当然,也有踩坑的地方。groupby默认不排序,如果你需要按月排序,记得加sort_values。还有个隐藏坑:groupby后如果数据全为NaN,结果会消失——最好先处理缺失值。上周五加班到凌晨,才发现是这个破问题。
你可以立刻用的三个点:
和encoding,省去后期类型转换和乱码烦恼。和str.strip,避免循环,速度提升10倍。+agg`,一行搞定,代码简洁且性能爆炸。记住,Pandas不是魔法,但掌握这些技巧后,你的数据处理效率会从”等得想睡觉”变成”瞬间完成”。下次再遇到CSV文件,先检查参数,再动手写代码。