06 NumPy & Pandas — 学习指南
学习理念:NumPy 是 Python 数据计算的"发动机",Pandas 是"方向盘"。 AI 可以帮你写任何数据处理代码,你需要理解的是数据长什么样、要做什么变换、怎么清洗和分析。
学习路径
NumPy 数组 → NumPy 运算 → Pandas Series → Pandas DataFrame → 合并/清洗 → 分组聚合 → 可视化 → 综合案例
① 🟢 NumPy ndarray(数组创建/属性/切片)
② 🟡 NumPy 运算(广播/统计/矩阵运算)
③ 🟢 Pandas Series(一维数据结构)
④ 🟢 Pandas DataFrame(二维数据结构,核心)
⑤ 🟡 数据合并(concat/merge/join)
⑥ 🟢 缺失值与数据清洗
⑦ 🟡 分组聚合与 apply
⑧ 🟡 日期与时间序列
⑨ 🟡 可视化(matplotlib/seaborn)
⑩ 🟡 综合案例:房价数据分析本节 AI 替代率:~95% | 人工干预率:~5%
AI 擅长:写数据清洗代码、统计计算、生成图表。
人类需决策:数据分析思路、特征选择、业务洞察。
1. NumPy ndarray
李永乐式比喻:Python 列表是"装杂物的抽屉"(可以放任何类型),NumPy 数组是"装同种货物的货架"(只能放一种类型)。 因为货物规格统一,搬运工(CPU)可以用叉车一次处理一批,而不是一件一件搬——速度提升 10~100 倍。
安装
bash
pip install numpy pandas matplotlib seaborn创建数组
python
import numpy as np
# 从列表创建
arr = np.array([1, 2, 3, 4, 5])
print(arr) # [1 2 3 4 5]
print(type(arr)) # <class 'numpy.ndarray'>
# 二维数组(矩阵)
matrix = np.array([[1, 2, 3], [4, 5, 6]])
print(matrix.shape) # (2, 3) 2 行 3 列
# 常用创建方式
np.zeros((3, 4)) # 3 行 4 列的全 0 矩阵
np.ones((2, 3)) # 2 行 3 列的全 1 矩阵
np.eye(3) # 3x3 单位矩阵
np.empty((2, 2)) # 2x2 未初始化数组(速度快)
# 序列
np.arange(10) # [0 1 2 ... 9]
np.arange(2, 10, 2) # [2 4 6 8]
np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1. ] 等间距 5 个数ndarray 属性
python
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.ndim) # 2(维度数)
print(arr.shape) # (2, 3)(形状)
print(arr.size) # 6(元素总数)
print(arr.dtype) # int64(数据类型)切片与索引
python
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
# 基本切片
print(arr[0]) # [1 2 3 4] 第一行
print(arr[:, 1]) # [2 6 10] 第二列
print(arr[1:, 2:]) # [[7 8], [11 12]] 子矩阵
print(arr > 5) # [[F F F F], [F T T T], [T T T T]] 布尔数组
print(arr[arr > 5]) # [6 7 8 9 10 11 12] 布尔索引2. NumPy 运算与广播
数组运算
python
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# 逐元素运算(比 Python 循环快 10~50 倍)
print(a + b) # [5 7 9]
print(a * b) # [4 10 18]
print(a ** 2) # [1 4 9]
print(a > 2) # [False False True]
# 统计函数
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.sum()) # 21(总和)
print(arr.mean()) # 3.5(平均值)
print(arr.max()) # 6(最大值)
print(arr.min()) # 1(最小值)
print(arr.std()) # 1.7(标准差)
# 按轴运算
print(arr.sum(axis=0)) # [5 7 9] 按列求和
print(arr.sum(axis=1)) # [6 15] 按行求和广播机制(⚠️ 需要理解)
李永乐式比喻:一张 5×5 的大贴纸和一张 1×5 的小贴纸拼在一起,小贴纸会自动"复制"成 5×5 的大小,然后贴上去。
python
# 广播:不同形状的数组也能做运算
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 3x3
b = np.array([1, 0, 1]) # 1x3
# b 自动"广播"成和 a 一样的形状:
# [[1, 0, 1],
# [1, 0, 1],
# [1, 0, 1]]
print(a + b)
# [[2 2 4]
# [5 5 7]
# [8 8 10]]
# 矩阵乘法(不触发广播)
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print(a @ b) # 矩阵乘法
print(np.dot(a, b)) # 等价3. Pandas Series
李永乐式比喻:Series = Excel 中的一列数据,但每个格子都有一个"行标签"(索引)。
python
import pandas as pd
# 创建 Series
s = pd.Series([85, 90, 78, 92], index=["张三", "李四", "王五", "赵六"])
print(s)
# 张三 85
# 李四 90
# 王五 78
# 赵六 92
# dtype: int64
# 常用属性
print(s.values) # [85 90 78 92]
print(s.index) # Index(['张三', '李四', '王五', '赵六'], dtype='object')
print(s.size) # 4
# 常用方法
print(s.mean()) # 86.25
print(s.max()) # 92
print(s.min()) # 78
print(s.std()) # 6.18
# 排序
print(s.sort_values()) # 按值排序
print(s.sort_index()) # 按索引排序
# 布尔索引
print(s[s > 80]) # 张三 85, 李四 90, 赵六 92
# 运算
print(s + 5) # 每个元素 +54. Pandas DataFrame
李永乐式比喻:DataFrame = 一张完整的 Excel 表格。Series 是一列,DataFrame 是多列。
python
# 创建 DataFrame
data = {
"姓名": ["张三", "李四", "王五"],
"年龄": [20, 22, 21],
"成绩": [85, 90, 78],
}
df = pd.DataFrame(data)
print(df)
# 姓名 年龄 成绩
# 0 张三 20 85
# 1 李四 22 90
# 2 王五 21 78常用属性与方法
python
df = pd.read_csv("data.csv") # 从 CSV 读数据(最常用)
print(df.head()) # 前 5 行
print(df.tail(3)) # 后 3 行
print(df.info()) # 列名、类型、非空数(⭐⭐ 最常用)
print(df.describe()) # 数值列的统计摘要(均数/标准差/分位数)
print(df.shape) # (行数, 列数)
print(df.columns) # 所有列名
print(df.dtypes) # 每列的数据类型选取数据
python
# 选列
print(df["姓名"]) # Series
print(df[["姓名", "成绩"]]) # DataFrame
# 选行
print(df.iloc[0]) # 第 0 行(按位置)
print(df.iloc[1:3]) # 第 1~2 行
print(df.loc[0]) # 第 0 行(按索引名)
# 条件筛选
print(df[df["成绩"] > 80]) # 成绩 > 80 的行
print(df[(df["成绩"] > 80) & (df["年龄"] < 22)]) # 多条件修改操作
python
# 新增列
df["等级"] = df["成绩"].apply(lambda x: "优秀" if x >= 90 else "良好")
# 修改列
df["年龄"] = df["年龄"] + 1 # 所有人年龄 +1
# 删除列
df = df.drop("等级", axis=1)
# 重命名列
df = df.rename(columns={"姓名": "name", "成绩": "score"})5. 数据合并(concat / merge / join)
python
# concat:纵向拼接(上下堆叠)
df1 = pd.DataFrame({"A": [1, 2], "B": [3, 4]})
df2 = pd.DataFrame({"A": [5, 6], "B": [7, 8]})
result = pd.concat([df1, df2])
# A B
# 0 1 3
# 1 2 4
# 0 5 7
# 1 6 8
# merge:横向连接(类似 SQL JOIN)
students = pd.DataFrame({"id": [1, 2, 3], "name": ["张三", "李四", "王五"]})
scores = pd.DataFrame({"id": [1, 2, 4], "score": [85, 90, 88]})
result = pd.merge(students, scores, on="id", how="inner")
# id name score
# 0 1 张三 85
# 1 2 李四 90
# how 参数:inner=交集, left=左表全保留, right=右表全保留, outer=并集6. 缺失值与数据清洗
python
# 查看缺失值
print(df.isna().sum()) # 每列的缺失值数量
print(df.info()) # Non-Null Count 列
# 填充缺失值
df["年龄"] = df["年龄"].fillna(df["年龄"].mean()) # 用均值填充
df["姓名"] = df["姓名"].fillna("未知") # 用固定值填充
df = df.fillna(method="ffill") # 用上一个值填充(前向填充)
# 剔除缺失值
df = df.dropna() # 删除包含 NaN 的行
df = df.dropna(subset=["年龄"]) # 只检查"年龄"列
df = df.dropna(axis=1) # 删除包含 NaN 的列7. 分组聚合与 apply
李永乐式比喻:
groupby= 把全班同学按性别分成两组,然后分别统计身高平均值的操作。
python
df = pd.DataFrame({
"班级": ["A", "A", "B", "B"],
"姓名": ["张三", "李四", "王五", "赵六"],
"成绩": [85, 90, 78, 92],
})
# 分组聚合
result = df.groupby("班级")["成绩"].mean()
# 班级
# A 87.5
# B 85.0
# 多列聚合
result = df.groupby("班级").agg({
"成绩": ["mean", "max", "min", "count"],
"姓名": "count"
})
# apply:逐行/逐列处理
df["成绩评价"] = df["成绩"].apply(lambda x: "优秀" if x >= 90 else "普通")8. 日期与时间序列
python
# 创建日期数据
dates = pd.date_range("2026-01-01", periods=5, freq="D")
print(dates)
# DatetimeIndex(['2026-01-01', '2026-01-02', '2026-01-03', '2026-01-04', '2026-01-05'], ...)
# 设置日期为索引
df["日期"] = pd.to_datetime(df["日期"]) # 转为日期类型
df = df.set_index("日期")
# 按时间筛选
print(df["2026-01-01":"2026-01-03"])
# 日期提取
df["年"] = df.index.year
df["月"] = df.index.month
df["日"] = df.index.day
df["星期"] = df.index.dayofweek # 0=周一
# 时间序列重采样
df.resample("M")["销售额"].sum() # 按月汇总
df.resample("Q")["销售额"].mean() # 按季度汇总9. 可视化
python
import matplotlib.pyplot as plt
import seaborn as sns
# Matplotlib 基础
plt.figure(figsize=(10, 6))
plt.plot([1, 2, 3, 4], [1, 4, 9, 16], "o-", label="数据")
plt.xlabel("X 轴")
plt.ylabel("Y 轴")
plt.title("图表标题")
plt.legend()
plt.show()
# Pandas 内置可视化
df["成绩"].plot(kind="hist", bins=10) # 直方图
df.plot(kind="scatter", x="年龄", y="成绩") # 散点图
# Seaborn(更美观)
sns.set_theme() # 设置样式
sns.histplot(df["成绩"]) # 直方图
sns.boxplot(x="班级", y="成绩", data=df) # 箱线图(看分布/异常值)
sns.heatmap(df.corr(), annot=True) # 热力图(看相关性)
sns.pairplot(df) # 矩阵散点图(全体特征对比)10. 综合案例:房价数据分析
原始数据集:
2.资料/data/house_sales.csv
python
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 1. 读取数据
df = pd.read_csv("house_sales.csv")
print(df.info()) # 看数据结构
print(df.describe()) # 看数值统计
# 2. 数据清洗
df = df.dropna() # 剔除缺失值
# 3. 特征工程(添加新列)
df["房龄"] = 2026 - df["建造年份"]
df["每平米单价"] = df["价格"] / df["面积"]
# 4. 相关性分析
print(df.corr()) # 数值列之间的相关系数矩阵
plt.figure(figsize=(10, 8))
sns.heatmap(df.corr(), annot=True, cmap="RdBu")
plt.title("房价相关性矩阵")
plt.show()
# 5. 可视化洞察
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
axes[0, 0].scatter(df["面积"], df["价格"], alpha=0.5)
axes[0, 0].set_title("面积 vs 价格")
axes[0, 1].hist(df["价格"], bins=30)
axes[0, 1].set_title("价格分布")
axes[1, 0].boxplot(df["价格"].values)
axes[1, 0].set_title("价格箱线图")
sns.countplot(x="卧室数", data=df, ax=axes[1, 1])
axes[1, 1].set_title("卧室数量分布")
plt.tight_layout()
plt.show()AI 协作指南
AI 能做的:
- 根据数据描述生成完整的数据清洗代码
- 根据分析需求生成 pandas 操作链
- 生成 matplotlib/seaborn 可视化代码
- 解释数据集的统计特征
人类需决策的:
- 数据分析的总体思路和方向
- 哪些特征是重要的、哪些是噪声
- 如何解读可视化结果、提炼业务洞察
最高效的学习方式:
- 把 CSV 文件路径和分析需求描述给 AI
- 让 AI 生成完整的 EDA(探索性数据分析)代码
- 重点关注数据清洗逻辑和特征工程思路
- 不需要背 pandas 的 API,用的时候问 AI附录:原始资料处理说明
| 原始文件 | 处理方式 |
|---|---|
尚硅谷大模型技术之numpy与pandas1.0.docx | 内容已整合到本文档各章节 |
Anaconda3-2024.10 | 不推荐安装,建议用 pip 按需安装 |
2.资料/data/*.csv(6 个文件) | 保留使用,各章节案例中标注 |
| 视频(80+ 个) | 跳过 |
| 代码(27 个 Jupyter Notebook) | 代码逻辑已整合到各章节 |