一、连接数组
1.1、concatenate
该函数用于将多个数组沿指定的轴连接起来,形成一个更大的数组
numpy.concatenate((a1, a2, ..., arr_n), axis=0, out=None)
函数 | 说明 |
---|---|
(a1, a2, ..., arr_n) | 这是一个包含数组的元组,这些数组需要被连接。所 有数组在除了连接轴之外的其他维度上必须有相同的形状 |
axis | 整数,指定沿着哪个轴进行连接。如果不指定,默认为 0,表示第一个 轴。 |
out | 可选参数,如果提供,结果将直接存储在这个数组中。这个数组必须具有 与输入数组相同的形状和数据类型。 |
工作原理:
1. 输入验证: concatenate 接受一个元组或列表作为输入,其中包含一系列数 组。这些数组可以是任意维度,但它们在除了要连接的轴之外的所有维度上必须 具有相同的形状。
2. 轴参数: concatenate 有一个必需的参数 axis,它指定了沿着哪个轴进行连 接。轴的编号从 0 开始,对于一维数组,只有一个轴(轴 0)。对于二维数组, 轴 0 是行,轴 1 是列。
3. 形状兼容性检查:所有输入数组在 axis 参数指定的轴上的维度大小可以不同, 但在其他轴上的维度大小必须相同。例如,如果 axis=1,则所有输入数组的行 数必须相同。
4. 内存分配:在连接之前, concatenate 会计算输出数组的大小,并分配足够的 内存空间来存储结果。
5. 数据复制: concatenate 会将输入数组的数据复制到新分配的内存空间中。具 体来说,它将沿着指定的轴顺序地复制每个数组的数据,从而形成一个新的数 组。
6. 结果数组:输出结果是一个新的数组,它在 axis 指定的轴上的维度大小是所有 输入数组在该轴上维度大小的总和,而在其他轴上则与输入数组相同。
import numpy as np
# 创建两个数组
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
print(f'数组a的形状为{a.shape}, 数组a为:\n', a)
print(f'数组b的形状为{b.shape}, 数组b为:\n', b)
# 沿着第一个轴(垂直方向)连接数组
c = np.concatenate((b, a), axis=0)
print(f'数组c的形状为{c.shape}, 数组c为:\n', c)
# 沿着第二个轴(水平方向)连接数组
d = np.concatenate((a, b.T), axis=1)
print(f'数组b的转置的形状为{b.T.shape}, 数组b的转置为:\n', b.T)
print(f'数组d的形状为{d.shape}, 数组d为:\n', d)
'''
数组a的形状为(2, 2), 数组a为:
[[1 2]
[3 4]]
数组b的形状为(1, 2), 数组b为:
[[5 6]]
数组c的形状为(3, 2), 数组c为:
[[5 6]
[1 2]
[3 4]]
数组b的转置的形状为(2, 1), 数组b的转置为:
[[5]
[6]]
数组d的形状为(2, 3), 数组d为:
[[1 2 5]
[3 4 6]]
'''
1.2、stack
该函数用于沿着新的轴连接一系列数组。与 numpy.concatenate 不同, numpy.stack 总是创建一个新的轴,而numpy.concatenate则是在现有轴上进行数组的连接
numpy.stack(arrays, axis=0, out=None)
函数 | 说明 |
---|---|
arrays | 一系列数组,它们将被堆叠在一起。所有数组必须具有相同的形状 |
axis | 整数,表示新轴的位置。默认值为 0 |
out | 可选参数,如果提供,结果将直接存储在这个数组中。这个数组必须具有 与输出数组相同的形状和数据类型 |
工作原理:
1. 输入验证: stack 接受一个数组序列(例如一个列表或元组)作为输入。所有输 入数组必须具有相同的形状。
2. 轴参数: stack 有一个必需的参数 axis,它指定了新轴的位置。
3. 形状兼容性检查:所有输入数组在除了要创建的新轴外的所有维度上必须具有相 同的形状。
4. 内存分配: stack 会计算输出数组的形状,并在内存中为这个新数组分配空间。 新数组的形状将比输入数组的形状多一个维度,这个新增的维度的大小等于输入 数组的数量。
5. 数据复制: stack 将输入数组的数据复制到新分配的内存空间中,每个输入数组 在新轴上占据一个位置。
6. 结果数组:输出结果是一个新的数组,其形状在 一个维度。
import numpy as np
# 创建两个一维数组
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
c = np.array([7, 8, 9])
print(f'数组a的形状为{a.shape}, 数组a为:\n', a)
print(f'数组b的形状为{b.shape}, 数组b为:\n', b)
# # 沿着新的轴堆叠数组
d = np.stack((a, c, b), axis=0)
print(f'数组d的形状为{d.shape}, 数组d为:\n', d)
# 沿着第二个轴堆叠数组
e = np.stack((a, b), axis=1)
print(f'数组e的形状为{e.shape}, 数组e为:\n', e)
'''
数组a的形状为(3,), 数组a为:
[1 2 3]
数组b的形状为(3,), 数组b为:
[4 5 6]
数组d的形状为(3, 3), 数组d为:
[[1 2 3]
[7 8 9]
[4 5 6]]
数组e的形状为(3, 2), 数组e为:
[[1 4]
[2 5]
[3 6]]
'''
1.3、hstack
在 NumPy 中, numpy.hstack(水平堆叠)函数用于沿着水平方向堆叠数组序列。
numpy.hstack(tup)
函数 | 说明 |
---|---|
tup | 一个数组序列,它们将被水平堆叠在一起。所有数组在除了第二个轴之外 的轴上必须具有相同的形状。 |
工作原理:
1. 输入验证:首先, hstack 会检查所有输入数组是否都是二维的,或者至少可以 被视为二维的。如果输入数组是多维的,它们将被重新塑造为二维数组。
2. 形状兼容性检查:所有输入数组在除了第二个轴(列)之外的所有其他轴上必须 有相同的形状。这意味着,如果输入数组是一系列的矩阵,那么这些矩阵的行数 必须相同。例如,如果你有两个矩阵 A 和 B,它们分别是 3x2 和 3x3 的,那么它 们可以在水平方向上堆叠,因为它们都有 3 行。
3. 堆叠操作:如果输入数组通过了形状兼容性检查, hstack 将沿着第二个轴 (列)将它们连接起来。这意味着,对于每个输入数组,它们的列将被依次排列 在一起。
4. 结果数组:输出结果是一个新的二维数组,其列数是所有输入数组列数的总和, 而行数与输入数组中的任何一个相同。
import numpy as np
# 创建两个 2x2 的矩阵
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print(f'数组a的形状为{a.shape}, 数组a为:\n', a)
print(f'数组b的形状为{b.shape}, 数组b为:\n', b)
# 使用 hstack 进行水平堆叠
c = np.hstack((a, b))
# 输出结果
print(f'数组c的形状为{c.shape}, 数组c为:\n', c)
'''
数组a的形状为(2, 2), 数组a为:
[[1 2]
[3 4]]
数组b的形状为(2, 2), 数组b为:
[[5 6]
[7 8]]
数组c的形状为(2, 4), 数组c为:
[[1 2 5 6]
[3 4 7 8]]
'''
1.4、vstack
numpy.vstack函数用于将多个数组沿垂直方向(即沿着第一个轴,axis=0)堆叠成 一个单一的数组
numpy.vstack(tup)
函数 | 说明 |
---|---|
tup | 一个包含数组的元组或列表。所有数组在除了第一个轴外的维度上必须具 有相同的形状 |
工作原理:
1. 输入验证: vstack 接受一个数组序列(例如一个列表或元组)作为输入。所有 输入数组在除了第一个轴外的所有其他维度上必须具有相同的形状。
2. 内存分配: vstack 会计算输出数组的形状,并在内存中为这个新数组分配空 间。输出数组的第一个维度将是所有输入数组第一个维度大小的总和,其他维度 与输入数组相同。
3. 数据复制: vstack 将输入数组的数据复制到新分配的内存空间中,每个输入数 组在新数组中占据连续的块。
4. 结果数组:输出结果是一个新的数组,其中输入数组沿第一个轴(垂直方向)堆 叠。
import numpy as np
# 创建两个二维数组
a = np.array([[1, 2, 3],
[4, 5, 6]])
b = np.array([[7, 8, 9]])
print(f'数组a的形状为{a.shape}, 数组a为:\n', a)
print(f'数组b的形状为{b.shape}, 数组b为:\n', b)
# 使用 vstack 进行垂直堆叠
c = np.vstack((a, b))
# 输出结果
print(f'数组c的形状为{c.shape}, 数组c为:\n', c)
'''
数组a的形状为(2, 3), 数组a为:
[[1 2 3]
[4 5 6]]
数组b的形状为(1, 3), 数组b为:
[[7 8 9]]
数组c的形状为(3, 3), 数组c为:
[[1 2 3]
[4 5 6]
[7 8 9]]
'''
二、分割数组
2.1、split
该函数用于沿着指定的轴将数组分割成多个子数组,可以指定要分割的数组、分割的 位置或子数组的数量。
numpy.split(ary, indices_or_sections, axis=0)
函数 | 说明 |
---|---|
ary | 要分割的数组 |
indices_or_sections | 可以是一个整数,表示要将数组平均分割成多少个子 数组;也可以是一个整数数组,表示分割的位置 |
axis | 沿着哪个轴进行分割,默认为 0,即第一个轴 |
工作原理:
1. 输入验证: split 接受一个数组 参数 ary 作为输入,以及一个指示如何分割数组的 indices_or_sections。如果提供了 axis 参数,它指定了沿哪个轴分割 数组,默认为 0。
2. 解析分割参数:如果 indices_or_sections 是一个整数,它表示要将数组分割成多少个大小相等的子数组。如果是一个序列,它表示沿指定轴的分割点。
3. 计算分割点:如果indices_or_sections是整数,split 会计算每个子数组应该包含的元素数量。如果indices_or_sections是一个序列,则直接使用这些值作为分割点。
4. 执行分割:split 使用计算出的分割点在指定轴上将原始数组分割成多个子数 组。这通常涉及到创建原始数组的视图,而不是复制数据。
5. 返回结果: split 返回一个列表,其中包含所有分割后的子数组。
# split
import numpy as np
# 创建一个一维数组
a = np.array([1, 2, 3, 4, 5, 6])
# 使用 split 平均分割数组为 3 个子数组
result1 = np.split(a, 3, axis=0)
# 使用 split 按位置分割数组
result2 = np.split(a, [1, 2, 4])
# 输出结果
print("平均分割为 3 个子数组:", result1)
print("按位置分割:", result2)
'''
平均分割为 3 个子数组: [array([1, 2]), array([3, 4]), array([5, 6])]
按位置分割: [array([1]), array([2]), array([3, 4]), array([5, 6])]
'''
2.2、hsplit
numpy.hsplit 用于沿着横向(水平方向)将数组分割成多个子数组。这个函数是 numpy.split 的一个特化版本,专门用于沿着第二个轴(axis=1)进行分割。
numpy.hsplit(ary, indices_or_sections)
函数 | 说明 |
---|---|
ary | 要分割的数组 |
indices_or_sections | 可以是一个整数,表示要将数组平均分割成多少个子 数组;也可以是一个整数数组,表示分割的位置 |
工作原理:
1. 输入验证: hsplit 接受一个数组ary作为输入,以及一个指示如何分割数组的参数indices_or_sections。与 split 不同,hsplit 不接受axis 参数,因为它默认沿着第二个轴(axis=1)进行分割。
2. 解析分割参数:如果 indices_or_sections 是一个整数,它表示要将数组分割成多少个大小相等的子数组。如果是一个序列,它表示沿指定轴的分割点。
3. 计算分割点:如果 indices_or_sections 是整数, hsplit 会计算每个子数组 在水平方向上应该包含的列数。如果 indices_or_sections 是一个序列,则直 接使用这些值作为分割点。
4. 执行分割: hsplit 使用计算出的分割点在第二个轴上将原始数组分割成多个子 数组。与 split 类似,这通常涉及到创建原始数组的视图,而不是复制数据。
5. 返回结果: hsplit 返回一个列表,其中包含所有分割后的子数组。每个子数组 都是原始数组的一部分,沿第二个轴分割而成。
import numpy as np
# 创建一个 6x4 的二维数组
arr = np.arange(24).reshape(6, 4)
# 打印原始数组
print("原始数组:")
print(arr)
# 指定每部分应该包含的列数
col_counts = [1, 2]
# 使用 hsplit 分割数组
subarrays = np.hsplit(arr, col_counts)
# 打印分割后的子数组
print("\n分割后的子数组:")
print(subarrays)
'''
原始数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]
分割后的子数组:
[array([[ 0],
[ 4],
[ 8],
[12],
[16],
[20]]), array([[ 1],
[ 5],
[ 9],
[13],
[17],
[21]]), array([[ 2, 3],
[ 6, 7],
[10, 11],
[14, 15],
[18, 19],
[22, 23]])]
'''
2.3、vsplit
numpy.vsplit 用于沿着纵向(垂直方向)将数组分割成多个子数组。这个函数是 numpy.split 的一个特化版本,专门用于沿着第一个轴(axis=0)进行分割。
numpy.vsplit(ary, indices_or_sections)
函数 | 说明 |
---|---|
ary | 要分割的数组 |
indices_or_sections | 可以是一个整数,表示要将数组平均分割成多少个子 数组;也可以是一个整数数组,表示分割的位置 |
工作原理:
1. 输入验证: vsplit 接受一个数组 参数 ary 作为输入,以及一个指示如何分割数组的 indices_or_sections。与 split 不同, vsplit 不接受 为它默认沿着第一个轴(axis=0)进行分割。
2. 解析分割参数:如果 axis 参数,因 indices_or_sections 是一个整数,它表示要将数组在垂 直方向上平均分割成多少个子数组。如果是一个序列,它表示沿第一个轴的分割 点。
3. 计算分割点:如果 indices_or_sections 是整数, vsplit 会计算每个子数组 在垂直方向上应该包含的行数。如果 indices_or_sections 是一个序列,则直 接使用这些值作为分割点。
4. 执行分割: vsplit 使用计算出的分割点在第一个轴上将原始数组分割成多个子 数组。与 split 类似,这通常涉及到创建原始数组的视图,而不是复制数据。
5. 返回结果: vsplit 返回一个列表,其中包含所有分割后的子数组。每个子数组 都是原始数组的一部分,沿第一个轴分割而成。
import numpy as np
# 创建一个 6x4 的二维数组
arr = np.arange(24).reshape(6, 4)
# 打印原始数组
print("原始数组:")
print(arr)
# 指定每部分应该包含的列数
col_counts = [1, 2]
# 使用 hsplit 分割数组
subarrays = np.vsplit(arr, col_counts)
# 打印分割后的子数组
print("\n分割后的子数组:")
print(subarrays)
'''
原始数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]
分割后的子数组:
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])]
'''
三、元素的添加与删除
3.1、append
numpy.append(arr, values, axis=None)
函数 | 说明 |
---|---|
arr | 原始数组,可以是任何形状 |
values | 要追加的值,它们会被追加到arr的末尾。values的形状必须与arr 在除了要追加的轴之外的所有轴上兼容。 |
axis | 可选参数,指定要追加值的轴。如果axis没有被指定, arr 会被展平,values 会被追加到结果数组的末尾。 |
注意事项:
1、numpy.append 在追加元素时,如果 arr 的形状。
2、如果 values 是一个数组,它的形状必须与 values 是一个标量,它会自动广播以匹配 arr 在除了要追加的轴之外的所有 轴上匹配。
3、numpy.append 可能不是最高效的操作,因为它涉及到创建一个新的数组。如果 频繁追加元素,考虑使用 numpy.concatenate 或 numpy.append 的替代方法, 如使用 numpy.resize 和直接赋值。
import numpy as np
# 创建一个一维数组
arr = np.array([[1, 2, 3], [4, 5, 6]])
# 要追加的值
values = np.array([[1, 2, 3]])
# 使用 numpy.append 追加值
result = np.append(arr, values, axis=0)
# 输出结果
print(result)
'''
[[1 2 3]
[4 5 6]
[1 2 3]]
'''
import numpy as np
arr_2d = np.array([[1, 2], [3, 4]])
# 要追加的值
values_2d = np.array([[5], [6]])
# 使用 numpy.append 追加值,沿着列方向
result_2d = np.append(arr_2d, values_2d, axis=1)
# 输出结果
print(result_2d)
'''
[[1 2 5]
[3 4 6]]
'''
3.2、insert
该函数用于在数组的指定位置插入元素。与 numpy.append 不同的是, numpy.insert 允许用户在数组的任意位置插入元素,而不仅仅是数组的末尾。
numpy.insert(arr, obj, values, axis=None)
函数 | 说明 |
---|---|
arr | 原始数组,可以是任何形状。 |
obj | 表示插入位置的索引。它可以是整数或者整数数组。如果是整数,则表示 在哪个位置插入。如果是整数数组,则表示在哪些位置插入。 |
values | 要插入的值。如果 arr 是多维数组,则 axis 指定的轴以外的所有轴上与 arr 保持一致。 |
axis | 可选参数,指定插入操作的轴。如果未指定,则 values 会被插入到一维数组中。 |
注意事项:
1、如果 obj 是一个整数数组,values也会被分割成多个部分每个部分被插入到 对应的索引位置。
2、如果 values 是一个标量,它会自动广播以匹配需要插入的位置。
3、插入操作可能会比追加操作更加低效,因为它涉及到数组元素的移动。
import numpy as np
# 创建一个一维数组
arr = np.array([1, 2, 3, 4, 5])
print(arr)
result = np.insert(arr, 2, 10)
print(result)
# 在索引 [1, 3] 的位置插入值 [20, 30]
result_2 = np.insert(arr, [1, 3], [20, 10])
# 输出结果
print(result_2)
'''
[1 2 3 4 5]
[ 1 2 10 3 4 5]
[ 1 20 2 3 10 4 5]
'''
import numpy as np
# 在二维数组中插入值
arr_2d = np.array([[1, 2], [3, 4], [5, 6]])
print(arr_2d)
values = np.array([[5], [6], [7]])
# 在索引 0 的位置沿着列方向插入值 [10]
result_2d = np.insert(arr_2d, [0], values, 1)
# 输出结果
print(result_2d)
'''
[[1 2]
[3 4]
[5 6]]
[[5 1 2]
[6 3 4]
[7 5 6]]
'''
3.3、delete
该函数用于从数组中删除指定的子数组,并返回一个新的数组。这个函数允许用户删 除数组中的单个元素或多个连续的元素。
numpy.delete(arr, obj, axis=None)
函数 | 说明 |
---|---|
arr | 原始数组,可以是任何形状。 |
obj | 表示要删除的子数组的索引。它可以是单个整数、一个整数列表或一个整 数数组。如果是一个整数,它表示要删除单个元素的位置;如果是列表或数组, 则表示要删除多个元素的位置。 |
axis | 可选参数,指定删除操作的轴。如果未指定,则 arr 会被展平,然后根 据 obj 指定的索引删除元素。 |
注意事项:
1、如果 obj 是一个列表或数组,删除操作会按照索引的顺序进行,这意味着删除 操作可能会影响后续索引的位置。
2、如果 obj 中的索引超出数组的范围, numpy.delete 会抛出一个异常。
import numpy as np
# 创建一个一维数组
arr = np.array([1, 2, 3, 4, 5])
# 删除索引 2 的元素
result = np.delete(arr, 2)
# 输出结果
print(result)
# 删除索引 [1, 3] 的元素
result_2 = np.delete(arr, [1, 3])
# 输出结果
print(result_2)
'''
[1 2 4 5]
[1 3 5]
'''
import numpy as np
# 在二维数组中删除元素
arr_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 删除索引 1 的列
result_2d = np.delete(arr_2d, 0, axis=0)
# 输出结果
print(result_2d)
'''
[[4 5 6]
[7 8 9]]
'''
# 删除索引 [0, 2] 的行
result_2d_row = np.delete(arr_2d, [0, 2], axis=0)
# 输出结果
print(result_2d_row)
'''
[[4 5 6]]
'''