Skip to content

NumPy - 索引与切片

使用索引(indexing)和切片(slicing)可以访问和修改 NumPy 的 ndarray 对象中的元素,这与标准的 Python 序列(如列表、元组)非常相似。

如前所述,ndarray 的元素使用从零开始的索引(zero-based indexing)。NumPy 提供了多种索引方法,包括基本切片(basic slicing)、高级索引(advanced indexing,包括整数索引和布尔索引),以及结构化数组的字段访问(field access)。

基本切片将 Python 的切片概念扩展到了多个维度。您可以使用 slice(start, stop, step) 对象或更常见的 start:stop:step 语法直接在方括号 [] 中创建切片。

重要提示:基本切片通常返回原数组的视图(view),而不是副本(copy)。修改切片会修改原数组。如果您需要一个副本,请在切片上使用 .copy() 方法(例如,a[start:stop:step].copy())。

演示如何创建 slice 对象并将其应用于数组。

import numpy as np
a = np.arange(10) # Creates an array [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
s = slice(2, 7, 2) # Represents indices from 2 up to (but not including) 7, with a step of 2
print(a[s])

输出:

[2 4 6]

在此示例中,np.arange(10) 创建一个一维数组。定义了一个 slice 对象 s,用于选择从索引 2 开始、到索引 7 结束(不包含)、步长为 2 的元素。应用此切片 a[s] 提取相应的元素。

使用冒号表示法直接在方括号中可以更简洁地实现同样的结果。

演示标准的 start:stop:step 语法。

import numpy as np
a = np.arange(10)
b = a[2:7:2] # Equivalent to the slice object in Example 1
print(b)

输出:

[2 4 6]

省略切片参数将使用默认值:省略 start 默认为 0,省略 stop 默认为数组末尾,省略 step 默认为 1。单个索引获取单个项。单独一个冒号 : 选择整个维度。

通过索引访问单个元素。

import numpy as np
a = np.arange(10)
b = a[5] # Access the element at index 5
print(b)

输出:

5

使用 start: 选择从起始索引开始的所有元素。

import numpy as np
a = np.arange(10)
print(a[2:]) # Elements from index 2 to the end

输出:

[2 3 4 5 6 7 8 9]

使用 start:stop 选择指定索引之间的元素(不包括 stop 索引)。

import numpy as np
a = np.arange(10)
print(a[2:5]) # Elements from index 2 up to (not including) index 5

输出:

[2 3 4]

这些切片概念自然地扩展到多维数组,方法是为每个维度提供切片,并用逗号分隔。

将切片应用于二维数组。

import numpy as np
a = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
print("Original array:")
print(a)
# Slice rows starting from index 1 (the second row)
print('\nSlice from row index 1 onwards (a[1:]):')
print(a[1:])
# Slice a specific region: rows 0 to 1, columns 1 to 2
print('\nSlice rows 0:2, columns 1:3 (a[0:2, 1:3]):')
print(a[0:2, 1:3])

输出:

Original array:
[[1 2 3]
[4 5 6]
[7 8 9]]
Slice from row index 1 onwards (a[1:]):
[[4 5 6]
[7 8 9]]
Slice rows 0:2, columns 1:3 (a[0:2, 1:3]):
[[2 3]
[5 6]]

切片还可以包含省略号(ellipsis,...)。省略号会扩展以表示填充维度所需数量的冒号 :。在处理未知或高维度的数组时,这很有用。

演示如何使用省略号选择列或行。

import numpy as np
a = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
print('Original array:')
print(a)
print('\n')
# Select all items in the second column (index 1)
# a[..., 1] is equivalent to a[:, 1]
print('Items in the second column (a[..., 1]):')
print(a[..., 1])
print('\n')
# Select all items in the second row (index 1)
# a[1, ...] is equivalent to a[1, :]
print('Items in the second row (a[1, ...]):')
print(a[1, ...])
print('\n')
# Select all items from the second column onwards
# a[..., 1:] is equivalent to a[:, 1:]
print('Items from column index 1 onwards (a[..., 1:]):')
print(a[..., 1:])

输出:

Original array:
[[1 2 3]
[4 5 6]
[7 8 9]]
Items in the second column (a[..., 1]):
[2 5 8]
Items in the second row (a[1, ...]):
[4 5 6]
Items from column index 1 onwards (a[..., 1:]):
[[2 3]
[5 6]
[8 9]]