Pandas: Pandas 入门
NumPy 解决了 Python 数值计算的性能问题,但现实世界的数据远比"纯数字数组"复杂——它有列名、有混合类型、有缺失值、有各种文件格式。Pandas 就是为此而生:它让 Python 拥有了媲美 SQL 的数据操作能力,同时保持代码的简洁与直观。本节从 NumPy 的局限出发,揭示 Pandas 为什么是数据分析的"瑞士军刀"。
1. 你将学到
- ❶ NumPy 做数据分析的痛点
- ❷ Pandas 的核心优势(标签索引 / 混合类型 / 缺失值 / IO)
- ❸ DataFrame 与 ndarray / Excel / SQL 的关键差异
- ❹ Pandas 生态系统概览
- ❺ 安装 Pandas 并运行第一个程序
2. 从 NumPy 到 Pandas 的演进
(1) 痛点:Alice 的混合类型困境
Alice 是一名数据分析师,她需要处理一份客户数据:姓名是字符串、年龄是整数、工资是浮点数、入职日期是日期类型。她先用 NumPy 尝试:
▶ 示例
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
:NumPy 处理混合类型数据的困境(难度⭐)
import numpy as np
# Customer data: name(str), age(int), salary(float)
names = np.array(['Alice', 'Bob', 'Charlie'])
ages = np.array([28, 34, 25])
salaries = np.array([75000.0, 92000.0, 68000.0])
# Problem 1: mixing types forces upcast to object
mixed = np.array(['Alice', 28, 75000.0])
print(mixed.dtype) # object — loses numeric operations!
# Problem 2: cannot compute mean on object array
try:
print(np.mean(mixed)) # Error or meaningless result
except TypeError:
print("Cannot compute mean on object array")
# Problem 3: missing values need special handling
ages_with_nan = np.array([28, 34, np.nan, 25])
print(np.mean(ages_with_nan)) # nan — need np.nanmean()
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
NumPy 的核心限制是 同质类型——一个 ndarray 只能存一种数据类型。当你把字符串和数字放进同一个数组,NumPy 会把所有元素升级为 object 类型,丧失了向量化运算能力。此外,NumPy 没有"列名"概念,也没有内置的缺失值标记系统(只能借助于 np.nan,而 np.nan 仅支持浮点数)。
(2) 解法:Bob 的 Pandas DataFrame
Bob 用 Pandas 的 DataFrame 处理同样的数据——一气呵成:
▶ 示例
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
:Pandas 处理混合类型数据(难度⭐⭐)
import pandas as pd
# One DataFrame handles mixed types naturally
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'age': [28, 34, 25],
'salary': [75000.0, 92000.0, 68000.0],
'hire_date': pd.to_datetime(['2022-03-15', '2019-08-01', '2023-01-10'])
})
print(df.dtypes)
# name object
# age int64
# salary float64
# hire_date datetime64[ns]
print(df['salary'].mean()) # 78333.33 — works naturally
print(df[df['age'] > 27]) # filter by condition
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
每列保持自己的类型,统计运算自动工作,条件筛选像 SQL 一样直观——这就是 Pandas 的魅力。
(3) 收益:4 大核心能力
Pandas 在 NumPy 之上增加了 4 项关键能力:
| 能力 | NumPy | Pandas |
|---|---|---|
| 标签索引 | 只能按整数位置访问 | 按列名 / 行名访问 |
| 混合类型 | 同一数组只能一种类型 | 每列独立类型 |
| 缺失值 | np.nan(仅浮点) |
NaN / NaT / pd.NA(全覆盖) |
| 数据 IO | np.loadtxt / np.savetxt |
CSV / Excel / JSON / SQL / Parquet / HDF5 |
3. Pandas 的核心优势详解
(1) 标签索引:让数据自描述
NumPy 用 arr[0]、arr[1, 2] 访问数据——你必须记住"第 0 列是姓名,第 2 列是工资"。Pandas 让数据自己说话:
▶ 示例
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
:标签索引 vs 位置索引(难度⭐)
import numpy as np
import pandas as pd
# NumPy: must remember column order
arr = np.array([['Alice', 28, 75000.0],
['Bob', 34, 92000.0]])
# What is column 2? Have to check documentation
print(arr[0, 2]) # 75000.0 — but what does this mean?
# Pandas: column names are self-documenting
df = pd.DataFrame(arr, columns=['name', 'age', 'salary'])
df['age'] = df['age'].astype(int)
df['salary'] = df['salary'].astype(float)
print(df['salary']) # column name says it all
# 0 75000.0
# 1 92000.0
print(df.loc[0, 'name']) # Alice — label-based access
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
(2) 混合类型:每列独立 dtype
DataFrame 的每一列(Series)有自己的 dtype,就像 Excel 表格中每列可以设置不同格式一样。
| 特性 | NumPy ndarray | Pandas DataFrame |
|---|---|---|
| 类型约束 | 全局同一 dtype | 每列独立 dtype |
| 字符串列 | 整个数组降为 object | 单列为 object / StringDtype |
| 数值列 | 必须与字符串分离 | 与字符串列共存 |
| 运算 | 全局向量化 | 按列独立运算 |
(3) 缺失值处理:原生支持
Pandas 用 NaN(浮点缺失)、NaT(时间缺失)、pd.NA(通用缺失)构建了完整的缺失值体系,而 NumPy 的 np.nan 只适用于浮点类型。
▶ 示例
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
:缺失值处理对比(难度⭐)
import numpy as np
import pandas as pd
# NumPy: nan in integer array forces float conversion
arr = np.array([1, 2, np.nan, 4])
print(arr.dtype) # float64 — integers lost!
print(np.mean(arr)) # nan — need np.nanmean()
# Pandas: handles missing values per column
s = pd.Series([1, 2, pd.NA, 4], dtype='Int64') # nullable integer
print(s) # keeps integer type with <NA>
print(s.mean()) # 2.333 — auto-skips missing
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
(4) 丰富的 IO 工具:一站式数据枢纽
▶ 示例
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
:Pandas 数据读写(难度⭐)
import pandas as pd
from io import StringIO
# Read from CSV string
csv_data = """name,age,salary
Alice,28,75000
Bob,34,92000
Charlie,25,68000"""
df = pd.read_csv(StringIO(csv_data))
print(df)
# Write to different formats
# df.to_csv('output.csv', index=False)
# df.to_excel('output.xlsx', sheet_name='Employees')
# df.to_json('output.json', orient='records')
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
4. DataFrame 与 Excel / SQL 的类比
(1) 三者对比
| 概念 | Excel | SQL Table | Pandas DataFrame |
|---|---|---|---|
| 数据结构 | 工作表 (Sheet) | 表 (Table) | DataFrame |
| 行 | 行号 | 行 | Index (行标签) |
| 列 | 列字母 (A, B, C) | 列名 | Columns (列名) |
| 筛选 | AutoFilter | WHERE | df[condition] |
| 排序 | Sort | ORDER BY | df.sort_values() |
| 分组 | PivotTable | GROUP BY | df.groupby() |
| 合并 | VLOOKUP | JOIN | pd.merge() |
| 新增列 | 公式列 | SELECT expr | df['new'] = expr |
| 去重 | Remove Duplicates | DISTINCT | df.drop_duplicates() |
(2) 关键差异
虽然三者概念相似,但 DataFrame 有 Excel 和 SQL 不具备的能力:
- 可编程:用 Python 代码自动化所有操作,可重复执行
- 可扩展:与 NumPy / Matplotlib / scikit-learn 无缝集成
- 可处理大数据:轻松处理 million 级数据(Excel 限制约 1 million 行)
- 版本控制:代码文件可用 Git 管理,Excel 二进制文件不行
5. Pandas 生态系统概览
(1) Pandas 在数据科学中的位置
mindmap
root((Pandas Ecosystem))
Data Input
CSV Excel JSON
SQL Database
Parquet HDF5
Web Scraping
Data Processing
Cleaning
Transforming
Merging
Reshaping
Data Analysis
Groupby Aggregate
Pivot Table
Time Series
Statistical Summary
Data Output
Visualization Matplotlib
ML scikit-learn
Reports HTML Excel
Foundation
NumPy ndarray
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
(2) Pandas 的定位
Pandas 在 Python 数据科学栈中处于"承上启下"的核心位置:
| 层级 | 工具 | 作用 |
|---|---|---|
| 底层计算 | NumPy | 高性能数值计算引擎 |
| 数据处理 | Pandas | 表格数据的加载/清洗/变换/分析 |
| 可视化 | Matplotlib / Seaborn | 图表展示 |
| 机器学习 | scikit-learn | 模型训练与预测 |
| 深度学习 | PyTorch / TensorFlow | 神经网络 |
6. 完整示例:NumPy vs Pandas 全流程对比
▶ 示例
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
:学生成绩分析全流程(难度⭐⭐⭐)
import numpy as np
import pandas as pd
# ============================================
# Comprehensive comparison: NumPy vs Pandas
# for student grade analysis workflow
# ============================================
# --- Raw data ---
students = ['Alice', 'Bob', 'Charlie', 'Carol', 'David']
math = [85, 92, 78, 95, 88]
english = [90, 85, 82, 88, 91]
science = [88, 90, 75, 93, 86]
# --- NumPy approach ---
scores_np = np.array([math, english, science]) # shape: (3, 5)
# Which row is which subject? Must remember: row 0=math, 1=english, 2=science
# Which column is which student? Must remember order
avg_per_student = scores_np.mean(axis=0)
print("NumPy - Average per student (by position):")
for i, avg in enumerate(avg_per_student):
print(f" Student {i}: {avg:.1f}") # Who is Student 0?
# --- Pandas approach ---
df = pd.DataFrame({
'student': students,
'math': math,
'english': english,
'science': science
})
df['average'] = df[['math', 'english', 'science']].mean(axis=1)
df['grade'] = df['average'].map(
lambda x: 'A' if x >= 90 else 'B' if x >= 85 else 'C'
)
print("\nPandas - Student grades:")
print(df[['student', 'average', 'grade']])
# Top performers
top = df[df['grade'] == 'A']
print(f"\nA-grade students: {top['student'].tolist()}")
# Subject statistics
print("\nSubject statistics:")
print(df[['math', 'english', 'science']].describe())
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
预期输出(节选):
NumPy - Average per student (by position):
Student 0: 87.7
Student 1: 89.0
Student 2: 78.3
Pandas - Student grades:
student average grade
0 Alice 87.7 B
1 Bob 89.0 B
2 Charlie 78.3 C
3 Carol 92.0 A
4 David 88.3 B
A-grade students: ['Carol']
Subject statistics:
math english science
count 5.00 5.00 5.00
mean 87.60 87.20 86.40
std 6.19 3.70 7.60
min 78.00 82.00 75.00
max 95.00 91.00 93.00
NumPy 能完成计算,但结果缺乏"自描述性"——你必须额外记住哪个数字对应哪个学生。Pandas 让数据和标签始终绑定,结果一目了然。
7. 安装与验证
(1) 安装方式
| 方式 | 命令 | 适用场景 |
|---|---|---|
| pip | pip install pandas |
最通用 |
| conda | conda install pandas |
Anaconda 环境 |
| 从源码 | pip install . |
开发者/贡献者 |
▶ 示例
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
:安装验证(难度⭐)
import pandas as pd
import numpy as np
print(f"Pandas version: {pd.__version__}")
print(f"NumPy version: {np.__version__}")
# Quick functionality check
df = pd.DataFrame({'x': [1, 2, 3], 'y': [4, 5, 6]})
print(df)
print(f"\nMean of x: {df['x'].mean()}")
> **输出:** 在本地 Python 环境(pandas 2.x)运行。Piston 服务器未预装 pandas,请在本机安装(`pip install pandas`)后实操对照。实际数值会因 pandas 版本略有差异。
(2) 版本说明
| 版本 | 状态 | 说明 |
|---|---|---|
| Pandas 3.x | 当前最新 | 2026 年发布,Copy-on-Write 默认开启 |
| Pandas 2.x | 广泛使用 | 2023 年发布,性能大幅提升 |
| Pandas 1.x | 旧版 | 部分写法已 deprecated |
append)已在 2.0 中移除,我们不再使用。
❓ 常见问题
append、DataFrame.ix 等废弃 API;(3) 底层使用 PyArrow 提升性能。本教程使用 2.x/3.x 语法,1.x 用户建议升级。pip install pandas 一行命令。📖 小节
- Pandas 在 NumPy 之上增加了标签索引、混合类型、缺失值处理和丰富 IO 工具 4 大核心能力
- DataFrame ≈ 可编程的 Excel 表 ≈ 内存中的 SQL 表,但具备自动化/可扩展/可版本控制优势
- Pandas 处于 Python 数据科学栈核心位置:NumPy → Pandas → Matplotlib/scikit-learn
- 95% 的数据分析工作使用 Pandas 完成,NumPy 是底层计算引擎
- Pandas 2.x/3.x 是当前主流版本,1.x 部分写法已废弃
- 对于超出单机能力的大数据,可升级到 Dask/Polars/PySpark
📝 作业
- 基础题(难度⭐):安装 Pandas 并运行验证代码,确认
pd.__version__输出正常。创建一个包含 3 列(name / age / city)的 DataFrame 并打印。 - 进阶题(难度⭐⭐):用 NumPy 和 Pandas 分别处理同一份学生成绩数据(5 名学生 / 3 门课),计算每名学生平均分和每门课最高分。对比两者代码量和可读性。
- 挑战题(难度⭐⭐⭐):从 CSV 字符串中加载一份含缺失值的数据,用 Pandas 完成:查看 info → 填充缺失值 → 按类别分组统计 → 输出 describe。全程只使用 Pandas,不使用任何循环。