Numpy repeat 方法:从基础到高级应用详解 – wiki基地


NumPy repeat 方法:从基础到高级应用详解

在数据处理和科学计算中,NumPy 是 Python 不可或缺的库。它提供了高效的多维数组对象,以及大量用于操作这些数组的函数。其中,numpy.repeat 是一个非常实用的函数,用于按照指定的次数重复数组中的元素。本文将从基础用法入手,逐步深入到 repeat 方法的高级应用场景,并探讨其与 tile 方法的区别。

1. numpy.repeat 简介

numpy.repeat(a, repeats, axis=None) 函数是用来重复数组 a 中的元素。它有三个主要参数:

  • a: 输入数组。
  • repeats: 指定每个元素或整个数组重复的次数。它可以是一个整数,也可以是一个数组(序列),其长度必须与 axis 指定的轴的长度匹配。
  • axis: 可选参数,指定沿着哪个轴重复元素。
    • None (默认值): 将输入数组 a 展平(flatten)后再进行重复操作,返回一个一维数组。
    • 整数: 指定沿着该轴重复。例如,axis=0 沿着行重复,axis=1 沿着列重复。

理解 repeat 的核心是记住它会重复数组中的元素,而不是像 tile 那样重复整个数组或子数组。

2. 基础用法

2.1 简单重复整个一维数组

repeats 是一个整数,且 axisNone 或输入数组是一维时,repeat 会将数组中的每个元素重复 repeats 次。

“`python
import numpy as np

arr1d = np.array([1, 2, 3])

每个元素重复 3 次

result1 = np.repeat(arr1d, 3)
print(“Result 1 (each element repeated):”, result1)

Output: [1 1 1 2 2 2 3 3 3]

“`

2.2 重复整个多维数组(展平后)

axis=None 时,多维数组会被展平为一维数组,然后其元素按顺序重复。

“`python
arr2d = np.array([[1, 2], [3, 4]])

展平后每个元素重复 2 次

result2 = np.repeat(arr2d, 2, axis=None)
print(“\nResult 2 (flattened, then each element repeated):”, result2)

Output: [1 1 2 2 3 3 4 4]

“`

3. repeats 参数的灵活运用

repeats 参数不仅可以是单个整数,还可以是一个数组或列表,这为元素重复提供了更精细的控制。

3.1 repeats 为整数

repeats 是一个整数时,数组中的每个元素(如果 axisNone)或沿着指定轴的每个“切片”(如果 axis 指定),都会重复相同的次数。

“`python

沿 axis=0 (行) 重复

result3 = np.repeat(arr2d, 2, axis=0)
print(“\nResult 3 (repeating rows):”)
print(result3)

Output:

[[1 2]

[1 2]

[3 4]

[3 4]]

沿 axis=1 (列) 重复

result4 = np.repeat(arr2d, 2, axis=1)
print(“\nResult 4 (repeating columns):”)
print(result4)

Output:

[[1 1 2 2]

[3 3 4 4]]

``
**注意:** 当
axis被指定时,repeats的长度如果是一个序列,则必须与该axis上的元素数量(即a.shape[axis]`)相匹配。

3.2 repeats 为数组或列表

repeats 是一个数组或列表时,它指定了输入数组中每个对应的元素或切片应该重复的次数。

  • 一维数组: repeats 的长度必须与输入数组的长度相同。

    “`python
    arr1d_complex = np.array([1, 2, 3])

    1 重复 1 次,2 重复 3 次,3 重复 2 次

    result5 = np.repeat(arr1d_complex, [1, 3, 2])
    print(“\nResult 5 (variable repeats for 1D):”, result5)

    Output: [1 2 2 2 3 3]

    “`

  • 多维数组 (axis 指定): repeats 序列的长度必须与 axis 指定的维度的大小相同。

    “`python
    arr2d_complex = np.array([[1, 2], [3, 4]])

    沿 axis=0 (行) 重复:第一行重复 1 次,第二行重复 3 次

    result6 = np.repeat(arr2d_complex, [1, 3], axis=0)
    print(“\nResult 6 (variable repeats for rows):”)
    print(result6)

    Output:

    [[1 2]

    [3 4]

    [3 4]

    [3 4]]

    沿 axis=1 (列) 重复:第一列重复 2 次,第二列重复 1 次

    result7 = np.repeat(arr2d_complex, [2, 1], axis=1)
    print(“\nResult 7 (variable repeats for columns):”)
    print(result7)

    Output:

    [[1 1 2]

    [3 3 4]]

    “`

4. 高级应用场景

np.repeat 在许多数据处理任务中都非常有用,尤其是在需要扩展数据维度、对数据进行插值或为某些算法准备输入时。

4.1 数据增强/上采样

