云计算百科
云计算领域专业知识百科平台

机器学习之Numpy(Machine Learning about Numpy)

二、NumPy数据处理

1、Numpy基础与数组创建

1.1 Numpy基础知识

Numpy(Numerical Python)是Python编程语言里面用于数值计算的基础库,它提供了高性能的多维数组对象 narray 以及一系列用于操作这类数组的工具函数。NumPy于2005年发布,现如今已成为Python数据科学生态系统的核心组件。

💡重要提示:pandas、scipy、scikit-learn等主流数据处理库都是基于NumPy构建的。掌握NumPy就像掌握了数据分析的「内功心法」,后续学习其他库将事半功倍。

NumPy的核心特性包括:

  • 向量化运算:无需编写循环即可对整个数组进行数学运算。
  • 广播机制:支持不同形状数组之间的运算。
  • 高效内存存储:连续内存块存储,访问速度快。
  • 丰富的数学函数库:线性代数、傅里叶变换、随机数生成等。

1.2 ndarray 与 Python列表

对于Python列表与Numpy数组两者之间的关系让大多数初学者有些不解,虽然看着并无差别,但是通过特性回来看确实大不相同。

💡NumPy数组

  • 元素类型:必须同质
  • 运算方式:向量化运算
  • 执行速度:使用C语言作为底层,速度快
  • 内存占用:紧凑,连续内存块
  • 维度支持:原生N维数组
  • 功能丰富度:多维运算、矩阵分解、统计聚合

import numpy as np
import time

# Python列表:循环求和
py_list = list(range(1000000))
start = time.time()
py_sum = sum(py_list)
print(f"Python列表求和耗时:{time.time() – start:.4f}秒")

# NumPy数组:向量化求和
np_arr = np.arange(1000000)
start = time.time()
np_sum = np_arr.sum()
print(f"NumPy数组求和耗时:{time.time() – start:.4f}秒")

1.3 创建数组的方式

# NumPy库
import numpy as np

# 方式1:从Python列表转换(最常用)
a = np.array([1, 2, 3, 4, 5])
print(f"从列表创建:{a}") # [1 2 3 4 5]

# 方式2:全0数组
zeros_1d = np.zeros(5) # 一维:5个元素
zeros_2d = np.zeros((3, 4)) # 二维:3行4列
print(f"全0一维数组:{zeros_1d}")
# [0. 0. 0. 0. 0.]

# 方式3:全1数组
ones_1d = np.ones(5)
ones_2d = np.ones((3, 4))
print(f"全1二维数组:\\n{ones_2d}")
# [[1. 1. 1. 1.]
# [1. 1. 1. 1.]
# [1. 1. 1. 1.]]

# 方式4:指定填充值的数组
full_arr = np.full((2, 3), 7) # 2行3列,全部填充7
print(f"全7数组:\\n{full_arr}")
# [[7 7 7]
# [7 7 7]]

# 方式5:范围数组
arr1 = np.arange(0, 10, 2) # 开始0,结束10,步长2
arr2 = np.linspace(0, 1, 5) # 开始0,结束1,均匀切分5份
print(f"arange创建:{arr1}") # [0 2 4 6 8]
print(f"linspace创建:{arr2}") # [0. 0.25 0.5 0.75 1. ]

# 方式6:随机数组(最常用)
rand_uniform = np.random.rand(3, 4) # 0~1均匀分布
rand_int = np.random.randint(0, 10, (3, 4)) # 0~10整数随机
randn = np.random.randn(3, 4) # 标准正态分布(均值0方差1)
print(f"随机整数数组:\\n{rand_int}")

💡注意事项: np.arange() 的区间是左闭右开 [start, stop) ,而 np.linspace() 是左闭右闭 [st

art, stop] 。

1.4 数组的关键属性

每个NumPy数组都有以下重要属性,理解它们对于数组的操作可谓是必不可少:

a = np.array([[1, 2, 3], [4, 5, 6]])

print(f"形状 (shape):{a.shape}") # (2, 3) – 2行3列
print(f"维度数 (ndim):{a.ndim}") # 2 – 二维数组
print(f"数据类型 (dtype):{a.dtype}") # int64 – 64位整数
print(f"元素总数 (size):{a.size}") # 6 – 共6个元素
print(f"单个元素字节数 (itemsize):{a.itemsize}") # 8
print(f"数组总字节数 (nbytes):{a.nbytes}") # 48

