一、数组的索引和切片
Ndarray数组中的元素是可以被修改的,如果需要访问或者修改Ndarray数组某个位 置的元素,则需要使用Ndarray数组的索引来完成;如果需要访问或者修改一些区域 的元素,则需要使用Ndarray数组的切片。
1.1、一维数组的索引与切片
1.1.1、索引
一维数组的索引方式与Python列表的索引方式类似,Ndarray数组使用方括号 行索引,索引值从左向右从0开始,从右向左从-1开始。
# 一维数组的索引方式
import numpy as np
# 创建了一个一维数组
arr = np.array([1, 2, 3, 4, 5])
print(arr[0])
print(arr[4])
print(arr[-1])
print(arr[-3])
arr[0] = 10
print(arr)
'''
1
5
5
3
[10 2 3 4 5]
'''
1.1.2、切片
与Python列表的切片方式类似,使用冒号:进行切片,格式为 start:stop:step, 其中start、stop、step可根据情况省略。
# 一维数组的切片方式
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
arr1 = arr[4:7]
print('arr1数组元素为', arr1)
arr2 = arr[1:6:2]
print('arr2数组元素为', arr2)
# 将一个标量值赋值给一个切片时,该值会自动传播到整个选区。
arr[4:7] = 6
print('arr数组元素为:', arr)
# 也可以使用:代表全部元素
arr[:] = 10
print('arr数组元素为:', arr)
arr[:4] = 1
print(arr)
'''
arr1数组元素为 [5 6 7]
arr2数组元素为 [2 4 6]
arr数组元素为: [ 1 2 3 4 6 6 6 8 9 10]
arr数组元素为: [10 10 10 10 10 10 10 10 10 10]
[ 1 1 1 1 10 10 10 10 10 10]
'''
1.2、多维数组的索引与切片
1.2.1、索引
对于多维数组,可以通过逗号分隔的索引来访问特定元素,也可以使用连续的[]来访 问特定元素,例如,对于一个二维数组,第一个索引表示行,第二个索引表示列。
# 二维数组的索引
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print('arr数组为:\n', arr)
# 只有一个索引指标时,会在第0维上索引,后面的维度保持不变
print('arr[0]为:', arr[0])
# 两个索引指标
print('arr[0][0]为:', arr[0][0])
print(arr[0][0])
# 两个索引指标
print('arr[0, 1]为:', arr[0, 1])
arr[0][2] = 5
print(arr)
'''
arr数组为:
[[1 2 3]
[4 5 6]]
arr[0]为: [1 2 3]
arr[0][0]为: 1
1
arr[0, 1]为: 2
[[1 2 5]
[4 5 6]]
'''
1.2.2、切片
多维数组切片时,可以分别为每个维度指定切片。
# 二维数组的切片
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print('arr: \n', arr)
# 选择特定的一行
row1 = arr[1]
print(row1)
# 选择连续的多行
rows = arr[1:3]
print(rows)
# 选择不连续的多行
rows = arr[[0, 2]]
print(rows)
# 选择特定的一列
col1 = arr[:, 1]
print(col1)
# 选择连续的多列
cols = arr[:, 1:3]
print(cols)
# 选择不连续的多列
cols = arr[:, [0, 2]]
print(cols)
# 同时选择行和列
subset = arr[1:3, 1:3]
print(subset)
'''
arr:
[[1 2 3]
[4 5 6]
[7 8 9]]
[4 5 6]
[[4 5 6]
[7 8 9]]
[[1 2 3]
[7 8 9]]
[2 5 8]
[[2 3]
[5 6]
[8 9]]
[[1 3]
[4 6]
[7 9]]
[[5 6]
[8 9]]
'''
二、数组的属性
2.1、shape
通过调用Ndarray.shape即可返回一个表示数组维度大小的元组。
import numpy as np
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr1)
print(arr1.shape)
'''
[[1 2 3]
[4 5 6]]
(2, 3)
'''
2.2、dtype
通过调用Ndarray.dtype即可返回一个Ndarray数组中元素的数据类型。
import numpy as np
# 可以在创建的时候去指定数据类型
arr1 = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float32)
print(arr1)
print(arr1.dtype)
'''
[[1. 2. 3.]
[4. 5. 6.]]
float32
'''
2.3、size
该属性是指数组中包含的元素个数,其大小等于调用shape函数返回的元组中的所有 元素的乘积。
import numpy as np
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr1)
print(arr1.shape)
print(arr1.size)
'''
[[1 2 3]
[4 5 6]]
(2, 3)
6
'''
2.4、ndim
该属性是指数组的维度大小,其大小等于调用shape函数返回的元组中的元素的个数。
import numpy as np
arr1 = np.array([[[[1, 2, 3], [4, 5, 6]]]])
print(arr1)
print(arr1.shape)
print(arr1.ndim)
'''
[[[[1 2 3]
[4 5 6]]]]
(1, 1, 2, 3)
4
'''
三、改变数组的数据类型和形状
3.1、数据类型的修改
numpy.ndarray.astype(dtype, order='K', casting='unsafe', subok=True, copy=True)
函数 | 说明 |
---|---|
dtype | 表示新数据类型的对象。这可以是 NumPy 的 dtype 对象,也可以是 Python 的数据类型,例如 int 或 float |
order | 一个字符,指定结果的内存布局。 按列(Fortran风格), 'C' 表示按行(C风格), 'F' 表示 'A' 或 'K' 表示在内存中的顺序与原数组保持一致 |
casting | 控制数据类型转换的安全性。它可以是 'no'、 'equiv'、 'safe'、 'same_kind' 或 'unsafe' 之一 。 |
subok | 如果为True,子类将被传递,否则返回的数组将强制转换为基类数组 |
copy | 布尔值,指定是否复制数据。 |
casting参数说明:
'no':表示根本不应该进行转换数据类型。
'equiv':允许数值上等价的类型转换,即转换前后数据的位表示相同。这意味着转 换不会导致数据丢失。
'safe':允许安全的类型转换,即转换过程中不会丢失信息。
'same_kind':允许相同数据类型类别内的转换。例如,允许整型和整型之间、浮点 型和浮点型之间的转换,但是不允许整型和浮点型之间的转换。
'unsafe':允许任何类型的转换,不考虑是否会导致数据丢失或改变。这是最不安全 的选项,因为它可能会静默地丢弃数据。
比如:
从 int64 到 int32 的转换:
'no':不允许。
'equiv':不允许。
'safe':不允许。
'same_kind':允许。
'unsafe':允许。
从 float64 到 int32 的转换:
'no':不允许,因为会丢失小数部分。
'equiv'、'safe'、'same_kind':不允许,因为这不是数值上等价或安全的转换。
'unsafe':允许,但会丢失小数部分。
import numpy as np
# 创建一个浮点数数组
arr = np.array([1.1, 2.2, 3.3])
# 使用 astype 方法将数组转换为整数类型
new_arr = arr.astype(np.int32)
print("Original array:", arr)
print("old type:", arr.dtype)
print("New array:", new_arr)
print("new type:", new_arr.dtype)
'''
Original array: [1.1 2.2 3.3]
old type: float64
New array: [1 2 3]
new type: int32
'''
3.2、形状的修改
3.2.1、reshape
reshape方法用于给数组一个新的形状而不改变其数据,它返回一个新的数组,但是 如果给定的形状与原始数组的数据不兼容,会抛出异常
numpy.ndarray.reshape(newshape, order='C')
函数 | 说明 |
---|---|
newshape | 整数或整数元组,新的形状应该与原始数组中的元素数量相匹配 |
order | 可选参数,‘C’ 表示按行(C-style),‘F’ 表示按列(Fortran-style),‘A’ 表示原数组内存顺序,‘K’ 表示元素在内存中的出现顺序 |
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a)
print('shape--a', a.shape)
b = a.reshape((3, 2))
print(a)
print(b)
print('shape--b',b.shape)
'''
[[1 2 3]
[4 5 6]]
shape--a (2, 3)
[[1 2 3]
[4 5 6]]
[[1 2]
[3 4]
[5 6]]
shape--b (3, 2)
'''
3.2.2、resize
resize 方法用于改变数组的大小,与 reshape类似,但它会直接修改调用它的原始数 组。如果新形状大于原始形状,则会在数组的末尾添加新的元素,这些元素的值未定 义;如果新形状小于原始形状,则会截断数组。
numpy.ndarray.resize(newshape)
函数 | 说明 |
---|---|
newshape | 整数或整数元组,新的形状。 |
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a)
print('before:', a.shape)
a.resize((3, 2))
print('after:', a.shape)
print(a)
a.resize((2, 2))
print(a)
a.resize((5, 5))
print(a)
'''
[[1 2 3]
[4 5 6]]
before: (2, 3)
after: (3, 2)
[[1 2]
[3 4]
[5 6]]
[[1 2]
[3 4]]
[[1 2 3 4 0]
[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]]
'''
3.2.3、flatten
flatten方法返回一个一维数组,它是原始数组的拷贝,它默认按行顺序展平数组,但 可以通过参数 order 来指定展平顺序。
numpy.ndarray.flatten(order='C')
函数 | 说明 |
---|---|
order | 可选参数,‘C’ 表示按行,‘F’ 表示按列,‘A’ 或 ‘K’ 表示与原数组相同的顺序 |
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
print(a)
b = a.flatten()
print(b)
b[0] = 10
print(a)
print(b)
'''
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
[ 1 2 3 4 5 6 7 8 9 10 11 12]
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
[10 2 3 4 5 6 7 8 9 10 11 12]
'''
3.2.4、ravel
ravel方法返回一个连续的数组,它尝试以最低的复制操作来返回展平后的数组
numpy.ndarray.ravel(order='C')
函数 | 说明 |
---|---|
order | 可选参数,‘C’ 表示按行,‘F’ 表示按列 |
ravel和flatten的区别:
flatten 方法返回的是原数组的副本。这意味着返回的新数组与原数组是两个独 立的对象,对新数组的修改不会影响原数组。
ravel 方法返回的是原数组的视图(view)或副本(copy),这取决于数组的 顺序。如果数组是连续的(C-style,行优先),则 ravel 返回的是视图,这意 味着对返回数组的修改会影响到原数组。如果数组不是连续的,则 的是副本。可以通过传递 order='F' 参数来请求列优先的视图。
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
b = a.flatten()
c = a.ravel()
d = a.ravel(order='F')
a[0][0] = 100
a[1][0] = 50
print('a', a)
print('b', b)
print('c', c)
print('d', d)
'''
a [[100 2 3]
[ 50 5 6]]
b [1 2 3 4 5 6]
c [100 2 3 50 5 6]
d [1 4 2 5 3 6]
'''
3.2.5、T
Ndarray 对象的 T 属性是一个特殊的属性,它返回数组的转置(transpose)。
转置是一个操作,它将数组的维度进行交换。对于二维数组,这意味着行变为列,列 变为行。对于更高维度的数组,转置操作涉及到交换数组的轴。
import numpy as np
# 创建一个二维数组
arr_2d = np.array([[1, 2], [3, 4], [5, 6]])
# 获取转置
transposed_arr = arr_2d.T
print(" array:")
print(arr_2d)
print("T array:")
print(transposed_arr)
'''
array:
[[1 2]
[3 4]
[5 6]]
T array:
[[1 3 5]
[2 4 6]]
'''
四、修改维度
4.1、squeeze
该函数的作用是从数组形状中删除所有单维度的条目,即把形状中为1的维度去掉。
numpy.squeeze(a, axis=None)
函数 | 说明 |
---|---|
a | 输入数组。它可以是任何形状的数组,但至少有一个维度的大小为1。 |
axis | 可选参数。一个整数或整数元组。如果指定了该参数,则只压缩指定的 轴。如果该轴在数组 a 中不是单维度的,则不会进行压缩。如果未指定,则所有 单维度的轴都将被压缩。 |
# squeeze: 降维
import numpy as np
# 创建一个具有单维度的数组
arr = np.array([[[1], [2], [3]]])
print(arr)
print("原始数组形状:", arr.shape)
# 使用squeeze函数去掉所有单维度的条目
squeezed_arr = np.squeeze(arr, axis=(0, 2))
print(squeezed_arr)
print("压缩后的数组形状:", squeezed_arr.shape)
'''
[[[1]
[2]
[3]]]
原始数组形状: (1, 3, 1)
[1 2 3]
压缩后的数组形状: (3,)
'''
4.2、expand_dims
该函数的作用是在指定的位置增加一个单一维度,即在指定的位置增加一个形状为1 的维度。
numpy.expand_dims(a, axis)
函数 | 说明 |
---|---|
a | 输入数组。它可以是任何形状的数组,但至少有一个维度的大小为1。 |
axis | 可选参数。一个整数或整数元组。如果指定了该参数,则只压缩指定的 轴。如果该轴在数组 a 中不是单维度的,则不会进行压缩。如果未指定,则所有 单维度的轴都将被压缩。 |
# expand_dims:升维
import numpy as np
# 创建一个一维数组
arr = np.array([[1, 2, 3], [4, 5, 6]])
print("原始数组形状:", arr.shape)
print(arr)
# 在位置0增加一个维度
expanded_arr = np.expand_dims(arr, axis=2)
print("增加维度后的数组形状:", expanded_arr.shape)
print(expanded_arr)
# 在位置1增加一个维度
expanded_arr = np.expand_dims(arr, axis=(0, 1))
print("增加维度后的数组形状:", expanded_arr.shape)
print(expanded_arr)
'''
原始数组形状: (2, 3)
[[1 2 3]
[4 5 6]]
增加维度后的数组形状: (2, 3, 1)
[[[1]
[2]
[3]]
[[4]
[5]
[6]]]
增加维度后的数组形状: (1, 1, 2, 3)
[[[[1 2 3]
[4 5 6]]]]
'''