写在前面
第89天了。
前88天把 NumPy 的核心模块过了一遍,但单独用 NumPy 能做的事其实有限。真实项目里,它更多是作为底层支撑,配合 Pandas 处理表格、配合 Matplotlib 出图、配合 SciPy 做高级计算。
今天就把这三个组合都跑一遍。
今日学习目标
- NumPy 与 Pandas 之间的数据转换和协同计算
- 用 NumPy 生成数据,配合 Matplotlib 绘图
一、NumPy × Pandas:表格数据的搭档
Pandas 的 DataFrame 和 Series 底层就是 NumPy 数组。两者配合,NumPy 负责高性能计算,Pandas 负责数据操作,各司其职。
1.1 相互转换:一行代码搞定
import numpy as npimport pandas as pd# ✅ NumPy → Pandasnp_data = np.array([[1, 2, 3], [4, 5, 6]])df = pd.DataFrame(np_data, columns=['A', 'B', 'C'])print("DataFrame:\n", df)# ✅ Pandas → NumPy(推荐现代写法 .to_numpy())arr_from_df = df.to_numpy()print("\n转换回数组:\n", arr_from_df)
两点要注意:
- 用
df.to_numpy() 而不是 df.values,后者已经被弃用 - 转换后的数组和 DataFrame 共享内存,修改前记得
.copy()
1.2 协同计算:各取所长
# 在 Pandas 中直接调用 NumPy 函数mean_vals = np.mean(df, axis=0) # 计算每列均值print("每列均值:", mean_vals) # 输出: A:2.5 B:3.5 C:4.5# 复杂场景:Pandas 做分组,NumPy 做向量化运算df['D'] = np.where(df['A'] > 2, 'High', 'Low') # 条件赋值print("\n添加条件列后:\n", df)
二、NumPy × Matplotlib:数据可视化
Matplotlib 的图表数据来源基本都是 NumPy 数组,两者配合是 Python 数据可视化最常见的写法。
2.1 生成数据 + 绘制函数曲线
import matplotlib.pyplot as plt# 1. NumPy 生成平滑数据x = np.linspace(0, 10, 100) # 0到10之间均匀取100个点y_sin = np.sin(x) # 计算正弦值y_cos = np.cos(x) # 计算余弦值# 2. Matplotlib 绘制双图对比plt.figure(figsize=(10, 4))plt.subplot(1, 2, 1)plt.plot(x, y_sin, label='sin(x)', color='blue', linewidth=2)plt.title('正弦函数')plt.xlabel('x (弧度)')plt.ylabel('y')plt.grid(True)plt.legend()plt.subplot(1, 2, 2)plt.plot(x, y_cos, label='cos(x)', color='orange', linewidth=2)plt.title('余弦函数')plt.xlabel('x (弧度)')plt.ylabel('y')plt.grid(True)plt.legend()plt.tight_layout()plt.show() # 在Jupyter或IDE中自动弹出窗口
2.2 统计分析 + 直方图可视化
# 生成1000个标准正态分布随机数data = np.random.randn(1000)plt.figure(figsize=(8, 5))# Matplotlib 直接接收 NumPy 数组绘图plt.hist(data, bins=30, alpha=0.7, color='steelblue', edgecolor='black')plt.axvline(np.mean(data), color='red', linestyle='--', label=f'均值={np.mean(data):.2f}')plt.title('正态分布随机数直方图')plt.xlabel('数值')plt.ylabel('频数')plt.legend()plt.grid(axis='y', alpha=0.3)plt.show()
分工很清晰:NumPy 算数据,Matplotlib 画图,不需要额外转换。
三、NumPy × SciPy:科学计算进阶
SciPy 建在 NumPy 之上,补充了 NumPy 没有的高级算法。需要做优化、插值、信号处理时,用 SciPy。
3.1 线性代数加速:scipy.linalg
from scipy.linalg import inv, detA = np.array([[1, 2], [3, 4]])# SciPy 的 inv 通常比 np.linalg.inv 更快、更稳定A_inv = inv(A)print("矩阵逆:\n", A_inv)print("行列式:", det(A)) # 输出: -2.0
3.2 函数优化:scipy.optimize
from scipy.optimize import minimize# 定义目标函数:f(x) = x² + 3x + 2def objective(x): return x[0]**2 + 3*x[0] + 2# 从初始点 x=0 开始寻找最小值result = minimize(objective, x0=[0])print("最优解 x:", result.x[0]) # ≈ -1.5print("最小值 f(x):", result.fun) # ≈ -0.25print("是否成功:", result.success) # True
3.3 数据插值:scipy.interpolate
from scipy.interpolate import interp1dx = np.array([1, 2, 3, 4])y = np.array([1, 4, 9, 16]) # y = x²# 创建线性插值函数f_linear = interp1d(x, y, kind='linear')# 生成密集点并插值x_new = np.linspace(1, 4, 10)y_new = f_linear(x_new)print("插值结果 y_new:", np.round(y_new, 2))# 输出: [ 1. 2.33 3.67 5. 6.33 7.67 9. 10.67 12.33 14. ]
今日作业
基础题 ⭐
- 创建一个
3×3 的 NumPy 数组,转换为 Pandas DataFrame 并打印 - 使用
np.linspace 生成 0~2π 的50个点,用 Matplotlib 绘制 tan(x) 曲线(注意设置 ylim 避免无穷大) - 用
scipy.linalg.det() 计算矩阵 [[2,1],[1,2]] 的行列式
进阶题 ⭐⭐
- 读取一个包含缺失值的 CSV 文件(可用 Pandas),提取数值列转为 NumPy 数组,计算每列的
均值±标准差 - 使用
scipy.optimize.minimize 求函数 f(x,y) = (x-2)² + (y+3)² 的最小值点 - 将
np.random.normal(0,1,500) 的数据绘制为带拟合正态曲线的直方图(提示:用 scipy.stats.norm.pdf)
挑战题 ⭐⭐⭐
- 完整数据流:用 NumPy 生成模拟销售数据 → 用 Pandas 分组求和 → 用 Matplotlib 绘制柱状图 → 用 SciPy 拟合趋势线
- 性能对比:对比
np.linalg.inv 与 scipy.linalg.inv 对 1000×1000 随机矩阵求逆的耗时 - 自定义插值器:封装一个函数,输入稀疏数据点,返回指定分辨率的平滑插值数组及绘图
参考代码(基础题1):
import numpy as npimport pandas as pdarr = np.arange(1, 10).reshape(3, 3)df = pd.DataFrame(arr, columns=['X', 'Y', 'Z'])print(df)
学习小贴士
内存与视图:
- Pandas 和 NumPy 转换默认共享内存,大规模修改前建议
.copy() - 用
df.to_numpy() 而不是 .values
函数选择:
调试:
- 形状报错先看
arr.shape 和 df.shape - 图空白检查有没有漏
plt.show(),或者数据范围是否异常
写在最后
NumPy 单独用能做的事不多,配合 Pandas、Matplotlib、SciPy 才是它真正的使用场景。
做完作业的同学欢迎评论区打卡,贴代码或截图都行。
【一起学Python】
每天一点,明天见。
NumPy 是地基,Pandas 是框架,Matplotlib 是外墙,SciPy 是设备。缺哪个都盖不成楼。