1.5  数据类型详解

NumPy支持多种数据类型,合理选择可以节省内存:

dtype 说明 字节数 典型用途
int32 32位整数 4 一般整数运算
int64 64位整数 8 大数值统计
float32 单精度浮点 4 内存敏感场景
float 双精度浮点 8 精度要求高
bool 布尔类型 1 条件判断
boject Python对象 可变 混合类型存储

# 指定数据类型
arr1 = np.array([1, 2, 3], dtype=np.float32)
arr2 = np.array([1, 2, 3], dtype=np.float64)
print(f"float32内存:{arr1.nbytes}字节") # 12
print(f"float64内存:{arr2.nbytes}字节") # 24


2、数组索引与切片

2.1 一维数组索引基础

NumPy数组的索引方式与 Python 列表类似,但功能强大。索引基础规则:

  • 正向索引:从0开始,a[0] 是第一个元素
  • 负向索引:从-1开始,a[-1] 是最后一个元素
  • 切片:a[start:stop:step],遵循左闭右开原则

a = np.arange(10) # 创建 [0 1 2 3 4 5 6 7 8 9]
print(f"原数组:{a}")

# 正向索引
print(f"a[0] = {a[0]}") # 0
print(f"a[5] = {a[5]}") # 5

# 负向索引
print(f"a[-1] = {a[-1]}") # 9
print(f"a[-3] = {a[-3]}") # 7

# 切片操作
print(f"a[2:7] = {a[2:7]}") # [2 3 4 5 6] – 第3到第7个元素
print(f"a[:5] = {a[:5]}") # [0 1 2 3 4] – 从头到第5个
print(f"a[5:] = {a[5:]}") # [5 6 7 8 9] – 从第6个到末尾

# 步长切片
print(f"a[::2] = {a[::2]}") # [0 2 4 6 8] – 步长2
print(f"a[::3] = {a[::3]}") # [0 3 6 9] – 步长3
print(f"a[::-1] = {a[::-1]}") # [9 8 7 6 5 4 3 2 1 0] – 完全反转

2.2 二维数组索引

二维数组的索引需要同时指定行和列,语法为 array[row, col]:

b = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
print(f"原数组:\\n{b}")

# 单个元素索引
print(f"b[1, 2] = {b[1, 2]}") # 6 – 第2行第3列

# 行索引
print(f"b[0, :] = {b[0, :]}") # [1 2 3] – 第1行所有列
print(f"b[1] = {b[1]}") # [4 5 6] – 第2行(省略写法)

# 列索引
print(f"b[:, 1] = {b[:, 1]}") # [2 5 8] – 第2列所有行

# 子矩阵切片
print(f"b[0:2, 0:2] = \\n{b[0:2, 0:2]}")
# [[1 2]
# [4 5]]

# 跳行跳列
print(f"b[::2, ::2] = \\n{b[::2, ::2]}")
# [[1 3]
# [7 9]]

2.3 布尔索引

布尔索引是 NumPy 里面最强大的特征之一,它允许我们根据条件筛选数组元素:

a = np.array([10, 20, 30, 40, 50])
print(f"原数组:{a}")

# 创建布尔掩码
mask = a > 30
print(f"a > 30 的掩码:{mask}") # [False False False True True]

# 使用掩码筛选
result = a[mask]
print(f"a[a > 30] = {result}") # [40 50]

# 一行写法(最常用)
print(f"a[a > 25] = {a[a > 25]}") # [30 40 50]

💡核心应用场景:在数据分析中,布尔索引用于数据清洗、异常值检测、条件筛选等场景。

实际应用:

# 场景:筛选价格大于150的商品
prices = np.array([99, 199, 299, 399, 149])
print(f"高价商品价格:{prices[prices > 150]}") # [199 299 399]

# 场景:筛选成绩及格的学生
scores = np.array([45, 78, 92, 63, 88, 55, 76])
print(f"及格成绩:{scores[scores >= 60]}") # [78 92 63 88 76]

# 复合条件
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

# 找出大于3且小于8的数
result = a[(a > 3) & (a < 8)]
print(f"大于3且小于8:{result}") # [4 5 6 7]

💡注意:在NumPy中进行复合条件筛选时,必须使用 & (按位与)而不是 and (Python逻辑与),因为NumPy操作的是数组而不是单个值。

2.4 花式索引

