在真实的数据科学与 AI 工程中,数据很少以干净的 NumPy 纯数字矩阵形式直接呈现。真实的数据集往往是包含姓名、日期、省份、类别标签与缺失值的异构表格数据 (Tabular Data)。
NumPy 擅长高密度的纯数字矩阵运算,但面对字符串列、缺失值 NaN 以及按列名查找时却力不从心。
这正是 Pandas 登场的时刻!可以把 Pandas 比作 Python 中的“超级 Excel 引擎”:它不仅能以极高效率读取 GB 级别的 CSV/Excel 文件,还能用极其简洁的代码完成数据清洗、条件筛选与分组统计。
完成本章学习后,你将能够:
pd.Series 与 pd.DataFrame 的层次关系及 Index、Columns、Values 物理三要素;pd.read_csv() 读取文件,以及使用 df.info() 和 df.describe() 探查数据质量;df.loc[](基于显式标签闭区间)与 df.iloc[](基于整数位置开区间)的切片用法;df[(cond1) & (cond2)] 的小括号使用规则;isnull().sum() 检测缺失值与 fillna() / dropna() 缺失值清洗流程;df.groupby().agg() 进行多指标分组统计。一个 pd.DataFrame 相当于附带了额外坐标轴信息的二维表格:
Index (行索引):每行数据的唯一身份标识(如 0, 1, 2... 或时间日期);Columns (列名/表头):每列数据的语义标签(如 'name', 'price', 'city');Values (底层的 NumPy 数组):真正存储底层数据的二维矩阵。支持自定义输入 loc/iloc 参数与布尔条件,观察 DataFrame 动态高亮与切片输出
| Index | id | name | age | city | score |
|---|---|---|---|---|---|
| 0 | 1 | Alice | 24 | Beijing | 88 |
| 1 | 2 | Bob | 29 | Shanghai | 92 |
| 2 | 3 | Charlie | 22 | Guangzhou | 79 |
| 3 | 4 | David | 31 | Beijing | 95 |
| 4 | 5 | Eva | 27 | Shenzhen | 84 |
import pandas as pd
import numpy as np
# 1. 创建一维带索引的 Series
s = pd.Series([88, 92, 79], index=["小明", "小红", "小刚"], name="Score")
print("--- pd.Series ---")
print(s)
# 2. 从 Python 字典创建二维 DataFrame
data = {
"name": ["小明", "小红", "小刚", "小华"],
"age": [24, 29, 22, 31],
"city": ["北京", "上海", "广州", "北京"],
"score": [88.5, 92.0, np.nan, 95.5]
}
df = pd.DataFrame(data)
print("\n--- pd.DataFrame ---")
print(df)
最常用的数据格式是 CSV 文本表格:
import pandas as pd
# 读取 CSV 文件 (常用参数: encoding='utf-8', sep=',')
df = pd.read_csv("./housing.csv", encoding="utf-8")
# 导出为 CSV 文件 (index=False 表示不保存默认数字行索引)
df.to_csv("./housing_cleaned.csv", index=False, encoding="utf-8")
df.head(n):查看前 行数据(默认 5 行);df.info():输出数据框占用内存、每列非空值数量 (Non-Null Count) 与数据类型 (dtypes);df.describe():输出数值列的八项统计汇总(计数、均值、标准差、最小值、四分位数、最大值);df.shape:返回 (行数, 列数) 元组。import pandas as pd
import numpy as np
df = pd.DataFrame({
"user_id": [101, 102, 103, 104, 105],
"age": [25, np.nan, 31, 22, 29],
"income": [50000, 72000, 61000, np.nan, 85000],
"status": ["active", "inactive", "active", "active", "pending"]
})
print("Shape:", df.shape)
print("\n--- df.info() ---")
df.info()
print("\n--- df.describe() ---")
print(df.describe())
这是初学 Pandas 时最容易混淆的地方。Pandas 提供了两种精准切片索引器:
df.loc[行标签, 列标签]:基于显式名称/标签 (Label-based) 进行索引。包含起始和结束端点(闭区间 [a, b]);df.iloc[行位置, 列位置]:基于 0 开始的整数位置 (Integer Position-based) 进行索引。遵循 Python 标准(前闭后开区间 [a, b))。import pandas as pd
df = pd.DataFrame({
"name": ["小明", "小红", "小刚", "小华"],
"age": [24, 29, 22, 31],
"score": [88, 92, 79, 95]
}, index=["a", "b", "c", "d"])
# 1. loc 基于标签索引:包含 'c' (闭区间)
print("--- df.loc['a':'c', ['name', 'score']] ---")
print(df.loc["a":"c", ["name", "score"]])
# 2. iloc 基于整数位置切片:不包含 2 (半开区间)
print("\n--- df.iloc[0:2, 0:2] ---")
print(df.iloc[0:2, 0:2])
在 Pandas 中组合多个筛选条件时,必须遵守两条规则:
&,逻辑或使用 |,逻辑非使用 ~(不能使用 Python 原生的 and, or, not);() 括起来。# 筛选:年龄 > 25 且 分数 >= 90
high_performers = df[(df["age"] > 25) & (df["score"] >= 90)]
# 成员资格筛选 .isin()
beijing_shanghai = df[df["city"].isin(["北京", "上海"])]
数据缺失在实际 AI 任务中极常见。Pandas 使用 NaN (Not a Number) 表示缺失值:
df.isnull().sum()(统计每列缺失值的数量);df.dropna(subset=['score'])(删除 score 列包含 NaN 的行);df['age'] = df['age'].fillna(df['age'].mean())(用年龄均值填充空值)。groupby 遵循“拆分 - 应用 - 合并”三步模式,常用于按类别统计指标:
import pandas as pd
import numpy as np
df = pd.DataFrame({
"city": ["北京", "上海", "北京", "上海", "广州", "北京"],
"department": ["HR", "Tech", "Tech", "HR", "Tech", "HR"],
"salary": [10000, 18000, 22000, 12000, 15000, np.nan]
})
# 1. 填充薪资缺失值
df["salary"] = df["salary"].fillna(df["salary"].mean())
# 2. 按城市做 Groupby 聚合统计
grouped = df.groupby("city").agg(
avg_salary=("salary", "mean"),
emp_count=("department", "count")
)
print("--- 按城市 Groupby 统计 ---")
print(grouped)
计算示例:已知薪资列表为 [10000, 18000, 22000, 12000, 15000, NaN]:
第一步(手算已知项均值并填充 NaN):
[10000, 18000, 22000, 12000, 15000, 15400]。第二步(按“北京”城市分组并计算平均薪资):
[10000, 22000, 15400];请在下方的代码块中,点击 “运行代码”,体验完整的数据载入、缺失值处理、布尔筛选与分组统计流程:
| 错误现象 / 异常类型 | 常见原因 | 标准排查与处理方式 |
|---|---|---|
TypeError: cannot compare a dtyped [object] array with a scalar | 在多条件布尔筛选时漏掉了子条件两边的小括号 () | 每个子条件表达式必须用括号包围,如 (df['a'] > 0) & (df['b'] < 10) |
KeyError: 'xxx' | 访问了不存在的列名,或 loc 查找了不存在的索引标签 | 检查列名拼写,先使用 print(df.columns) 核对所有列名 |
SettingWithCopyWarning | 对数据框切片提取出的子视图进行直接修改 | 如果需要修改切片后的 DataFrame,请先显式加上 .copy() 创建独立副本 |
pd.Series 与 pd.DataFrame 的结构以及 Index、Columns、Values 三要素;pd.read_csv() 读取文件,并用 head(), info(), describe() 探查数据;loc(基于显式标签闭区间)与 iloc(基于整数位置开区间);df[(cond1) & (cond2)] 的小括号要求;isnull().sum() 查空与 fillna() / dropna() 缺失值清洗;df.groupby().agg() 进行多指标分组统计。共 4 道精选测试题 · 答题进度已自动保存
恭喜你完成了 阶段 0.2 数据科学基础工具 的全部学习!
下一步我们将开启 [阶段 0.3 机器学习极简数学直觉] 的学习,第一站是 01. 线性代数直觉:向量与矩阵,用直观几何视角拆解向量点积与矩阵变换!