Python Numpy库基础用法与数组操作详解

Luna
Luna
发布时间:2026-10-13 | 6人浏览过
原创

本文详细介绍Python Numpy库的核心用法。涵盖ndarray对象的属性获取、多种数组创建方式(如array、zeros、arange)、矩阵算术与通函数运算,以及多维数组的索引、切片、维度重塑、合并拆分和复制机制,帮助开发者高效处理科学计算数据。

本文详细介绍Python Numpy库的核心用法与常见操作,供读者参考学习。

1、简介

Numpy是Python中广泛使用的科学计算库,支持对数组进行快速处理,包括形状变换、排序、选择、输入输出、离散傅立叶变换、基础线性代数、统计运算及随机模拟等功能。许多Python库和科学计算软件包均以Numpy数组为操作对象,或将传入的Python数组转换为Numpy数组,因此在Python中进行数据处理时,Numpy不可或缺。

Numpy的核心是ndarray对象,它基于Python的n维数组封装,但通过C语言预编译优化了数组操作,从而比原生Python具有更高的执行效率,同时仍使用Python语言进行编码,兼顾了代码简洁性与运行速度。需注意ndarray与Python原生数组的区别:Numpy数组中的元素类型必须相同,且在创建时确定固定大小,而Python数组对象支持动态增长。

2、数组对象

2.1、属性

Numpy对象表现为同构多维数组,数组的维度称为轴(axis),每个维度上的元素个数称为轴的长度。例如,一个2×3的二维数组arr,其第一轴长度为3,第二轴长度为2。


arr = [[ 1., 0., 0.],
    [ 0., 1., 2.]]

arr数组对象常用的属性如下:


# 数组轴的个数
arr.ndim
# 数组维度及长度,例如2×3的数组其shape为(2, 3)
arr.shape
# 数组元素的总个数
arr.size
# 数组中元素的数据类型
arr.dtype
# 数组中元素所占字节数
arr.itemsize

2.2、创建数组

可通过array()方法包裹普通Python数组将其转化为Numpy数组,并通过dtype=指定元素的数据类型。数组可以是二维或多维数组,也可以是元组形式。

若需填充已知大小的数组,可使用zeros()函数将所有元素填充为0,或使用ones()函数填充为1,empty()函数则填充为随机数。

arange(a,b,c)函数用于从a到b每隔c长度生成一个数组元素。linspace(a,b,c)函数用于在a到b之间生成c个等间距的数组元素。


# 普通数组转化为numpy数组
a1 = np.array([2, 3, 4], dtype=float)
print(a1)                  
# 将元组数组转化为二维numpy数组
a2 = np.array([(1, 2, 3), (3, 4, 5)])
print(a2)
# 将3×3的数组用1填充
a3 = np.ones((3, 3))
print(a3)
# 从1到10,每隔2生成一个元素
a4 = np.arange(1, 10, 2)
print(a4)
# 在1到12之间生成4个元素
a5 = np.linspace(1, 12, 4, dtype=int)
print(a5)
 
'''
普通数组转化为numpy对象:
[2. 3. 4.]
元组数组:
[[1 2 3]
 [3 4 5]]
用1填充数组:
[[1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]
从1到10每隔2生成一个元素:
[1 3 5 7 9]
在1到12之间生成4个元素:
[ 1 4 8 12]
'''

2.3、数组操作

算术运算符可直接应用于矩阵,结果是将运算应用到每个元素上。例如,矩阵A*B表示每个元素对应相乘,而矩阵乘法运算使用@符号。


A = np.array([[1, 1],
       [0, 1]])
B = np.array([[2, 0],
       [3, 4]])
print(A * B)
print(A @ B)
 
'''
矩阵元素对应相乘:
[[2 0]
 [0 4]]
矩阵的乘法:
[[5 4]
 [3 4]]
'''

Numpy中有些函数应用于整个数组,例如求和sum、最大值max、最小值min。若在参数中指定了某个轴,则运算仅应用于该指定轴。

还有一些函数应用于数组中的具体元素,例如求sin、cos、exp、开方sqrt等,这些函数称为通函数(ufunc)。


a = np.array([[0, 1, 2, 3],
       [4, 5, 6, 7],
       [8, 9, 10, 11]])
print(a.max()) # 求整体的最大值,结果为11
print(a.sum(axis=0)) # 求每一列的和,结果为:[12 15 18 21]
print(np.sqrt(a))  # 数组每个元素求开方

Numpy中的数组同Python中的list一样支持索引、切片和迭代操作。数组a[x]代表访问数组a下标为x的元素,一维数组a[x:y]代表访问从x到y的元素,若省略x代表从头开始,省略y代表直到结尾。a[x:y:a]代表从x到y每隔a个元素取一个值,若a为负数,代表逆序取值。


a = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print(a[1:3]) # 输出下标为1到3的元素:[1 2]
print(a[::-2]) # 逆序每隔两个元素选一个值:[9 7 5 3 1]

对于多维数组,索引之间用逗号分隔。可以使用...代表省略某几个维度,若省略则被视为该维度全部输出,例如x[...,3]等效于x[:,:,:,:,3]。

可通过for循环迭代多维数组,其内容为低一维度的子数组。若希望遍历每一个子元素,可使用flat属性。


a = np.array([[0, 1, 2, 3],
       [10, 11, 12, 13],
       [40, 41, 42, 43]])
