最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
NumPy数组创建完全指南:从零搭建你的数字积木城
时间:2026-06-03 08:30:01 编辑:袖梨 来源:一聚教程网
在机器学习实践过程中,NumPy是一个绕不开的基础工具,它提供了高效的数组运算能力,是进行数据处理的必备技能。本指南将详细介绍如何从零开始创建NumPy数组,涵盖多种创建方式与实用技巧,帮助你快速掌握这一核心强项。
NumPy数组创建完全指南:从零搭建你的数字积木城
为什么要学NumPy?
将机器学习比作一场冒险旅行,那么NumPy就是出发前必须掌握的基础技能课程,其重要性不言而喻。

在处理Python数据时,你很可能见过这一行类似“神咒”的代码:
import numpy as np
如此受推崇的原因可以总结为两点:速度快和操作简。
- 向量化运算:告别繁复的for循环,用一行代码完成以前十行的工作。
- 广播机制:形状不同的数组也能直接进行运算,这是原生Python列表无法做到的。
本文将带你从数组创建到变形运算,系统性地打牢NumPy基础——地基稳固,后续学习才能从容不迫。
一、np.array:从列表到数组,一步之遥
最直接的方式,就是将Python列表作为参数传入:
arr = np.array([1, 2, 3])
print(arr) # [1 2 3]
可能会有人问,Python列表[1, 2, 3]也能用,为什么需要多此一举?
因为它们本质上是不同的数据类型:
| Python列表 | NumPy数组 | |
|---|---|---|
| 类型 | 可以容纳多种类型,例如int、str、dict可以混装 | 类型统一,一个数组只能包含一种数据类型 |
| 运算 | [1,2]+[3,4] 结果为 [1,2,3,4](拼接操作) | np.array([1,2])+np.array([3,4]) 结果为 [4 6](逐元素相加) |
| 速度 | 依赖于循环处理,速度较慢 | 底层采用C语言实现,计算速度极快 |
# Python列表:+ 代表拼接
[1, 2, 3] + [4, 5, 6] # [1, 2, 3, 4, 5, 6]# NumPy数组:+ 代表数学运算
np.array([1, 2, 3]) + np.array([4, 5, 6]) # [5 7 9]
简单来说,列表侧重于“存储数据”,而数组侧重于“运算数据”。两者功能不同,不能混淆使用。
二、嵌套列表:给积木加个维度
一维数组像一条线,二维数组像一张表,三维数组则像一个立体箱子。通过嵌套列表可以逐层构建更高维度的结构:
list1 = [list(range(i, i+3)) for i in [2, 4, 6]]
print(list1)
# [[2, 3, 4], [6, 7, 8], [10, 11, 12]]c = np.array([range(i, i+3) for i in [2, 4, 6]])
print(c)
# [[ 2 3 4]
# [ 6 7 8]
# [10 11 12]]
每一层嵌套的列表就相当于结构的一个层级,层层叠加就能形成立体化的数据组织方式,其原理非常直观。
三、快速创建:NumPy的"模板工厂"
有些数组不需要手动逐一填充数值——全零、全一、等差数列等,NumPy已经预先准备好了相应的创建函数。
np.zeros:全0数组
nz = np.zeros(10, dtype=int)
print(nz) # [0 0 0 0 0 0 0 0 0 0]
这行代码生成了十个零,排列整齐。指定dtype=int可以确保输出整数类型而非浮点数。
np.ones:全1数组
no = np.ones((3, 5))
print(no)
# [[1. 1. 1. 1. 1.]
# [1. 1. 1. 1. 1.]
# [1. 1. 1. 1. 1.]]
生成一个3行5列的全一数组,默认数据类型是浮点型(1.而非1)。如果需要整数,可以添加dtype=int参数。
np.arange:等差数列
该函数与Python内置的range功能相似,但直接返回NumPy数组:
na = np.arange(0, 20, 2)
print(na) # [ 0 2 4 6 8 10 12 14 16 18]
对比两者:
list(range(0, 20, 2)) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] ← 列表类型
np.arange(0, 20, 2) # [ 0 2 4 6 8 10 12 14 16 18] ← 数组类型
虽然输出外观相似,但底层实现完全不同。一个是Python对象列表,另一个是NumPy的连续内存块。
四、随机数组:开盲盒时间
随机数生成是NumPy中一个有趣的功能——每次生成的结果都可能不同(除非设置了固定的随机种子)。
基础随机
a1 = np.random.random() # 单个[0,1)区间的随机浮点数
a2 = np.random.random(1) # 包含一个元素的数组
a3 = np.random.random((3, 3)) # 生成3×3的随机数组
a4 = np.random.random((2, 3, 4)) # 生成2层×3行×4列的三维随机数组
指定范围
a5 = np.random.uniform(5, 7, (2, 2)) # [5,7)区间内的随机浮点数,2×2大小
a6 = np.random.randint(5, 7, (2, 2)) # [5,7)区间内的随机整数,2×2大小
uniform函数负责生成浮点随机数,randint负责生成整数随机数,它们的参数格式保持一致。
正态分布
正态分布的核心特点是:多数数据集中在均值附近,向两侧延伸则逐渐稀疏。人的身高、考试成绩、测量误差等许多自然现象都近似服从这个分布。
# 均值为0,标准差为1,生成3×3的正态分布随机数组
np.random.normal(0, 1, (3, 3))# 简化版:标准正态分布
np.random.randn(3, 3)
种子:给随机数写剧本
计算机生成的随机数实际上是“伪随机”——由特定算法按固定规则计算得出。设置种子可以将计算规则固定下来,保证每次运行得到完全相同的结果。
np.random.seed(0)
a = np.random.random(3)
print(a) # 每次运行都会输出相同的值
何时需要设置种子?在代码调试阶段。如果你的程序出现错误,需要复现问题来分析原因,就必须确保输入数据不变。种子机制就像游戏的“存档点”,帮助你在相同的条件下重复实验。
五、特殊数组:预制件
np.eye:单位矩阵
ne = np.eye(3)
print(ne)
# [[1. 0. 0.]
# [0. 1. 0.]
# [0. 0. 1.]]
主对角线上的元素为1,其余位置均为0。在线性代数中,单位矩阵是“乘法单位元”——任何矩阵与其相乘,结果保持不变。
np.empty:未初始化的数组
ney = np.empty(3)
print(ney) # 输出的值是内存中的残留数据,不确定
使用np.empty就像打开一个未知内容的盒子——你无法预知里面会有什么数值。但它的创建速度极快,因为它跳过了初始化步骤,适合用于后期会逐个赋值的场景。
六、数组属性:读懂你的积木
数组创建后,如何了解其结构?可以通过查看其属性:
x = np.random.randint(10, size=(3, 4, 5)) # 3层×4行×5列
| 属性 | 含义 | 本例值 |
|---|---|---|
ndim | 维度数量 | 3 |
shape | 每个维度的大小 | (3, 4, 5) |
size | 元素总个数 | 60 |
dtype | 数据类型 | int64 |
itemsize | 单个元素占用的字节数 | 8 |
nbytes | 占用的总字节数 | 480 |
print('维度:', x.ndim) # 3
print('形状:', x.shape) # (3, 4, 5)
print('大小:', x.size) # 60
print('类型:', x.dtype) # int64
需要记住的关系式:nbytes = itemsize × size。
七、切片:精准取值,小心副作用
切片是NumPy最常用的操作之一,但有一个需要特别注意的地方:切片返回的是视图,而非数据的副本。
x = np.array([[3, 5, 2, 4],
[7, 6, 8, 8],
[1, 6, 7, 7]])x_sub = x[:2, :2] # 选取前两行、前两列
print(x_sub)
# [[3 5]
# [7 6]]
视图的含义是:当你修改切片的数据时,原数组中的数据也会随之改变。
x_sub[0, :] = 9
print(x_sub) # [[9 9] [7 6]]
print(x) # 原数组也被同步修改了!
# [[9 9 2 4]
# [9 9 8 8]
# [1 6 7 7]]
这就像你透过窗户观察房间——你在窗外摆放了一个花瓶,发现房间内也凭空多了一个。
如果需要独立操作切片数据,应该使用.copy()方法:
x_sub_copy = x[:2, :2].copy()
x_sub_copy[0, :] = 1
print(x) # 原数组不受影响
print(x_sub_copy) # 副本独立变化
这相当于给原数据拍了一张照片,对照片的修改不会影响真实的场景。
八、变形:reshape与newaxis
reshape:改变形状,不改内容
grid = np.arange(1, 10) # [1 2 3 4 5 6 7 8 9]
grid_reshape = grid.reshape((3, 3))
print(grid_reshape)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
9个元素可以重新排列成3×3的矩阵,但无法变成4×3——因为元素总数必须保持不变。
np.newaxis:增加一个维度
将一维数组转换为二维数组,本质是通过None插入一个长度为1的新维度:
x = np.array([1, 2, 3, 4, 5])# 变成一行(1×5)
x.reshape(1, 5) # [[1 2 3 4 5]]
x[np.newaxis, :] # 效果相同# 变成一列(5×1)
x.reshape(5, 1) # [[1] [2] [3] [4] [5]]
x[:, np.newaxis] # 效果相同
何时需要使用?当进行矩阵运算需要维度对齐的时候。例如,一个形状为(5,)的向量需要与一个形状为(3,5)的矩阵进行运算,首先需要将向量变为(1,5)的二维形状。
九、拼接与分裂:合体与分身
拼接:多个变一个
x = np.array([1, 2, 3])
y = np.array([3, 2, 1])
z = np.array([99, 99, 99])# 一维数组拼接
np.concatenate([x, y, z]) # [ 1 2 3 3 2 1 99 99 99]
二维数组则需要指定拼接方向:
grid = np.array([[1, 2, 3],
[4, 5, 6]])# axis=0:沿行方向上下堆叠
np.concatenate([grid, grid])
# [[1 2 3]
# [4 5 6]
# [1 2 3]
# [4 5 6]]# axis=1:沿列方向左右拼接
np.concatenate([grid, grid], axis=1)
# [[1 2 3 1 2 3]
# [4 5 6 4 5 6]]
NumPy还提供了两个快捷函数:
np.vstack([x, y, z, grid]) # 垂直堆叠,等价于axis=0
np.hstack([grid, grid]) # 水平堆叠,等价于axis=1
分裂:一个变多个
x = [0, 1, 2, 3, 4, 5, 6, 7, 8]
x1, x2, x3 = np.split(x, [3, 5])
print(x1, x2, x3) # [0 1 2] [3 4] [5 6 7 8]
分裂规则:np.split(数组, [断点位置列表]),设定N个断点可以分割出N+1个子数组。
二维数组的分裂:
grid = np.arange(16).reshape(4, 4)# 垂直分割:按行划分
upper, lower = np.vsplit(grid, [2])# 水平分割:按列划分
left, right = np.hsplit(grid, [1])
十、通用函数:向量化的魔法
NumPy的运算允许直接对整个数组进行操作,无需编写for循环——这就是向量化的核心优势。
x = np.arange(4)
print('x =', x)
print('x + 5 =', x + 5) # [5 6 7 8]
print('x - 5 =', x - 5) # [-5 -4 -3 -2]
print('x * 2 =', x * 2) # [0 2 4 6]
print('x / 2 =', x / 2) # [0. 0.5 1. 1.5]
print('x // 2 =', x // 2) # [0 0 1 1] 整除取商
print('x % 2 =', x % 2) # [0 1 0 1] 余数
print('x ** 2 =', x ** 2) # [0 1 4 9] 幂运算
print('-x =', -x) # [0 -1 -2 -3]
每种运算都有对应的函数形式:np.add、np.subtract、np.multiply、np.divide、np.power……
绝对值
x = np.array([-2, -1, 0, 1, 2])
print(np.abs(x)) # [2 1 0 1 2]
print(np.absolute(x)) # 效果相同
复数的模
y = np.array([3 - 4j, 4 - 3j, 2 + 0j, 0 + 1j])
print(abs(y)) # [5. 5. 2. 1.]
对复数取绝对值,返回的是其模长——即实部与虚部的平方和再开根号。例如3-4j的模就是√(9+16)=5。
写在最后
回顾一下今天搭建的“积木”知识体系:
- 基础创建:
np.array实现从列表到数组的快速转换,zeros/ones/arange用于快速生成标准模板 - 随机数组:
random、uniform、normal各有不同用途,seed是调试过程中的“存档点” - 变形与操作:
reshape改变数组形状、切片返回数据视图、拼接分裂实现数据组合 - 向量化运算:告别
for循环,用单行代码完成批量计算
数组创建是 NumPy 学习道路的起点,而非终点。你可以将上面的速查表收藏备用,接下来可以继续探索以下内容:
- 索引与切片进阶 — 包括花式索引、布尔索引等高级技巧
- 广播机制 — 不同形状数组进行对齐运算的原理
- 线性代数 — 矩阵乘法、特征值分解等线性代数操作
- 实战项目 — 运用 NumPy 进行图像处理、数据分析等实际应用
速查表
| 场景 | 函数 | 一句话说明 |
|---|---|---|
| 从列表创建 | np.array() | 最基础的创建方式,可接受任意嵌套列表 |
| 全零 | np.zeros() | 用于初始化占位 |
| 全一 | np.ones() | 同上 |
| 等差数列 | np.arange() | 类似range函数,但直接返回数组 |
| 随机浮点 | np.random.random() | [0,1)区间内 |
| 指定范围随机 | np.random.uniform() | 自定义数值区间 |
| 随机整数 | np.random.randint() | 整数版本 |
| 正态分布 | np.random.normal() | 高斯分布 |
| 固定种子 | np.random.seed() | 使随机结果可重现 |
| 单位矩阵 | np.eye() | 对角线为1,其余为0 |
| 未初始化 | np.empty() | 创建速度快,但值不确定 |
| 变形 | reshape | 改变形状但不改变数据内容 |
| 加维度 | np.newaxis | 将一维数组变为二维 |
| 拼接 | concatenate/vstack/hstack | 多个数组合并为一个 |
| 分裂 | split/vsplit/hsplit | 一个数组分割为多个 |
经过本次学习,你已经掌握了 NumPy 数组创建的核心技巧,可以在此基础上进行更深入的数据分析工作。
相关文章
- 扫福必得敬业福的福字图片 06-18
- 2026年DeepSeek使用要点:账号、权限与入口说明 06-18
- DeepSeek响应缓慢:网络环境与模型配置排查说明 06-18
- 容易能扫出敬业福福字图片大全-2026必出敬业福福字图最新 06-18
- 2026年Grok收费吗?免费版与会员订阅功能差异说明 06-18
- Kimi内容生成版权风险:使用场景与合规要点说明 06-18