Python Numpy基础教程:数组创建、属性与广播机制详解
本文详细介绍Python中Numpy库的核心基础。涵盖ndarray对象的创建方式、数据类型定义及shape/size属性;深入解析基于下标、布尔及花式索引的数组访问方法;重点讲解不同形状数组间的广播运算原理与tile函数实现;最后汇总常用的数学、算术及排序函数,帮助开发者高效进行科学计算。
Numpy概述与核心功能
Numpy是Python生态中极为常用的基础库,常与pandas配合用于机器学习数据处理,或与pylab结合进行数据可视化,是标准的技术栈组合。
Numpy
NumPy的官方中文文档地址为:NumPy 中文
NumPy是Python科学计算的基础软件包,其核心功能包括:
- 功能强大的N维数组对象;
- 精密的广播功能函数;
- 集成C/C++和Fortran代码的工具;
- 强大的线性代数、傅立叶变换和随机数处理功能。
简而言之,Numpy可视为Python版的Matlab数学计算包,利用它,Python能够更简单便捷地对矩阵和向量进行计算。
通常,我们在代码中引用该包并简写为np:
import numpy as np
ndarray对象创建与数据类型
Numpy的ndarray对象
ndarray的创建
Numpy中最重要的数据类型是N维数组对象ndarray。它由一系列同类型数据组成,索引从0开始。
该对象具备以下两个主要特点:
- ndarray用于存放同类型元素的多维数组;
- ndarray中的每个元素在内存中占据相同大小的存储区域。
创建一个ndarray对象:
np.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
参数说明:
| 名称 | 描述 |
|---|---|
| object | 数组或嵌套的数列 |
| dtype | 数组元素的数据类型,可选 |
| copy | 对象是否需要复制,可选 |
| order | 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认) |
| subok | 默认返回一个与基类类型一致的数组 |
| ndmin | 指定生成数组的最小维度 |
一般而言,无需记住所有可选参数:
import numpy as np
if __name__ == "__main__":
x = np.array([1, 2, 3])
print(x)
运行该脚本:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py [1 2 3]
除了使用array方法创建ndarray对象外,Numpy还提供了其他几种创建方式:
np.empty(shape, dtype = float, order = 'C') # 指定形状的未初始化数组
np.zeros(shape, dtype = float, order = 'C') # 指定形状的全0数组
np.ones(shape, dtype = None, order = 'C') # 指定形状的全1数组
np.arange(start = 0, stop, step = 1, dtype) # 从起始值到终止值(不包含)时,按步长从范围内创建数组
np.linspace(start, stop, num = 50, endpoint = True, retstep = False, dtype = None) # 从起始值到终止值(默认包含)创建一个等差数组的一维数组
np.logspace(start, stop, num = 50, endpoint = True, base = 10.0, dtype = None) # 从起始值到终止值(默认包含)创建一个等比数组的一维数组
Numpy也支持从Python其他类型直接转换为ndarray:
np.asarray(a, dtype = None, order = None) # 列表形式
np.frombuffer(buffer, dtype = float, count = -1, offset = 0) # 以流的形式读入
np.fromiter(iterable, dtype, count=-1) # 从可迭代对象中,以迭代器的形式读入
例如:
import numpy as np
if __name__ == "__main__":
a = [[1, 2 ,3], [4, 5]]
b = 'Hello World'
c = iter(range(5))
x = np.asarray(a)
y = np.frombuffer(b, dtype = 'S1')
z = np.fromiter(c, dtype = float)
print(x)
print(y)
print(z)
运行该脚本:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py [list([1, 2, 3]) list([4, 5])] ['H' 'e' 'l' 'l' 'o' ' ' 'W' 'o' 'r' 'l' 'd'] [0. 1. 2. 3. 4.]
ndarray的数据结构
Numpy支持多种数据类型,以下列举部分常见类型:
| 名称 | 描述 |
|---|---|
| bool_ | 布尔型数据类型(True或者False) |
| int_/int8/int16/int32/int64 | 有符号整数 |
| uint8/uint16/uint32/uint64 | 无符号整数 |
| float_/float16/float32/float64 | 浮点数 |
| complex_/complex64/complex128 | 复数 |
若需自定义数据类型,则需通过dtype来确定:
numpy.dtype(object, align, copy)
参数说明:
| 名称 | 描述 |
|---|---|
| object | 要转换为的数据类型对象 |
| align | 如果为true,填充字段使其类似C的结构体 |
| copy | 复制dtype对象 ,如果为false,则是对内置数据类型对象的引用 |
例如,可以创建一个包含学生信息的对象:
import numpy as np
if __name__ == "__main__":
student = np.dtype([('name', 'S20'), ('age', 'i8'), ('score', 'f4')])
a = np.array([('zhangsan', 18, 80), ('lisi', 19, 85)], dtype=student)
print(a)
运行该脚本:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py [('zhangsan', 18, 80.) ('lisi', 19, 85.)]
ndarray属性与格式变换
ndarray的属性
ndarray有两个常用属性:shape和size。shape表示数组维度,二维数组中即行数和列数;size表示数组元素总个数,二维数组中为行数与列数的乘积。
例如:
import numpy as np
if __name__ == "__main__":
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a.shape)
print(a.size)
运行该脚本:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py (2, 3) 6
ndarray对象提供了两种方式在不改变数据内容的情况下改变数组格式,但两者有所区别:
import numpy as np
if __name__ == "__main__":
a = np.array([[1, 2, 3], [4, 5, 6]])
a.shape = (3, 2) # 直接改变本体
print(a)
b = a.reshape(2, 3) # 本体不改变,将改变后的对象返回
print(b)
运行该脚本:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py [[1 2] [3 4] [5 6]] [[1 2 3] [4 5 6]]
ndarray内容访问与高级索引
ndarray的内容访问
ndarray对象的内容可通过索引或切片访问和修改,操作方式与Python中list的切片操作类似。
ndarray既支持基于下标的切片,也可通过内置的slice函数并设置start、stop及step参数,从原数组中切割出新数组。
例如:
import numpy as np
if __name__ == "__main__":
a = np.arange(10)
b = a[1:7:1]
s = slice(1,7,1)
c = a[s]
print(a)
print(b)
print(c)
运行该脚本:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py [0 1 2 3 4 5 6 7 8 9] [1 2 3 4 5 6] [1 2 3 4 5 6]
对冒号:的解释:
- 若为一维数组,仅放置一个参数如[2],将返回该索引对应的单个元素;若为[2:],表示提取该索引及之后的所有项;若使用两个参数如[2:7],则提取两个索引(不含停止索引)之间的项;
- 若是多维数组,使用,区分不同维数。
例如:
import numpy as np
if __name__ == "__main__":
a = np.arange(25)
a.shape = (5, 5)
b = a[1:4, 2:4]
print(a)
print(b)
运行该脚本:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14] [15 16 17 18 19] [20 21 22 23 24]] [[ 7 8] [12 13] [17 18]]
ndarray除了基于下标切片,还支持高级索引方式,如布尔索引和花式索引。
例如:
import numpy as np
if __name__ == "__main__":
a = np.arange(25)
a.shape = (5, 5)
b = a[a > 6]
c = a[[3, 2, 4]]
print(a)
print(b)
print(c)
运行该脚本:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14] [15 16 17 18 19] [20 21 22 23 24]] [ 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24] [[15 16 17 18 19] [10 11 12 13 14] [20 21 22 23 24]]
其他
判断元素是否为NaN:
np.isnan(...)
Numpy广播机制详解
Numpy的广播
若两个ndarray:a和b形状相同,即满足a.shape==b.shape,则a与b的算术结果为对应位置元素的运算。这要求维数相同,且各维度长度一致。
例如:
import numpy as np
if __name__ == "__main__":
a = np.array([1, 2, 3])
b = np.array([1, 2, 3])
c = a + b
d = a * b
print(c)
print(d)
运行该脚本:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py [2 4 6] [1 4 9]
而,广播是Numpy对不同形状(shape)的ndarray进行数值计算的方式,对ndarray的算术运算通常在相应的元素上进行。
如何确定相应的元素?
虽然广播针对不同形状(shape),但需满足两个条件:列数相同,且其中一个行数为1。在此前提下,每行相同列的元素即为对应元素。
直接看文字可能难以理解,可参考以下例子:
import numpy as np
if __name__ == "__main__":
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
b = np.array([1, 2, 3])
c = a + b
d = a * b
print(c)
print(d)
运行该脚本:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py [[ 2 4 6] [ 5 7 9] [ 8 10 12]] [[ 1 4 9] [ 4 10 18] [ 7 16 27]]
所谓广播即:当列数相同时,行数为1的ndarray会进行扩行操作,新增行的内容与原行内容相同。
扩行可通过tile函数实现:
np.tile(obj, (行, 列)) # 在行上和列上分别重复一定的次数
因此,上文的广播也可通过以下方式替代:
import numpy as np
if __name__ == "__main__":
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
b = np.array([1, 2, 3])
bb = np.tile(b, (3, 1))
c = a + bb
d = a * bb
print(bb)
print(c)
print(d)
运行该脚本:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py [[1 2 3] [1 2 3] [1 2 3]] [[ 2 4 6] [ 5 7 9] [ 8 10 12]] [[ 1 4 9] [ 4 10 18] [ 7 16 27]]
ndarray常用数学与排序函数
ndarray的函数
ndarray提供了多种数学函数、算术函数和排序函数,以便进行各类运算。
ndarray的数学函数,例如:
np.pi # 圆周率
np.sin(obj) # 三角运算
np.cos(obj)
np.tan(obj)
np.arcsin(obj) # 反三角运算
np.arccos(obj)
np.arctan(obj)
np.degrees(obj) # 将弧度值转换为角度值
np.around(obj, decimals) # 返回ndarray每个元素的四舍五入值,decimals为舍入的小数位数,默认为0
np.floor(obj) # 向下取整
np.ceil(obj) # 向上取整
ndarray的算术函数,例如:
np.add(obj1, obj2) # 加减乘除运算,与+-*/效果一致,需要符合广播原则
np.subtract(obj1, obj2)
np.multiply(obj1, obj2)
np.divide(obj1, obj2)
np.mod(obj1, obj2) # 求余数运算
np.reciprocal(obj) # 元素取倒数
np.power(obj1, obj2) # 计算前参数为底,后参数为幂的值
ndarray的排序函数,例如:
np.sort(obj, axis=1, kind='quicksort', order)
参数说明:
| 名称 | 描述 |
|---|---|
| obj | 数组或嵌套的数列 |
| axis | axis=0按列排序,axis=1按行排序 |
| kind | ‘quicksort'、‘mergesort'、‘heapsort' |
| order | 如果数组包含字段,则是要排序的字段 |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













