【Python数据科学】Pandas进阶 + NumPy入门,数据分析双剑合璧
·
【Python数据科学】Pandas进阶 + NumPy入门,数据分析双剑合璧
从数据处理到数值计算,掌握数据分析核心工具链
先看问题
假设你是一名数据分析师,面对以下场景:
场景1:老板要看每个部门的薪资分布,还要对比不同城市的差异
场景2:需要把销售数据、客户数据、产品数据合并分析
场景3:要计算销售额的环比增长率、移动平均
场景4:数据库里有100万条订单数据,需要快速读取并分析
场景5:要做线性回归预测下季度销售额
这些问题,用 Pandas + NumPy 就能轻松解决!
一、Pandas 进阶:数据处理的瑞士军刀
1.1 groupby 高级用法
import pandas as pd
# 命名聚合(推荐)
df.groupby('department').agg(
avg_salary=('salary', 'mean'),
max_salary=('salary', 'max'),
count=('id', 'count')
)
# 多函数聚合
df.groupby('department')['salary'].agg(['mean', 'max', 'min'])
# 自定义聚合函数
df.groupby('department')['salary'].agg(lambda x: x.max() - x.min())
1.2 pivot_table 透视表
# 类似 Excel 的透视表
pd.pivot_table(
df,
values='salary', # 聚合的值
index='department', # 行索引
columns='gender', # 列索引
aggfunc='mean', # 聚合函数
fill_value=0, # 填充空值
margins=True # 添加汇总行
)
1.3 merge 数据合并
# 内连接(类似 SQL INNER JOIN)
pd.merge(employees, departments, on='department_id', how='inner')
# 左连接(类似 SQL LEFT JOIN)
pd.merge(employees, departments, on='department_id', how='left')
# 多键连接
pd.merge(df1, df2, on=['city', 'department'], how='inner')
1.4 与数据库交互
from sqlalchemy import create_engine
# 创建连接
engine = create_engine('postgresql://user:password@localhost:5432/mydb')
# 读取数据
df = pd.read_sql('SELECT * FROM employees', engine)
# 写入数据
df.to_sql('new_table', engine, if_exists='replace', index=False)
# 关闭连接
engine.dispose()
二、NumPy:数值计算的基石
2.1 为什么需要 NumPy?
| 对比项 | Python List | NumPy Array |
|---|---|---|
| 性能 | 慢 | 快 10-100 倍 |
| 内存 | 分散 | 连续 |
| 运算 | 需要循环 | 向量化 |
| 类型 | 任意 | 固定 |
2.2 创建数组
import numpy as np
# 从列表创建
arr = np.array([1, 2, 3, 4])
# 全0数组
zeros = np.zeros((3, 4)) # 3行4列
# 全1数组
ones = np.ones(5)
# 序列
arr = np.arange(0, 10, 2) # [0, 2, 4, 6, 8]
# 随机数
rand = np.random.rand(5) # 0-1均匀分布
randn = np.random.randn(5) # 标准正态分布
randint = np.random.randint(1, 100, 5) # 整数
2.3 数组运算
arr1 = np.array([1, 2, 3, 4])
arr2 = np.array([5, 6, 7, 8])
# 数组间运算(对应位置)
print(arr1 + arr2) # [6, 8, 10, 12]
print(arr1 * arr2) # [5, 12, 21, 32]
# 标量运算(每个元素)
print(arr1 * 2) # [2, 4, 6, 8]
print(arr1 + 10) # [11, 12, 13, 14]
# 比较运算(返回布尔数组)
print(arr1 > 2) # [False, False, True, True]
2.4 聚合函数
arr = np.array([15, 23, 42, 87, 56, 12, 34, 67])
print(arr.sum()) # 总和
print(arr.mean()) # 均值
print(arr.std()) # 标准差
print(arr.max()) # 最大值
print(arr.min()) # 最小值
print(arr.cumsum()) # 累计和
2.5 矩阵运算
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
# 矩阵乘法
print(A @ B) # 推荐写法
print(np.dot(A, B))
# 转置
print(A.T)
# 逆矩阵
print(np.linalg.inv(A))
# 行列式
print(np.linalg.det(A))
# 特征值
values, vectors = np.linalg.eig(A)
2.6 统计函数
data = np.array([12, 25, 37, 48, 52, 61, 73, 84, 91, 100])
# 均值、中位数、标准差
print(np.mean(data))
print(np.median(data))
print(np.std(data))
# 百分位数
print(np.percentile(data, 25)) # 25%
print(np.percentile(data, 75)) # 75%
# 相关系数
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 5, 4, 5])
print(np.corrcoef(x, y)[0, 1]) # 接近1表示强相关
三、Pandas vs NumPy 对比
| 操作 | Pandas | NumPy |
|---|---|---|
| 创建 | pd.DataFrame() |
np.array() |
| 索引 | 标签索引 loc/iloc |
位置索引 [0] |
| 运算 | 自动对齐 | 对应位置 |
| 缺失值 | fillna() |
有限支持 |
| 分组 | groupby() |
无 |
| 矩阵 | 无 | @ / dot() |
| 性能 | 较慢 | 最快 |
选择建议:
- 数据分析 → Pandas
- 数值计算 → NumPy
- 大数据处理 → NumPy
- 表格处理 → Pandas
四、踩坑记录
4.1 Pandas 踩坑
坑1:groupby + apply 警告
# ❌ 会警告
df.groupby('department').apply(lambda x: x.sort_values('salary'))
# ✅ 正确写法
df.groupby('department').apply(
lambda x: x.sort_values('salary'),
include_groups=False
)
坑2:merge 列名冲突
# 如果两个表有相同列名,会自动加 _x, _y 后缀
pd.merge(df1, df2, on='id') # name_x, name_y
# 指定后缀
pd.merge(df1, df2, on='id', suffixes=('_left', '_right'))
坑3:to_sql 外键约束
# ❌ 如果表有外键约束,replace 会失败
df.to_sql('departments', engine, if_exists='replace')
# ✅ 先删除外键约束,或换个表名
df.to_sql('departments_new', engine, if_exists='replace')
4.2 NumPy 踩坑
坑1:数组形状不匹配
arr1 = np.array([1, 2, 3, 4]) # shape (4,)
arr2 = np.array([5, 6]) # shape (2,)
# ❌ 会报错
arr1 + arr2 # ValueError: operands could not be broadcast together
坑2:修改视图会影响原数组
arr = np.array([1, 2, 3, 4, 5])
view = arr[0:3]
# ❌ 修改 view 会影响 arr
view[0] = 100
print(arr) # [100, 2, 3, 4, 5]
# ✅ 使用 copy
copy = arr[0:3].copy()
坑3:整数除法
arr = np.array([1, 2, 3, 4])
# ❌ 整数除法会向下取整
print(arr / 2) # [0.5, 1. , 1.5, 2. ] # 实际会返回浮点数
# ✅ 如果要整数结果
print(arr // 2) # [0, 1, 1, 2]
五、实战案例
5.1 使用 Pandas 分析销售数据
import pandas as pd
from sqlalchemy import create_engine
# 1. 从数据库读取数据
engine = create_engine('postgresql://postgres:password@localhost:5432/mydb')
sales = pd.read_sql('SELECT * FROM sales', engine)
# 2. 数据清洗
sales['date'] = pd.to_datetime(sales['date'])
sales['amount'] = sales['amount'].fillna(0)
# 3. 计算环比增长率
sales['growth_rate'] = sales['amount'].pct_change()
# 4. 分组统计
dept_stats = sales.groupby('department').agg(
total_sales=('amount', 'sum'),
avg_sales=('amount', 'mean'),
count=('id', 'count')
)
# 5. 写回数据库
dept_stats.to_sql('dept_stats', engine, if_exists='replace')
engine.dispose()
5.2 使用 NumPy 做线性回归
import numpy as np
# 模拟数据
np.random.seed(42)
x = np.linspace(0, 10, 50)
y = 3 * x + 5 + np.random.normal(0, 2, 50)
# 最小二乘法拟合
n = len(x)
a = (n * np.sum(x * y) - np.sum(x) * np.sum(y)) / (n * np.sum(x**2) - np.sum(x)**2)
b = (np.sum(y) - a * np.sum(x)) / n
print(f"拟合结果: y = {a:.2f}x + {b:.2f}")
print(f"真实参数: y = 3x + 5")
六、方法速查表
Pandas 常用方法
| 类别 | 方法 | 说明 |
|---|---|---|
| 读取 | read_sql() |
从数据库读取 |
| 写入 | to_sql() |
写入数据库 |
| 分组 | groupby().agg() |
分组聚合 |
| 透视 | pivot_table() |
透视表 |
| 合并 | merge() |
数据合并 |
| 拼接 | concat() |
数据拼接 |
| 环比 | pct_change() |
环比增长率 |
| 排名 | rank() |
排名 |
NumPy 常用方法
| 类别 | 方法 | 说明 |
|---|---|---|
| 创建 | array(), zeros(), ones() |
创建数组 |
| 运算 | +, -, *, /, @ |
数组运算 |
| 聚合 | sum(), mean(), std() |
聚合函数 |
| 矩阵 | dot(), inv(), det() |
矩阵运算 |
| 统计 | median(), percentile() |
统计函数 |
| 随机 | rand(), randn(), randint() |
随机数 |
七、学习路径
Day 14-16: Pandas 基础(DataFrame、筛选、分组)
↓
Day 17-18: Pandas 进阶(透视表、合并、数据库)
↓
Day 19-20: NumPy 基础 + 进阶(数组、矩阵、统计)
↓
Day 21-22: Matplotlib 可视化
↓
Day 23+: 综合项目实战
八、总结
- Pandas 是数据处理的瑞士军刀:适合表格数据、数据分析
- NumPy 是数值计算的基石:适合矩阵运算、数值计算
- 两者配合使用:Pandas 底层依赖 NumPy,可以互相转换
- 不用深究数学原理:会用函数就行,数学慢慢补
掌握 Pandas + NumPy,数据分析基本功就扎实了!
下一篇:Matplotlib 数据可视化,让数据说话!
更多推荐
所有评论(0)