Python----数据分析(Numpy三:连接数组,分割数组,数组元素的添加和删除)

发布于:2025-02-26 ⋅ 阅读:(12) ⋅ 点赞:(0)

一、连接数组

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]]
'''

四、思维导图


网站公告

今日签到

点亮在社区的每一天
去签到