第一步:摸底

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)

下一篇讲可视化。