Skip to content

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)       # 每个元素 +5

4. 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)代码逻辑已整合到各章节

OPC 超级个体实战指南