数据科学 2 · Pandas¶
NumPy 处理"纯数值数组"。Pandas 处理"表格数据"——带行列标签、混合类型的数据,像内存里的 SQL 表或 Excel。对 Java 程序员,Pandas 的最大价值是:用几行代码完成 SQL/join/groupby/清洗,无需数据库、无需手写循环。
Pandas 同样是 Python 统治领域,Java 无等价生态。近邻对照用 SQL(你最熟的表操作心智)。
2.1 DataFrame:内存里的表¶
-
SQL 表
-
Pandas DataFrame
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)
-
Pandas(一行)
对照之下,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,按某分类列分组,计算另一数值列的均值和总和。
练习 2.2
解释为什么 df[df.amount > 0 & df.region == "north"] 会报错,并修正。
参考答案
布尔 Series 之间必须用 &/|(不能用 and/or),且每个条件要括号包裹(& 优先级低于比较运算符,不括号会错误结合)。修正:df[(df["amount"] > 0) & (df["region"] == "north")]。
练习 2.3
把两份月度销售 CSV(jan.csv、feb.csv)纵向合并成一份,按金额降序排列。
上一章:数据科学 1 · NumPy | ← 回首页 | 下一章:数据科学 3 · 可视化