数据清洗
这是什么:数据清洗 = 把缺失、重复、类型不对的脏数据收拾干净的手艺。
为什么用:拿到真实数据,第一件事不是分析,是打扫。真实数据从来不干净,缺失、重复、类型不对的混在一起;不先清理,后面统计全白搭。
如何用:本章从一份带缺失值的"脏数据"起步,先摸清缺了多少,再学 isnull、dropna、fillna 三件套。
先造一份"脏数据"练手:
import pandas as pd
data = {
"姓名": ["小明", "小红", "小明", "小刚", None],
"年龄": ["18", "17", "18", "19", "20"],
"成绩": [92, None, 92, 95, 60],
}
df = pd.DataFrame(data)
print(df)
姓名 年龄 成绩
0 小明 18 92.0
1 小红 17 NaN
2 小明 18 92.0
3 小刚 19 95.0
4 None 20 60.0
NaN(Not a Number)就是 pandas 表示"这里缺数据"的写法;成绩列因为混进了 NaN,被自动变成了小数(92.0)。
缺失值:isnull / dropna / fillna
先摸清缺了多少:
print(df.isnull().sum()) # 每列缺了几个
姓名 1
年龄 0
成绩 1
dtype: int64
处理只有两条路——删或补:
df = df.dropna(subset=["姓名"]) # 姓名缺失的行:删(关键信息缺了没法救)
df["成绩"] = df["成绩"].fillna(df["成绩"].mean()) # 成绩缺失:用平均分补上
重复值:drop_duplicates
上面的小明出现了两次、数据完全一样,一行去重:
df = df.drop_duplicates() # 完全重复的行只留第一条
类型转换:astype
年龄这一列存的是字符串 "18"(带引号没法算平均数),转成数字:
df["年龄"] = df["年龄"].astype(int)
改列名:rename
df = df.rename(columns={"姓名": "学生"}) # 写法:旧名: 新名
打扫完看结果
print(df)
学生 年龄 成绩
0 小明 18 92.0
1 小红 17 93.0
3 小刚 19 95.0
对比开头:缺姓名的行没了,小红的 NaN 变成了平均分 93,小明只留一条,年龄成了数字。注意行号还是 0、1、3——pandas 保留原始行号,想重排可以加一句 df = df.reset_index(drop=True)。
本章解读
| 代码 | 作用 |
|---|---|
df.isnull().sum() |
每列统计缺失数量 |
df.dropna(subset=[...]) |
指定列有缺失就删整行 |
df.fillna(值) |
用给定值(如平均数)填补缺失 |
df.drop_duplicates() |
删除完全重复的行 |
df["列"].astype(int) |
整列转换类型 |
df.rename(columns={旧: 新}) |
改列名 |
记忆口诀
缺失先问 isnull,删用 dropna 补用 fillna,重复 dedup 类型 astype。
动手改
- 把
fillna里的平均分改成固定值0,看输出有什么不同 - 在数据里再手动复制一行重复数据,用
drop_duplicates()验证能去掉 - 试试不带参数的
df.dropna(),对比dropna(subset=["姓名"])——为什么它删的行更多?
下一章:统计与筛选,干净的数据该分析起来了 🐸