NumPy - 数组步长



NumPy 数组步长

在 NumPy 中,步长 是整数元组,表示遍历数组时每个维度需要跨越的字节数。它提供了访问数组中的元素而无需显式复制数据的能力。

步长是根据数组的形状和数据类型计算得出的 -

  • 对于数据类型为 4 字节(例如,int32)的一维数组,步长只是数据类型的大小。
  • 对于多维数组,步长是通过将内部维度的尺寸乘以前一维度的步长来计算的。

在 NumPy 中访问步长

您可以使用strides 属性访问 NumPy 数组的步长。此属性返回一个元组,其中每个值表示在内存中移动以访问沿每个维度下一个元素所需的字节数。

示例

在以下示例中,我们使用 NumPy 的“stride”属性计算数组的步长 -

import numpy as np

# Creating a 2D array
array = np.array([[1, 2, 3], [4, 5, 6]])

# Accessing the strides
print("Array strides:", array.strides)

步长 (24, 8) 表示要从一行移动到下一行,跳过 24 个字节;要从一列移动到下一列,跳过 8 个字节 -

Array strides: (24, 8)

NumPy 步长的工作原理

步长是根据数组的形状和数据类型计算的。对于给定的维度,步长是元素大小(以字节为单位)和后续维度中元素数量的乘积。

对于形状为(m, n) 且数据类型为dtype 的二维数组 -

  • 第一维度的步长:stride[0] = n * size_of(dtype)
  • 第二维度的步长:stride[1] = size_of(dtype)

示例:基本步长

在下面的示例中,我们访问基本一维 NumPy 数组的步长 -

import numpy as np

# Creating a 1D array
array_1d = np.array([1, 2, 3, 4, 5])

# Accessing strides
print("1D Array strides:", array_1d.strides)

步长 (8,) 表示每个元素在内存中相隔 8 个字节,这对于整数数组来说很常见 -

1D Array strides: (8,)

示例:更改步长

转置数组会更改步长,反映新的内存布局,如下面的示例所示 -

import numpy as np

# Creating a 2D array
array_2d = np.array([[1, 2, 3], [4, 5, 6]])

# Transposing the array
array_2d_T = array_2d.T

# Accessing strides
print("Original array strides:", array_2d.strides)
print("Transposed array strides:", array_2d_T.strides)

步长 (8,) 表示每个元素在内存中相隔 8 个字节,这对于整数数组来说很常见 -

Original array strides: (24, 8)
Transposed array strides: (8, 24)

示例:使用步长优化内存

使用步长可以通过允许高效的访问模式来帮助优化内存使用 -

import numpy as np

# Creating a large array
large_array = np.zeros((1000, 1000))

# Accessing every 10th row
strided_array = large_array[::10, :]

print("Strided array shape:", strided_array.shape)
print("Strided array strides:", strided_array.strides)

步长表示我们正在跳过 80,000 个字节(10 行)以访问下一行,从而优化内存访问 -

Strided array shape: (100, 1000)
Strided array strides: (80000, 8)

多维数组中的步长

多维数组中的步长工作方式类似,每个步长值表示相应维度的字节步长。

对于多维数组,每个维度的步长是元素大小与后续维度大小的累积乘积的乘积。

这意味着最后一维的步长只是数据类型的大小,倒数第二维的步长是最后一维的大小乘以数据类型的大小,依此类推。

示例

在下面的示例中,我们计算三维数组的步长 -

import numpy as np

# Creating a 3D array
array_3d = np.zeros((2, 3, 4))

# Accessing strides
print("3D Array strides:", array_3d.strides)

获得的步长显示了每个维度的字节步长 -

3D Array strides: (96, 32, 8)

切片操作的步长

在执行 NumPy 数组的切片操作时,步长非常有用。当您对 NumPy 数组进行切片时,通常会创建一个数组的视图而不是副本。此视图共享相同的基础数据,但可能具有不同的形状或内存布局。

步长决定在内存中跨越多少字节才能沿着每个维度从一个元素移动到下一个元素。通过调整步长,您可以有效地访问特定模式的数据。

NumPy 中的切片操作允许您提取数组的子集,从单个元素到特定部分,而无需复制基础数据。

示例

在此示例中,我们创建了一个大型二维数组,并使用带步长的切片操作访问每第 10 行,而无需复制数据 -

import numpy as np

# Creating a large 2D array
large_array = np.arange(10000).reshape((100, 100))

# Accessing every 10th row
strided_array = large_array[::10, :]

print("Original array shape:", large_array.shape)
print("Strided array shape:", strided_array.shape)
print("Strided array strides:", strided_array.strides)

以下是获得的输出 -

Original array shape: (100, 100)
Strided array shape: (10, 100)
Strided array strides: (4000, 40)
广告