第一步:摸底
df.info()
df.describe()
df.isnull().sum() # 每列有多少缺失
df.duplicated().sum() # 有多少重复行
处理缺失值
df.dropna() # 删除任何含 NaN 的行
df.dropna(subset=["age"]) # 只看 age 列
df.fillna(0) # 全部填 0
df["age"].fillna(df["age"].mean(), inplace=True) # 填均值
df["city"].fillna("未知", inplace=True)
删除重复
df.drop_duplicates() # 全字段去重
df.drop_duplicates(subset=["email"]) # 按 email 去重
df.drop_duplicates(subset=["email"], keep="last") # 保留最后一条
类型转换
df["age"] = df["age"].astype(int)
df["price"] = df["price"].astype(float)
df["date"] = pd.to_datetime(df["date"]) # 字符串 → 日期
df["category"] = df["category"].astype("category") # 分类类型,省内存
apply:对每行/每列应用函数
# 对一列
df["name_upper"] = df["name"].apply(str.upper)
# 多列计算
df["bmi"] = df.apply(lambda r: r["weight"] / r["height"]**2, axis=1)
groupby:分组聚合
# 简单:按一列分组求另一列均值
df.groupby("city")["age"].mean()
# 多个聚合
df.groupby("city").agg({
"age": "mean",
"score": ["min", "max", "sum"],
})
# 自定义聚合
df.groupby("city")["score"].apply(lambda s: s.max() - s.min())
pivot_table:透视
df.pivot_table(
values="sales",
index="region",
columns="month",
aggfunc="sum",
fill_value=0,
)
变成"region × month"矩阵——Excel 数据透视表的 Python 版。
merge:表连接(类似 SQL JOIN)
users = pd.DataFrame({"id": [1, 2, 3], "name": ["A", "B", "C"]})
orders = pd.DataFrame({"user_id": [1, 1, 2], "amount": [100, 50, 30]})
merged = users.merge(orders, left_on="id", right_on="user_id", how="left")
how: "inner" / "left" / "right" / "outer"——和 SQL 一样。
concat:拼接(行 / 列)
pd.concat([df1, df2]) # 上下拼(增加行)
pd.concat([df1, df2], axis=1) # 左右拼(增加列)
字符串处理:.str
df["name"].str.upper()
df["email"].str.contains("@gmail")
df["phone"].str.replace("-", "")
df["address"].str.split(",", expand=True) # 拆成多列
实战:清洗一个真实 CSV
df = pd.read_csv("messy.csv")
# 1. 列名规范化
df.columns = df.columns.str.strip().str.lower().str.replace(" ", "_")
# 2. 类型修正
df["age"] = pd.to_numeric(df["age"], errors="coerce") # 不能转就变 NaN
df["date"] = pd.to_datetime(df["date"], errors="coerce")
# 3. 处理缺失
df = df.dropna(subset=["id"]) # id 缺失直接丢
df["age"] = df["age"].fillna(df["age"].median())
# 4. 去重
df = df.drop_duplicates(subset=["id"])
# 5. 异常值
df = df[(df["age"] >= 0) & (df["age"] <= 120)]
# 6. 输出
df.to_csv("clean.csv", index=False)
下一篇讲可视化。