在机器学习中,有时需要对数据进行简单的增强,或者在某些维度上进行上采样。repeat 可以方便地实现这一点。

“`python

假设有一组特征数据,需要将每个样本重复几次

data = np.array([[10, 20], [30, 40]]) # 2个样本,每个2个特征

每个样本(行)重复 2 次

augmented_data = np.repeat(data, 2, axis=0)
print(“\nAugmented Data (each sample repeated):”)
print(augmented_data)

Output:

[[10 20]

[10 20]

[30 40]

[30 40]]

“`

4.2 准备广播操作

在进行广播(Broadcasting)操作时,如果一个数组的维度需要扩展以匹配另一个数组的形状,repeat 可以作为一个有用的工具,尽管有时 np.newaxisreshape 也能达到类似目的。

例如,有一个 1xN 的数组,需要将其重复 M 次以与 MxN 数组进行元素级运算。

“`python
row_vector = np.array([1, 2, 3])

将行向量重复 4 次,形成一个 4×3 的矩阵

matrix = np.repeat(row_vector[np.newaxis, :], 4, axis=0)
print(“\nMatrix created for broadcasting:”)
print(matrix)

Output:

[[1 2 3]

[1 2 3]

[1 2 3]

[1 2 3]]

``
这里
row_vector[np.newaxis, :]将一维数组转换为二维行向量[[1, 2, 3]],然后repeat沿着axis=0` 重复这个行向量。

4.3 创建网格或棋盘图案

通过结合 repeat 和其他 NumPy 操作,可以有效地创建复杂的图案或网格。

“`python

创建一个简单的 2×2 模式

pattern = np.array([[0, 1], [1, 0]])

在行和列方向上重复,创建更大的棋盘

checkerboard = np.repeat(np.repeat(pattern, 2, axis=0), 2, axis=1)
print(“\nCheckerboard pattern:”)
print(checkerboard)

Output:

[[0 0 1 1]

[0 0 1 1]

[1 1 0 0]

[1 1 0 0]]

“`

5. np.repeatnp.tile 的区别

repeattile 都是用来扩展数组的函数,但它们的机制截然不同。这是 NumPy 初学者常混淆的地方。

  • np.repeat(a, repeats, axis=None): 重复数组中的每个元素或切片

    • axis=None 时,它会展平数组 a,然后对每个标量元素进行重复。
    • axis 指定时,它会沿着该轴复制“完整”的元素或子数组。
  • np.tile(a, reps): 重复整个数组 a 本身,或重复数组 a 的“瓦片”(tile)。

    • reps 可以是一个整数或一个元组。
    • 如果 reps 是一个整数,则将 a 作为整体在第一个维度上重复 reps 次。
    • 如果 reps 是一个元组,例如 (m, n),则将 a 在行方向上重复 m 次,在列方向上重复 n 次,形成一个更大的“瓦片网格”。

让我们通过一个例子来比较:

“`python
arr = np.array([1, 2])

使用 repeat: 每个元素重复 3 次

repeat_result = np.repeat(arr, 3)
print(“\nrepeat([1, 2], 3):”, repeat_result)

Output: [1 1 1 2 2 2]

使用 tile: 整个数组 [1, 2] 作为整体重复 3 次

tile_result = np.tile(arr, 3)
print(“tile([1, 2], 3):”, tile_result)

Output: [1 2 1 2 1 2]

arr2d_comp = np.array([[1, 2], [3, 4]])

repeat(arr2d_comp, 2, axis=0) – 每行重复2次

repeat_2d_axis0 = np.repeat(arr2d_comp, 2, axis=0)
print(“\nrepeat([[1,2],[3,4]], 2, axis=0):\n”, repeat_2d_axis0)

Output:

[[1 2]

[1 2]

[3 4]

[3 4]]

tile(arr2d_comp, (2,1)) – 整个数组在行方向重复2次,列方向重复1次

tile_2d_reps = np.tile(arr2d_comp, (2, 1))
print(“tile([[1,2],[3,4]], (2,1)):\n”, tile_2d_reps)

Output:

[[1 2]

[3 4]

[1 2]

[3 4]]

“`

从上面的例子可以看出,repeat 倾向于“放大”现有元素,而 tile 倾向于“平铺”整个数组的副本。

6. 总结

numpy.repeat 是 NumPy 中一个强大且灵活的数组操作函数。通过其 repeatsaxis 参数的组合,我们可以实现对数组元素进行各种方式的重复和扩展,无论是简单的元素复制,还是复杂的多维数据结构重塑。理解 repeattile 的核心区别,能帮助您在不同的数据处理场景中选择最合适的工具,从而更高效地操纵您的 NumPy 数组。

滚动至顶部