在Python数据分析领域,有这样一句话:“没有NumPy,就没有Pandas、Matplotlib和Scikit-learn”。作为Python科学计算的核心库,NumPy(Numerical Python)凭借高效的多维数组(ndarray)和向量化运算能力,成为了所有数据分析工具的底层支撑。无论是处理百万级别的销售数据,还是实现复杂的机器学习算法,NumPy都是绕不开的“基础设施”。本文将从基础到实战,带你彻底掌握NumPy的核心用法。
Python原生的列表(list)虽然灵活,但在处理大规模数值计算时效率极低。例如,计算两个长度为100万的列表的对应元素乘积,纯Python代码需要循环遍历,耗时约0.2秒;而NumPy的ndarray通过向量化运算(无需显式循环),仅需0.001秒,性能提升200倍!
ndarray的核心优势:
每个ndarray对象都有以下核心属性,理解它们是操作数组的基础:
ndim
:数组的维度(如1D、2D);shape
:各维度的长度(如(3,4)表示3行4列的二维数组);dtype
:数组元素的数据类型(如int32、float64);size
:数组总元素个数(等于各维度长度的乘积)。示例:
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.int32)
print("维度:", arr.ndim) # 输出: 2
print("形状:", arr.shape) # 输出: (2, 3)
print("类型:", arr.dtype) # 输出: int32
print("元素总数:", arr.size) # 输出: 6
NumPy提供了丰富的数组创建函数,覆盖从手动构造到自动生成的全场景需求:
最直接的方式是用np.array()
将Python列表或元组转换为ndarray:
# 一维数组
arr1 = np.array([1, 2, 3, 4]) # 形状(4,)
# 二维数组(矩阵)
arr2 = np.array([[1, 2], [3, 4], [5, 6]]) # 形状(3, 2)
处理大规模数据时,手动输入效率低下,以下函数更常用:
# 生成0到9的一维数组(类似range,但支持浮点)
arr3 = np.arange(10) # 输出: [0 1 2 3 4 5 6 7 8 9]
# 生成5个0到1的等间隔数(含端点)
arr4 = np.linspace(0, 1, 5) # 输出: [0. 0.25 0.5 0.75 1. ]
# 3行4列的全0数组(默认float64)
arr5 = np.zeros((3, 4))
# 2行2列的全1数组(指定int类型)
arr6 = np.ones((2, 2), dtype=int) # 输出: [[1 1], [1 1]]
数据分析中常用随机数组模拟测试数据,np.random
模块提供了丰富的分布函数:
# 3行2列的均匀分布随机数(0-1)
arr7 = np.random.rand(3, 2)
# 5个标准正态分布(均值0,方差1)的随机数
arr8 = np.random.randn(5)
# 1到10的随机整数(含1,不含10),形状(2,3)
arr9 = np.random.randint(1, 10, size=(2, 3))
ndarray的索引与Python列表类似,但支持多维操作:
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 取第2行(索引从0开始)
print(arr[1]) # 输出: [4 5 6]
# 取第2行第3列元素(行索引1,列索引2)
print(arr[1, 2]) # 输出: 6
# 切片:取前2行,前2列(形状(2,2))
print(arr[:2, :2]) # 输出: [[1 2], [4 5]]
# 布尔索引:筛选大于5的元素
print(arr[arr > 5]) # 输出: [6 7 8 9]
通过reshape
、ravel
等函数,可灵活调整数组形状(总元素数需保持不变):
arr = np.arange(8) # 初始形状(8,)
# 转换为2行4列的二维数组
arr_2d = arr.reshape(2, 4) # 形状(2,4)
# 展平为一维数组(等价于arr.reshape(-1))
arr_flat = arr_2d.ravel() # 输出: [0 1 2 3 4 5 6 7]
# 转置(行变列,列变行)
arr_trans = arr_2d.T # 形状(4,2)
处理多源数据时,常需要合并或分割数组:
# 垂直合并两个二维数组(行数增加)
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
c = np.concatenate((a, b), axis=0) # 输出: [[1 2], [3 4], [5 6]]
# 水平分割一维数组为3段
d = np.arange(9)
e, f, g = np.split(d, 3) # e=[0 1 2], f=[3 4 5], g=[6 7 8]
NumPy的核心价值在于高效的数值计算能力,以下是最常用的计算场景:
ndarray支持加减乘除等运算符的向量化操作(逐元素计算):
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
# 逐元素相加
print(arr1 + arr2) # 输出: [5 7 9]
# 逐元素平方
print(arr1 ** 2) # 输出: [1 4 9]
# 逐元素应用数学函数(如sin、exp)
print(np.sin(arr1)) # 输出: [0.84147098 0.90929743 0.14112001]
NumPy内置了丰富的统计函数,可快速计算均值、总和、标准差等:
arr = np.array([[1, 2], [3, 4], [5, 6]])
# 全局均值(所有元素的平均)
print(arr.mean()) # 输出: 3.5
# 按列求和(每列的总和)
print(arr.sum(axis=0)) # 输出: [9 12]
# 按行求标准差(每行的离散程度)
print(arr.std(axis=1)) # 输出: [0.5 0.5 0.5]
对于二维数组(矩阵),NumPy支持矩阵乘法、转置、逆矩阵等操作:
mat1 = np.array([[1, 2], [3, 4]])
mat2 = np.array([[5, 6], [7, 8]])
# 矩阵乘法(点积)
print(np.dot(mat1, mat2)) # 输出: [[19 22], [43 50]]
# 矩阵转置(行变列)
print(mat1.T) # 输出: [[1 3], [2 4]]
# 矩阵的逆(需方阵且行列式非零)
print(np.linalg.inv(mat1)) # 输出: [[-2. 1. ], [ 1.5 -0.5]]
某电商平台提供了7天的销售数据(单位:万元),需要计算以下指标:
# 模拟7天的销售数据(一维数组)
sales = np.array([12.3, 15.8, 18.2, 14.5, 20.1, 25.6, 28.9])
# 计算均值与标准差
mean_sales = sales.mean()
std_sales = sales.std()
print(f"日均销售额: {mean_sales:.2f}万元,标准差: {std_sales:.2f}") # 输出: 日均销售额: 19.14万元,标准差: 6.08
# 计算周末(索引5、6)总销售额
weekend_sales = sales[5:7].sum()
print(f"周末总销售额: {weekend_sales}万元") # 输出: 周末总销售额: 54.5万元
# 筛选超过均值的天数
high_days = sales[sales > mean_sales]
print(f"销售额超均值的天数: {len(high_days)}天") # 输出: 销售额超均值的天数: 3天
通过NumPy的向量化运算和统计函数,我们仅用几行代码就完成了复杂的销售分析。这种高效性在处理百万级数据时尤为明显——这正是NumPy成为数据分析“基石”的原因。
[1, 2.5]
会转为float64),需注意精度损失;copy()
方法;arr * 2
比[x*2 for x in arr]
快100倍)。NumPy的核心价值在于提供了高效的多维数组结构和底层计算能力,但它并非“全能”——例如,处理带标签的表格数据时,Pandas会更方便;可视化时需要Matplotlib配合。然而,所有上层库(如Pandas、Scikit-learn)的底层数据结构都是基于NumPy的ndarray。因此,掌握NumPy是进入Python数据分析领域的“必修课”。
下一篇文章,我们将基于NumPy,深入讲解Pandas的DataFrame操作,带你从“数组处理”进阶到“表格数据大师”!