# 输出a第一维(行)的前三个,第二维(列)下标的1~3
print(a[1:3, 0:3])
# 输出行的所有,下标为2的列
print(a[2, ...])
# 遍历数组
for row in a:
  print(row)
# 遍历每个子元素
for item in a.flat:
  print(item)
 
'''
后两行的1~3列:
[[10 11 12]
 [40 41 42]]
第三行的所有列:
[40 41 42 43]
遍历数组:
[0 1 2 3]
[10 11 12 13]
[40 41 42 43]
遍历每个元素:
0
1
2
......
41
42
43
'''

除使用具体数字作为索引外,还可使用Numpy数组作为索引。例如使用数组i作为一维数组a的索引,输出a[i]。当数组i为多维数组时,从a中选出元素填到i数组的对应位置。


a = np.arange(12) ** 2
print(a)
i = np.array([1, 3, 5])
print(a[i])
# 多维数组索引j
j = np.array([[3, 4], [9, 7]])
print(a[j])
 
'''
[ 0  1  4  9 16 25 36 49 64 81 100 121]
数组a的1、3、5个元素
[ 1 9 25]
通过多为索引j取出a的数据填到对应位置
[[ 9 16]
 [81 49]]
'''

若a是多维数组,索引数组的单个元素代表选中数组a的第一个维度。

若对多维数组在多个维度上进行索引,则传入多个索引数组i,j并用逗号分隔。


a = np.array(([[0, 1, 2, 3],
        [4, 5, 6, 7],
        [8, 9, 10, 11]]))
# 多维数组的单元素索引
i = np.array([0, 1])
print(a[i])
# 对多维数组提供多维度索引,同时提供i,j代表取出a的[0,2]、[1,3]两个元素
j = np.array([2, 3])
print(a[i, j])
'''
选择多维数组a的第0、1两行:
[[0 1 2 3]
 [4 5 6 7]]
a的[0,2]、[1,3]两个元素:
[2 7]
'''

2.4、改变维度

数组的reshape()方法可将原数组重构成目标维度的数组,例如将一个2×6的数组重构为3×4的数组。

数组在重构时不会修改原数组,而是返回修改后的结果数组。

需注意,数组在重构和打印时都是从最右边的维度开始往左进行。例如,下面的3×4数组b,先按行排列4个,然后再换行,排列这样的3行。若为多维,则按这样的行列继续输出。若数组维度为-1,则会自动计算该维度的大小,例如含有12个元素的数组,第二、第三维是3×2,则第一维就是2。

ravel()函数可将数组展成一维数组。


a=np.array([[1,2,3,4,5,6],
      [7,8,9,10,11,12]])
b=a.reshape(3,4)
print(b)
# 多维数组,自动计算
print(a.reshape(-1,3,2))
# 展开数组
flatted = b.ravel()
print(flatted, end=' ')
'''
[[ 1 2 3 4]
 [ 5 6 7 8]
 [ 9 10 11 12]]
2×3×2的多维数组:
[[[ 1 2]
 [ 3 4]
 [ 5 6]]

 [[ 7 8]
 [ 9 10]
 [11 12]]]
展开数组:
[ 1 2 3 4 5 6 7 8 9 10 11 12] 
'''

Numpy的hstack()函数可在水平方向上合并多个数组,vstack()函数可在垂直方向上合并多个数组。

相反地,hsplit()、vsplit()可将数组拆分为指定数量的子数组。


a=np.array([1,2,3])
b=np.array([4,5,6])
# 垂直方向合并
c=np.vstack((a,b))
print(c)
# 水平方向合并
print(np.hstack((a,b)))
# 水平方向拆分
print(np.hsplit(c,3))
'''
垂直堆叠
[[1 2 3]
 [4 5 6]]
水平合并
[1 2 3 4 5 6]
水平拆分为三个1×2的:
[array([[1],
    [4]]), 
array([[2],
    [5]]), 
array([[3],
    [6]])]
'''

2.5、数组的复制

当一个数组对象赋值给一个新变量时,是新开辟一个存储空间还是只是传递一个引用?答案是传递引用。

例如执行语句b=a,只是将引用传给了b,对b执行的操作会直接影响a。查看a、b两个对象的节点id也是一样的。


a = np.array([1, 2, 3])
b = a
# 修改b
b[0] = 0
print(a)
# 输出a、b对象的id
print(id(a), id(b))
 
'''
修改b,a也发生了变化
[0 2 3]
查看二者的id
2290013812656 2290013812656
'''

通过切片返回数组的视图,修改视图的形状不会影响原数组,但在视图上修改数据原数组也会改变。在执行del a之后,由于c引用了a,a依旧会存在内存中不会被删除。


c = a[:]
# 修改视图的形状
c.shape = 3, 1
print(c, a)
# 修改视图c的数据
c[0] = 1
print(a[0])
 
'''
对视图c的形状做修改,a不会受到影响
[[0]
 [2]
 [3]] [0 2 3]
修改c的数据,a也会随之改变:
1

通过copy()方法可生成数据的副本,因此对副本的操作完全不会影响原数组。


d= a.copy()
d[0]=5
# 修改数组的副本d,a不受影响,输出a:[1 2 3]
print(a)

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python数学运算技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》。

希望本文所述对大家的Python程序设计有所帮助。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表