跳转至

数据科学 2 · Pandas

NumPy 处理"纯数值数组"。Pandas 处理"表格数据"——带行列标签、混合类型的数据,像内存里的 SQL 表或 Excel。对 Java 程序员,Pandas 的最大价值是:用几行代码完成 SQL/join/groupby/清洗,无需数据库、无需手写循环

uv add pandas            # 或 pip install pandas

Pandas 同样是 Python 统治领域,Java 无等价生态。近邻对照用 SQL(你最熟的表操作心智)。


2.1 DataFrame:内存里的表

  • SQL 表

    CREATE TABLE sales (
      date DATE, region TEXT,
      product TEXT, amount INT
    );
    
  • Pandas DataFrame

    import pandas as pd
    df = pd.read_csv("sales.csv")
    

DataFrame = 二维表(行索引 + 列名),每列可有不同类型。Series 是单列。

df.shape        # (行数, 列数)
df.columns      # 列名列表
df.head(5)      # 前 5 行
df.info()       # 类型、非空数
df.describe()   # 数值列统计(均值/分位数)

2.2 选数据:[] / loc / iloc

df["amount"]              # 选一列 → Series
df[["date", "amount"]]    # 选多列 → DataFrame

df.loc[0]                 # 按标签取行
df.loc[:, ["date", "amount"]]   # 标签切片
df.iloc[0:5]              # 按位置取前 5 行
  • loc:按标签(行名/列名)取。
  • iloc:按整数位置取(像数组下标)。

2.3 筛选:对照 SQL WHERE

# SQL: SELECT * FROM sales WHERE amount > 100
df[df["amount"] > 100]

# 多条件(& | ~,注意括号!)
df[(df["amount"] > 100) & (df["region"] == "north")]

# SQL: SELECT region, amount WHERE ...
df.loc[df["amount"] > 100, ["region", "amount"]]

⚠️ Java 程序员的陷阱

Pandas 布尔条件用 & |(位运算符),不是 and or——且每个条件必须括号包裹(运算符优先级)。df[a > 0 & b] 会报错,要 df[(a > 0) & (b)]


2.4 新增/变换列

df["tax"] = df["amount"] * 0.1          # 向量化新增列
df["amount_with_tax"] = df["amount"] + df["tax"]
df["level"] = df["amount"].apply(lambda x: "high" if x > 100 else "low")  # 逐行变换

apply 对每行/每元素应用函数(非向量化场景,但比手写循环地道)。优先用向量化(df["amount"] * 0.1)。


2.5 分组聚合:对照 SQL GROUP BY

这是 Pandas 最强大的能力之一:

# SQL: SELECT region, SUM(amount) FROM sales GROUP BY region
df.groupby("region")["amount"].sum()

# 多聚合
df.groupby("region")["amount"].agg(["sum", "mean", "count"])

# 按多列分组
df.groupby(["region", "product"])["amount"].sum()
  • Java(手写或 Stream)

    // Stream collect groupingBy + summingInt
    map = sales.stream().collect(
      groupingBy(Sale::region,
        summingInt(Sale::amount)));
    
  • Pandas(一行)

    df.groupby("region")["amount"].sum()
    

对照之下,Pandas 把 SQL 的 GROUP BY/聚合/join 都内化成了简洁的 DataFrame 操作。


2.6 合并:对照 SQL JOIN

# 两个表按共同列连接
pd.merge(orders, customers, on="customer_id")          # INNER JOIN
pd.merge(orders, customers, on="customer_id", how="left")  # LEFT JOIN

# 纵向拼接(UNION ALL)
pd.concat([df_jan, df_feb])

2.7 缺失值处理

真实数据常有缺失(NaN):

df.isnull().sum()                # 每列缺失数
df.dropna()                      # 删缺失行
df["amount"].fillna(0)           # 填充
df["amount"].fillna(df["amount"].mean())   # 填均值

2.8 读写:CSV / Excel / SQL

df = pd.read_csv("sales.csv")                # 读 CSV
df = pd.read_excel("sales.xlsx")             # 读 Excel(需 openpyxl)
df.to_csv("out.csv", index=False)            # 写 CSV(不写行索引)

# 从 SQL 读
df = pd.read_sql("SELECT * FROM sales", engine)

2.9 与 SQL/Java 对照小结

操作 SQL Pandas
选列 SELECT a, b df[["a","b"]]
筛选 WHERE x > 0 df[df.x > 0]
分组聚合 GROUP BY ... SUM(...) df.groupby(...)sum()
连接 JOIN ON pd.merge(on=...)
排序 ORDER BY x df.sort_values("x")
去重 DISTINCT df.drop_duplicates()

核心认知:把 DataFrame 当"内存里的 SQL 表",Pandas 的几乎所有操作都有 SQL 对照。你会发现自己写的数据处理代码从几十行 Java 缩到几行 Pandas。


本章练习

练习 2.1

读一份 CSV,按某分类列分组,计算另一数值列的均值和总和。

参考答案
import pandas as pd
df = pd.read_csv("sales.csv")
df.groupby("region")["amount"].agg(["mean", "sum"])
练习 2.2

解释为什么 df[df.amount > 0 & df.region == "north"] 会报错,并修正。

参考答案

布尔 Series 之间必须用 &/|(不能用 and/or),且每个条件要括号包裹& 优先级低于比较运算符,不括号会错误结合)。修正:df[(df["amount"] > 0) & (df["region"] == "north")]

练习 2.3

把两份月度销售 CSV(jan.csvfeb.csv)纵向合并成一份,按金额降序排列。

参考答案
df = pd.concat([pd.read_csv("jan.csv"), pd.read_csv("feb.csv")])
df = df.sort_values("amount", ascending=False)

上一章:数据科学 1 · NumPy← 回首页 | 下一章:数据科学 3 · 可视化