3.2.2 数组基础

- 掌握多种数组创建方式
- 理解数组的核心属性(shape、dtype、ndim、size)
- 了解 NumPy 的数据类型系统
- 掌握数组的数据类型转换
从 Python 列表创建
Section titled “从 Python 列表创建”最基本的方式是用 np.array() 把 Python 列表转成 NumPy 数组:
import numpy as np
# 一维数组a = np.array([1, 2, 3, 4, 5])print(a) # [1 2 3 4 5]print(type(a)) # <class 'numpy.ndarray'>
# 二维数组(矩阵)b = np.array([ [1, 2, 3], [4, 5, 6]])print(b)# [[1 2 3]# [4 5 6]]
# 三维数组c = np.array([ [[1, 2], [3, 4]], [[5, 6], [7, 8]]])print(c.shape) # (2, 2, 2)快捷创建函数
Section titled “快捷创建函数”NumPy 提供了大量快速创建数组的函数,不需要你手写每个元素:
import numpy as np
# ========== 全 0 / 全 1 数组 ==========zeros_1d = np.zeros(5)print(zeros_1d) # [0. 0. 0. 0. 0.]
zeros_2d = np.zeros((3, 4)) # 3 行 4 列print(zeros_2d)# [[0. 0. 0. 0.]# [0. 0. 0. 0.]# [0. 0. 0. 0.]]
ones_2d = np.ones((2, 3)) # 2 行 3 列print(ones_2d)# [[1. 1. 1.]# [1. 1. 1.]]
# ========== 填充指定值 ==========fives = np.full((2, 3), 5) # 全部填充 5print(fives)# [[5 5 5]# [5 5 5]]
# ========== 单位矩阵 ==========eye = np.eye(3) # 3×3 单位矩阵print(eye)# [[1. 0. 0.]# [0. 1. 0.]# [0. 0. 1.]]等差数列:arange 和 linspace
Section titled “等差数列:arange 和 linspace”# arange:类似 Python 的 range,但返回 NumPy 数组a = np.arange(10) # 0 到 9print(a) # [0 1 2 3 4 5 6 7 8 9]
b = np.arange(2, 10, 2) # 从 2 开始,到 10(不含),步长 2print(b) # [2 4 6 8]
c = np.arange(0, 1, 0.2) # 支持小数步长!(range 不支持)print(c) # [0. 0.2 0.4 0.6 0.8]
# linspace:指定个数,自动计算步长d = np.linspace(0, 10, 5) # 从 0 到 10(含),均匀取 5 个点print(d) # [ 0. 2.5 5. 7.5 10. ]
e = np.linspace(0, 1, 11) # 0 到 1 之间取 11 个点print(e) # [0. 0.1 0.2 ... 0.9 1. ]创建随机数组
Section titled “创建随机数组”# 新 NumPy 代码优先使用 default_rng()rng = np.random.default_rng(seed=42)
# 0~1 之间的均匀分布随机数rand = rng.random((3, 4)) # 3×4print(rand)
# 标准正态分布随机数(均值0,标准差1)randn = rng.standard_normal((3, 4)) # 3×4
# 指定范围的随机整数randint = rng.integers(1, 100, size=(3, 4)) # 1~99 之间的 3×4 整数print(randint)创建方法速查表
Section titled “创建方法速查表”| 函数 | 作用 | 示例 |
|---|---|---|
np.array() | 从列表创建 | np.array([1, 2, 3]) |
np.zeros() | 全 0 数组 | np.zeros((3, 4)) |
np.ones() | 全 1 数组 | np.ones((2, 3)) |
np.full() | 填充指定值 | np.full((2, 3), 7) |
np.eye() | 单位矩阵 | np.eye(4) |
np.arange() | 等差数列(指定步长) | np.arange(0, 10, 2) |
np.linspace() | 等差数列(指定个数) | np.linspace(0, 1, 100) |
rng.random() | 均匀随机数 [0, 1) | rng.random((3, 4)) |
rng.standard_normal() | 标准正态分布 | rng.standard_normal((3, 4)) |
rng.integers() | 随机整数 | rng.integers(0, 10, size=(3, 4)) |
每个 NumPy 数组都有一些重要属性,了解它们是后续操作的基础:
import numpy as np
arr = np.array([ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
print(f"形状 (shape): {arr.shape}") # (3, 4) → 3 行 4 列print(f"维度 (ndim): {arr.ndim}") # 2 → 二维数组print(f"元素总数 (size): {arr.size}") # 12 → 3 × 4 = 12print(f"数据类型 (dtype): {arr.dtype}") # int64print(f"每个元素字节数: {arr.itemsize}") # 8 → int64 占 8 字节print(f"总字节数: {arr.nbytes}") # 96 → 12 × 8 = 96shape 的含义
Section titled “shape 的含义”shape 是最常用的属性,它告诉你数组的”形状”:
# 一维数组a = np.array([1, 2, 3])print(a.shape) # (3,) → 3 个元素
# 二维数组b = np.array([[1, 2, 3], [4, 5, 6]])print(b.shape) # (2, 3) → 2 行 3 列
# 三维数组c = np.ones((2, 3, 4))print(c.shape) # (2, 3, 4) → 2 个 "3行4列的矩阵"理解 shape 的方式:从外到内,逐层数。
三维数组 shape = (2, 3, 4) ↓ ↓ ↓ │ │ └── 最内层:每行 4 个元素 │ └───── 中间层:每个矩阵 3 行 └──────── 最外层:共 2 个矩阵数据类型(dtype)
Section titled “数据类型(dtype)”NumPy 数组中所有元素必须是同一类型。这也是它能快速运算的关键。
常用数据类型
Section titled “常用数据类型”| dtype | 含义 | 示例值 | 常见场景 |
|---|---|---|---|
int32 | 32位整数 | -2147483648 ~ 2147483647 | 计数、索引 |
int64 | 64位整数(默认) | 更大范围 | 通用整数 |
float32 | 32位浮点数 | 约7位有效数字 | 深度学习(节省显存) |
float64 | 64位浮点数(默认) | 约15位有效数字 | 科学计算(高精度) |
bool | 布尔值 | True / False | 条件过滤 |
str_ | 字符串 | ”hello” | 文本标签(少用) |
指定数据类型
Section titled “指定数据类型”# 自动推断类型a = np.array([1, 2, 3]) # int64(全是整数)b = np.array([1.0, 2.0, 3.0]) # float64(有小数点)c = np.array([1, 2.5, 3]) # float64(混合时自动向上转)
# 手动指定类型d = np.array([1, 2, 3], dtype=np.float32)print(d) # [1. 2. 3.]print(d.dtype) # float32
e = np.zeros(5, dtype=np.int32)print(e) # [0 0 0 0 0]print(e.dtype) # int32类型转换:astype
Section titled “类型转换:astype”# 整数转浮点数int_arr = np.array([1, 2, 3, 4])float_arr = int_arr.astype(np.float64)print(float_arr) # [1. 2. 3. 4.]print(float_arr.dtype) # float64
# 浮点数转整数(直接截断,不是四舍五入!)float_arr2 = np.array([1.7, 2.3, 3.9])int_arr2 = float_arr2.astype(np.int32)print(int_arr2) # [1 2 3] ← 注意:3.9 变成了 3,不是 4!
# 布尔转换bool_arr = np.array([0, 1, 0, 2, -1]).astype(bool)print(bool_arr) # [False True False True True] ← 0 是 False,非 0 是 Truefloat32 vs float64:什么时候用哪个?
Section titled “float32 vs float64:什么时候用哪个?”# float64:默认,精度高a = np.array([1.0, 2.0, 3.0]) # 默认 float64,每个元素 8 字节
# float32:省内存,深度学习常用b = np.array([1.0, 2.0, 3.0], dtype=np.float32) # 每个元素 4 字节
# 内存对比rng = np.random.default_rng(seed=42)big_f64 = rng.random(1_000_000) # float64big_f32 = rng.random(1_000_000).astype(np.float32) # float32print(f"float64 占内存: {big_f64.nbytes / 1024 / 1024:.1f} MB") # 7.6 MBprint(f"float32 占内存: {big_f32.nbytes / 1024 / 1024:.1f} MB") # 3.8 MB从已有数组创建
Section titled “从已有数组创建”有时候你需要基于已有数组的形状创建新数组:
original = np.array([[1, 2, 3], [4, 5, 6]])
# 创建和 original 形状相同的全 0 数组z = np.zeros_like(original)print(z)# [[0 0 0]# [0 0 0]]
# 创建和 original 形状相同的全 1 数组o = np.ones_like(original)print(o)# [[1 1 1]# [1 1 1]]
# 创建和 original 形状相同的指定值数组f = np.full_like(original, 99)print(f)# [[99 99 99]# [99 99 99]]
# 创建未初始化的数组(快但值随机)e = np.empty_like(original)# ⚠️ 值是随机的,不要直接使用未赋值的 empty 数组!学完这一页,至少保留这张证据卡:
- 数组状态
- 操作前的形状、dtype、轴和样本值
- 操作
- 索引、切片、广播、reshape、线性代数,或随机/统计函数
- 输出
- 结果数组形状、值,或统计量
- 失败检查
- 轴混淆、视图/副本陷阱、广播不匹配或形状错误
- 期望产出
- 打印的形状和值,便于检查数组运算
root((NumPy 数组基础)) 创建数组 np.array 从列表创建 np.zeros / ones / full np.arange / linspace rng.random / standard_normal / integers np.eye 单位矩阵 数组属性 shape 形状 ndim 维度 size 元素总数 dtype 数据类型 数据类型 int32 / int64 float32 / float64 bool astype 类型转换练习 1:创建各种数组
Section titled “练习 1:创建各种数组”import numpy as np
# 1. 创建一个包含 1 到 20 的一维数组arr1 = np.arange(1, 21)
# 2. 创建一个 4×5 的全零矩阵arr2 = np.zeros((4, 5))
# 3. 创建一个 3×3 的矩阵,所有元素为 7arr3 = np.full((3, 3), 7)
# 4. 创建一个从 0 到 2π (np.pi * 2) 之间均匀分布的 100 个点arr4 = np.linspace(0, np.pi * 2, 100)
# 5. 创建一个 5×5 的随机整数矩阵(范围 1~50)rng = np.random.default_rng(seed=42)arr5 = rng.integers(1, 51, size=(5, 5))练习 2:属性查看
Section titled “练习 2:属性查看”创建一个 shape 为 (3, 4, 5) 的全 1 数组,回答以下问题:
- 它的维度(ndim)是多少?
- 它有多少个元素(size)?
- 默认的 dtype 是什么?
- 把它转换成 int32 类型后,每个元素占多少字节?
练习 3:类型转换
Section titled “练习 3:类型转换”# 给定考试成绩(浮点数)scores = np.array([85.6, 92.3, 78.8, 95.1, 60.5, 73.9])
# 1. 把成绩四舍五入到整数rounded = np.rint(scores).astype(int)
# 2. 判断每个成绩是否及格(>= 60),得到布尔数组passed = scores >= 60
# 3. 计算及格人数(提示:True 算 1,False 算 0)pass_count = passed.sum()参考实现与讲解
- 形状检查应当是
arr1.shape == (20,)、arr2.shape == (4, 5)、arr3.shape == (3, 3)、arr4.shape == (100,)、arr5.shape == (5, 5)。 np.ones((3, 4, 5))是 3 维数组,共 60 个元素。没有指定 dtype 时,NumPy 通常使用float64;int32数组的itemsize是 4 字节。- 成绩数组可以用四舍五入得到更像整数的展示结果,但及格人数要按原始规则计算,例如
scores >= 60,所以60.5应当算及格。