NumPy数组对象ndarray操作教程
掌握NumPy数组对象ndarray
一、创建NumPy数组
代码 2 - 1:创建一维和二维数组
import numpy as np # 导入NumPy库
arr1 = np.array([1, 2, 3, 4]) # 创建一维数组
print(' 创建的数组为: ', arr1)
# 创建二维数组
arr2 = np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]])
print('创建的数组为:\n', arr2)
代码解析:
import numpy as np
:导入NumPy库,并将其命名为np
,方便后续调用。np.array()
:这是NumPy中用于创建数组的函数,接收一个列表作为参数,列表中的元素会成为数组的元素。对于二维数组,传入的是嵌套列表。
查看数组属性
print('数组维度为:', arr2.shape) # 查看数组结构
print('数组类型为:', arr2.dtype) # 查看数组类型
print('数组元素个数为:', arr2.size) # 查看数组元素个数
print('数组每个元素大小为:', arr2.itemsize) # 查看数组每个元素大小
代码解析:
arr2.shape
:返回一个元组,表示数组的维度,例如二维数组可能返回(行数, 列数)
。arr2.dtype
:返回数组中元素的数据类型。arr2.size
:返回数组中元素的总个数。arr2.itemsize
:返回数组中每个元素的字节大小。
代码 2 - 2:重新设置数组的shape
arr2.shape = 4,3 # 重新设置shape
print('重新设置shape 后的arr2 为:\n', arr2)
代码解析:
- 直接对数组的
shape
属性进行赋值,可以改变数组的形状,前提是新形状的元素总数与原数组元素总数一致。
二、使用NumPy函数创建数组
代码 2 - 3:使用arange函数创建数组
print('使用arange函数创建的数组为:\n', np.arange(0,1,0.1))
代码解析:
np.arange(start, stop, step)
:用于创建一个一维数组,start
是起始值(包含),stop
是终止值(不包含),step
是步长。
代码 2 - 4:使用linspace函数创建数组
print('使用linspace函数创建的数组为:\n', np.linspace(0, 1, 12))
代码解析:
np.linspace(start, stop, num)
:创建一个一维数组,start
是起始值,stop
是终止值,num
是元素个数,生成的数组元素在start
和stop
之间均匀分布。
代码 2 - 5:使用logspace函数创建数组
print('使用logspace函数创建的数组为:\n', np.logspace(0, 2, 20))
代码解析:
np.logspace(start, stop, num)
:创建一个一维数组,数组元素在 1 0 s t a r t 10^{start} 10start到 1 0 s t o p 10^{stop} 10stop之间按对数刻度均匀分布,num
是元素个数。
代码 2 - 6:使用zeros函数创建数组
print('使用zeros函数创建的数组为:\n', np.zeros((2,3)))
代码解析:
np.zeros(shape)
:创建一个指定形状的数组,数组元素都为0,shape
是一个元组,表示数组的维度。
代码 2 - 7:使用eye函数创建数组
print('使用eye函数创建的数组为:\n', np.eye(3))
代码解析:
np.eye(N)
:创建一个 N × N N\times N N×N的单位矩阵,即主对角线元素为1,其余元素为0。
代码 2 - 8:使用diag函数创建数组
print('使用diag函数创建的数组为:\n', np.diag([1,2,3,4]))
代码解析:
np.diag(v)
:以一维数组v
的元素作为主对角线元素,创建一个二维对角矩阵。
代码 2 - 9:使用ones函数创建数组
print('使用ones函数的数组为:\n', np.ones((5,3)))
代码解析:
np.ones(shape)
:创建一个指定形状的数组,数组元素都为1,shape
是一个元组,表示数组的维度。
三、NumPy数组的数据类型转换
代码 2 - 10:数据类型转换
print('转换结果为:', np.float64(42)) # 整型转换为浮点型
print('转换结果为:', np.int8(42.0)) # 浮点型转换为整型
print('转换结果为:', bool(42)) # 整型转换为布尔型
print('转换结果为:', bool(0)) # 整型转换为布尔型
print('转换结果为:', float(True)) # 布尔型转换为浮点型
print('转换结果为:', float(False)) # 布尔型转换为浮点型
代码解析:
np.float64()
、np.int8()
、np.bool()
等函数可以将数据转换为指定的数据类型。
四、自定义NumPy数组的数据类型
代码 2 - 11:定义数据类型
df = np.dtype([('name', np.str_, 40), ('numitems', np.int64),
('price',np.float64)])
print('数据类型为:\n', df)
代码解析:
np.dtype()
:用于定义一个结构化数据类型,接收一个列表作为参数,列表中的每个元素是一个元组,元组包含字段名、数据类型和可选的字段长度。
代码 2 - 12:访问数据类型的字段
print('数据类型为:', df['name'])
print('数据类型为:', np.dtype(df['name']))
代码解析:
- 通过
df['name']
可以访问定义的数据类型中的name
字段。
代码 2 - 13:创建自定义数据类型的数组
itemz = np.array([('tomatoes', 42, 4.14), ('cabbages', 13, 1.72)],
dtype=df)
print('自定义数据为:', itemz)
代码解析:
- 创建数组时,通过
dtype
参数指定自定义的数据类型。
五、生成随机数组
代码 2 - 14:生成随机数组
print('生成的随机数组为:\n', np.random.random(100))
代码解析:
np.random.random(size)
:生成一个指定大小的数组,数组元素是0到1之间的随机浮点数。
代码 2 - 15:生成随机数组
print('生成的随机数组为:\n', np.random.rand(10,5))
代码解析:
np.random.rand(d0, d1, ..., dn)
:生成一个指定形状的数组,数组元素是0到1之间的随机浮点数,d0, d1, ..., dn
表示数组的维度。
代码 2 - 16:生成随机数组
print('生成的随机数组为:\n', np.random.randn(10,5))
代码解析:
np.random.randn(d0, d1, ..., dn)
:生成一个指定形状的数组,数组元素是符合标准正态分布的随机浮点数。
代码 2 - 17:生成随机整数数组
print('生成的随机数组为:\n', np.random.randint(2, 10, size=[2,5]))
代码解析:
np.random.randint(low, high, size)
:生成一个指定形状的数组,数组元素是low
(包含)到high
(不包含)之间的随机整数。
六、NumPy数组的索引和切片
代码 2 - 18:一维数组的索引和切片
import numpy as np
# arr = np.arange(10)
arr = np.array([10, 20, 30, 40,50,60,70,80,90,100])
print('索引结果为:', arr[5]) # 用整数作为下标可以获取数组中的某个元素
# 用范围作为下标获取数组的一个切片,包括arr[3]不包括arr[5]
print('索引结果为:', arr[3:5])
print('索引结果为:', arr[:5]) # 省略开始下标,表示从arr[0]开始
print('索引结果为:', arr[5:]) # 省略开始下标,表示从arr[5]开始
# 下标可以使用负数,-1表示从数组后往前数的第一个元素
print('索引结果为:', arr[-1])
#arr[2:4] = 100,101
print('索引结果为:', arr) # 下标还可以用来修改元素的值
arr[0] = 1000
print('索引结果为:', arr[0]) # 修改单个元素
# 范围中的第三个参数表示步长,2表示隔一个元素取一个元素
print('索引结果为:', arr[1:9:2]) #
print('索引结果为:', arr[1:-1:2]) #-1能直接找到最后一个元素在不知道有多少个元素的情况下
print('索引结果为:', arr[5:1:-2]) # 步长为负数时,开始下标必须大于结束下标
代码解析:
- 对于一维数组,可以使用整数索引获取单个元素,使用范围
start:stop:step
进行切片操作,start
是起始下标(包含),stop
是终止下标(不包含),step
是步长,省略start
表示从0开始,省略step
表示步长为1。
代码 2 - 19:二维数组的索引和切片
arr = np.array([[1, 2, 3, 4, 5],[4, 5, 6, 7, 8], [7, 8, 9, 10, 11]])
print('创建的二维数组为:\n', arr)
print('索引结果为:', arr[0,3:5]) # 索引第0行中第3和第4列的元素
# 索引第2和第3行中第3列、第4列和第5列的元素
print('索引结果为:\n', arr[1:,2:])
print('索引结果为:', arr[:,2]) # 索引第2列的元素
代码解析:
- 对于二维数组,使用
arr[row, col]
的形式进行索引,row
和col
可以是整数、范围或整数数组,用于指定行和列的索引。
代码 2 - 20:使用整数数组进行索引
# 从两个序列的对应位置取出两个整数组成下标:arr[0,1], arr[1,2], arr[2,3]
# 定义一个示例数组
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
# 从两个序列的对应位置取出两个整数组成下标:arr[0,1], arr[1,2], arr[2,3]
print('索引结果为:', arr[[0, 1, 2], [1, 2, 3]])
# 在 numpy 中,可以使用两个数组来进行高级索引。这里 [0, 1, 2] 表示行索引,[1, 2, 3] 表示列索引。
# 程序会从两个数组的对应位置取出元素组成下标,即 (0, 1)、(1, 2)、(2, 3),然后使用这些下标来访问数组 arr 中的元素。
# arr[0, 1] 对应的值是 2,arr[1, 2] 对应的值是 7,arr[2, 3] 对应的值是 12。
# 所以最终输出的结果是 [2 7 12]。
# 索引第2、3行中第0、2、3列的元素
print('索引结果为:', arr[1:, [0, 2, 3]])
# arr[1:] 表示从第 1 行(索引从 0 开始)开始到最后一行的所有行,即取第 2 行和第 3 行。
# [0, 2, 3] 表示列索引,即取第 0 列、第 2 列和第 3 列。
# 因此,这行代码会取出第 2 行和第 3 行中第 0 列、第 2 列和第 3 列的元素,最终输出结果为
mask = np.array([1, 0, 1], dtype=bool)
# mask是一个布尔数组,它索引第1、3行中第2列的元素
print('索引结果为:', arr[mask, 2])
# mask = np.array([1, 0, 1], dtype=bool) 创建了一个布尔数组 mask,其中 True 表示要选择的行,False 表示不选择的行。在布尔类型中,非零值被视为 True,零值被视为 False,所以 mask 数组等价于 [True, False, True]。
# arr[mask, 2] 表示选择 mask 数组中为 True 的行(即第 1 行和第 3 行),并取这些行中第 2 列的元素。
#第 1 行第 2 列的元素是 3,第 3 行第 2 列的元素是 11,所以最终输出结果为 [ 3 11]。
代码解析:
- 可以使用整数数组作为索引,从数组中选取指定位置的元素,也可以使用布尔数组进行索引,布尔数组中为
True
的位置对应的元素会被选取。
七、NumPy数组的形状操作
代码 2 - 21:改变数组的形状
arr = np.arange(12) # 创建一维数组
print('创建的一维数组为:', arr)
print('新的一维数组为:\n', arr.reshape(3, 4)) # 设置数组的形状
print('数组维度为:', arr.reshape(3, 4).ndim) # 查看数组维度
代码解析:
arr.reshape(shape)
:返回一个具有指定形状的新数组,原数组的元素顺序不变。arr.ndim
:返回数组的维度数。
代码 2 - 22:数组展平
arr = np.arange(12).reshape(3, 4)
print('创建的二维数组为:\n', arr)
print('数组展平后为:', arr.ravel())
代码解析:
arr.ravel()
:将多维数组展平为一维数组,返回的是数组的视图,修改视图会影响原数组。
代码 2 - 23:数组展平
print('数组展平为:', arr.flatten()) # 横向展平
print('数组展平为:', arr.flatten('F')) # 纵向展平
代码解析:
arr.flatten(order)
:将多维数组展平为一维数组,返回的是数组的副本,修改副本不会影响原数组,order
参数可以指定展平的顺序,'C'
表示按行优先(默认),'F'
表示按列优先。
八、NumPy数组的组合和分割
代码 2 - 24:数组的横向组合
arr1 = np.arange(12).reshape(3, 4)
print('创建的数组1为:\n', arr1)
arr2 = arr1*3
print('创建的数组2为:\n', arr2)
print('横向组合为:\n', np.hstack((arr1, arr2))) # hstack函数横向组合
代码解析:
np.hstack((arr1, arr2))
:将数组arr1
和arr2
按列方向(横向)进行组合,要求数组的行数相同。
代码 2 - 25:数组的纵向组合
print('纵向组合为:\n', np.vstack((arr1, arr2))) # vstack函数纵向组合
代码解析:
np.vstack((arr1, arr2))
:将数组arr1
和arr2
按行方向(纵向)进行组合,要求数组的列数相同。
代码 2 - 26:使用concatenate函数进行组合
print('横向组合为:\n', np.concatenate((arr1, arr2), axis=1)) # concatenate函数横向组合
print('纵向组合为:\n', np.concatenate((arr1, arr2), axis=0)) # concatenate函数纵向组合
代码解析:
np.concatenate((arr1, arr2), axis)
:根据axis
参数的值进行数组的组合,axis=0
表示按行方向(纵向)组合,axis=1
表示按列方向(横向)组合。
代码 2 - 27:数组的横向分割
arr = np.arange(16).reshape(4, 4)
print('创建的二维数组为:\n', arr)
print('横向分割为:\n', np.hsplit(arr, 2)) # hsplit函数横向分割
代码解析:
np.hsplit(arr, num)
:将数组arr
按列方向(横向)分割成num
个部分。
代码 2 - 28:数组的纵向分割
print('纵向分割为:\n', np.vsplit(arr, 2)) # vsplit函数纵向分割
代码解析:
np.vsplit(arr, num)
:将数组arr
按行方向(纵向)分割成num
个部分。
代码 2 - 29:使用split函数进行分割
print('横向分割为:\n', np.split(arr, 2, axis=1)) # split函数横向分割
print('纵向分割为:\n', np.split(arr, 2, axis=0)) # split函数纵向分割
代码解析:
np.split(arr, num, axis)
:根据axis
参数的值进行数组的分割,axis=0
表示按行方向(纵向)分割,axis=1
表示按列方向(横向)分割。
总结
通过本文的学习,你将掌握NumPy数组对象ndarray的基本操作,包括数组的创建、属性查看、数据类型转换、随机数组生成、索引和切片、形状操作、组合和分割等。这些操作是使用NumPy进行科学计算和数据处理的基础,能够帮助你更高效地处理和分析数据。