花式索引(Fancy Indexing)使用整数数组作为索引,可以实现任意顺序、任意位置的元素选取:

a = np.arange(10) # [0 1 2 3 4 5 6 7 8 9]

# 使用整数数组指定索引位置
indices = [0, 2, 4, 6]
print(f"a[{indices}] = {a[indices]}") # [0 2 4 6]

# 不按顺序选取
print(f"a[[3, 0, 5]] = {a[[3, 0, 5]]}") # [3 0 5]

# 二维花式索引
b = np.arange(12).reshape(3, 4)
print(f"原数组:\\n{b}")

# 选取特定行
print(f"b[[0, 2], :] = \\n{b[[0, 2], :]}") # 选取第1行和第3行,因为下标从0开始所以是0和2


3、数组运算与聚合

3.1 逐元素运算

NumPy的核心优势之一是支持向量化运算,无需循环即可对数组的每个元素进行数学运算:

a = np.array([1, 2, 3, 4, 5])

# 基本算术运算
print(f"a + 10 = {a + 10}") # [11 12 13 14 15]
print(f"a – 5 = {a – 5}") # [-4 -3 -2 -1 0]
print(f"a * 2 = {a * 2}") # [2 4 6 8 10]
print(f"a / 2 = {a / 2}") # [0.5 1. 1.5 2. 2.5]
print(f"a ** 2 = {a ** 2}") # [1 4 9 16 25]
print(f"a % 2 = {a % 2}") # [1 0 1 0 1] – 取模

# 比较运算(布尔索引)
print(f"a > 3 = {a > 3}") # [False False False True True]
print(f"a == 3 = {a == 3}") # [False False True False False]

💡向量化优势:使用向量化运算比Python循环快10-100倍,因为NumPy在底层使用了SIMD指令集优化。

3.2 数组间运算

两个形状相同的数组可以进行逐元素运算:

a = np.array([1, 2, 3, 4])
b = np.array([10, 20, 30, 40])

print(f"a + b = {a + b}") # [11 22 33 44]
print(f"a * b = {a * b}") # [10 40 90 160]
print(f"b – a = {b – a}") # [9 18 27 36]

3.3 广播机制(Boardcasting)

广播 NumPy 最强大的特征之一,它允许不同形状的数组进行运算:

# 一维数组与二维数组广播
c = np.array([
[1, 2, 3],
[4, 5, 6]
])
d = np.array([10, 20, 30])

print(f"c + d = \\n{c + d}")
# [[11 22 33]
# [14 25 36]]

# 标量与数组广播
print(f"c * 2 = \\n{c * 2}")
# [[2 4 6]
# [8 10 12]]

💡广播规则:当两个数组的形状不同时,NumPy会从后向前比较维度,如果维度相同或其中一个为1,则可以广播。

3.4 聚合函数

NumPy 提供了丰富的聚合函数,用于统计计算:

arr = np.array([1, 2, 3, 4, 5])

# 基本统计
print(f"总和 sum = {arr.sum()}") # 15
print(f"均值 mean = {arr.mean()}") # 3.0

print(f"最大值 max = {arr.max()}") # 5
print(f"最小值 min = {arr.min()}") # 1

print(f"标准差 std = {arr.std():.4f}") # 1.4142
print(f"方差 var = {arr.var():.4f}") # 2.0000

# 累积函数
print(f"累加 cumsum = {arr.cumsum()}") # [1 3 6 10 15]
print(f"累乘 cumprod= {arr.cumprod()}") # [1 2 6 24 120]

3.5 多维数组聚合(轴向)

对于多维数组,可以通过指定 axis 参数沿特定轴进行聚合:

m = np.arange(12).reshape(3, 4)
print(f"原数组:\\n{m}")

# 按列聚合(axis=0)
print(f"每列求和 (axis=0):{m.sum(axis=0)}") #[12 15 18 21]

# 按行聚合(axis=1)
print(f"每行求和 (axis=1):{m.sum(axis=1)}") # [ 6 22 38]

# 其他轴向聚合
print(f"每列最大值:{m.max(axis=0)}") # [ 8 9 10 11]
print(f"每行平均值:{m.mean(axis=1)}") # [1.5 5.5 9.5]

💡参数提示:axis=1表示行,axis=0表示列

赞(0)
未经允许不得转载:网硕互联帮助中心 » 机器学习之Numpy(Machine Learning about Numpy)
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!