NumPy数组切片(Slicing)

NumPy是Python中用于科学计算的一个库,它提供了对大规模多维数组和矩阵的支持。切片(slicing)是从这些数组中提取子数组的一个强大工具。

基本切片语法

基本的切片语法是start:stop:step,它可以用于一维和多维数组。让我们一步步来理解。

一维数组的切片

假设我们有一个一维NumPy数组:

import numpy as np

arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
  • arr[start:stop:step]:选择从索引start到索引stop(不包括stop)的元素,步长为step
  • 示例:

    print(arr[2:7])      # [2 3 4 5 6]
    print(arr[2:7:2])    # [2 4 6]
    print(arr[:5])       # [0 1 2 3 4]
    print(arr[5:])       # [5 6 7 8 9]
    print(arr[::2])      # [0 2 4 6 8]
    print(arr[::-1])     # [9 8 7 6 5 4 3 2 1 0]  逆序
    
    多维数组的切片

    对于多维数组,切片操作适用于每一个维度。假设我们有一个二维数组:

    arr_2d = np.array([
        [0, 1, 2, 3],
        [4, 5, 6, 7],
        [8, 9, 10, 11]
    ])
    
  • arr_2d[row_start:row_stop:row_step, col_start:col_stop:col_step]:可以同时对行和列进行切片操作。
  • 示例:

    print(arr_2d[:2, :3])       # 前两行和前三列
    # [[0 1 2]
    #  [4 5 6]]
    
    print(arr_2d[1:, 2:])       # 从第二行开始到最后一行,从第三列开始到最后一列
    # [[ 6  7]
    #  [10 11]]
    
    print(arr_2d[:, 1:3])       # 所有行,第二列到第三列
    # [[ 1  2]
    #  [ 5  6]
    #  [ 9 10]]
    
    print(arr_2d[::2, ::2])     # 隔行隔列取值
    # [[ 0  2]
    #  [ 8 10]]
    

    具体示例与解释

    为了更好地理解这些操作,让我们再详细看一些具体的示例。

    提取特定行和列

    从一个二维数组中提取特定的行和列:

    print(arr_2d[1, :])   # 提取第二行
    # [4 5 6 7]
    
    print(arr_2d[:, 2])   # 提取第三列
    # [ 2  6 10]
    
    提取特定区域

    我们可以通过组合行和列的切片来提取特定的区域:

    print(arr_2d[1:3, 1:3])  # 提取从第二行到第三行,从第二列到第三列的区域
    # [[ 5  6]
    #  [ 9 10]]
    

    高级切片

    除了基础的切片,NumPy还支持一些高级切片技术,如布尔索引和花式索引(fancy indexing)。

    布尔索引

    布尔索引使用布尔数组来选择数组中的元素:

    arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    bool_idx = arr > 5
    
    print(arr[bool_idx])  # 选择大于5的元素
    # [6 7 8 9]
    
    # 也可以直接在索引中使用条件表达式
    print(arr[arr % 2 == 0])  # 选择偶数
    # [0 2 4 6 8]
    
    花式索引

    花式索引允许使用整数数组进行索引:

    arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    idx = [1, 3, 5, 7]
    
    print(arr[idx])  # 选择索引1, 3, 5, 7处的元素
    # [1 3 5 7]
    

    对于多维数组,同样适用:

    arr_2d = np.array([
        [0, 1, 2, 3],
        [4, 5, 6, 7],
        [8, 9, 10, 11]
    ])
    
    row_idx = [0, 2]
    col_idx = [1, 3]
    
    print(arr_2d[row_idx, col_idx])  # 选择(0, 1)和(2, 3)位置的元素
    # [ 1 11]
    

    结合使用

    切片、布尔索引和花式索引可以结合使用以实现复杂的数据提取:

    arr = np.array([
        [0, 1, 2, 3],
        [4, 5, 6, 7],
        [8, 9, 10, 11],
        [12, 13, 14, 15]
    ])
    
    # 提取偶数行的前两列
    print(arr[::2, :2])
    # [[ 0  1]
    #  [ 8  9]]
    
    # 使用布尔索引提取大于5的元素
    print(arr[arr > 5])
    # [ 6  7  8  9 10 11 12 13 14 15]
    
    # 花式索引提取指定行和列
    print(arr[[0, 2], [1, 3]])
    # [ 1 11]
    

    实际应用中的例子

    假设有一个包含训练数据的二维数组train_data,它的最后一列是目标变量,我们希望提取特征数据和目标变量:

    import numpy as np
    
    train_data = np.array([
        [1.0, 2.0, 3.0, 10.0],
        [4.0, 5.0, 6.0, 20.0],
        [7.0, 8.0, 9.0, 30.0]
    ])
    
    # 提取目标变量(最后一列)
    y_train = train_data[:, -1]
    print("y_train:", y_train)
    # [10. 20. 30.]
    
    # 提取特征数据(除最后一列外的所有列)
    raw_x_train = train_data[:, :-1]
    print("raw_x_train:\n", raw_x_train)
    # [[1. 2. 3.]
    #  [4. 5. 6.]
    #  [7. 8. 9.]]
    

    这个例子展示了如何使用切片从数据集中提取目标变量和特征数据。

    结论

    NumPy切片是一种强大且灵活的工具,用于从数组中提取子集。理解这些基本概念和操作对于高效处理和操作数据非常重要。

    作者:Violent-Ayang

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python数组切片详解

    发表回复