numpy - 步幅如何帮助遍历 numpy 中的数组?

标签 numpy memory numpy-ndarray stride

arr = np.arange(16).reshape((2, 2, 4))

arr.strides
(32, 16, 4)

因此,据我所知,我相信在内存中它会类似于下图。 步幅沿轴标记(在箭头上)。

Initial stacking in memory block

这就是我在使用命令转置其中一个轴后的想法:

arr.transpose((1, 0, 2))

After transposing i.e. switching 2 of the axes

我知道内存块中没有变化,但我无法理解步幅究竟如何帮助遍历内存块中的数组以生成预期的数组。 (是否将不同轴上的元素倒序遍历?)

[[[ 0  1  2  3]
[ 4  5  6  7]] 
[[ 8  9 10 11]
[12 13 14 15]]]

我尝试通过 C 中的官方 numpy 代码来理解,但我无法理解。

如果有人能以更简单的方式提供解释,那就太好了。

最佳答案

除非明确要求(例如使用 axis 参数),否则 Numpy 总是从最大的轴到最小的轴迭代轴(即降序)。因此,在您的示例中,它首先读取内存中偏移量 0 处的 View 项目,然后添加轴 2 的步幅(此处为 4)并读取下一个项目,依此类推,直到到达轴的末端。然后它添加一次轴 1 的步幅并再次重复之前的循环,以此类推其他轴。

内部 Numpy C 代码的行为如下:

// Numpy array are not strongly typed internally.
// The raw memory buffer is always contiguous.
char* data = view.rawData;

const size_t iStride = view.stride[0];
const size_t jStride = view.stride[1];
const size_t kStride = view.stride[2];

for(int i=0 ; i<view.shape[0] ; ++i) {
    for(int j=0 ; j<view.shape[1] ; ++j) {
        for(int k=0 ; k<view.shape[2] ; ++k) {
            // Compute the offset from the view strides
            const size_t offset = iStride * i + jStride * j + kStride * k;

            // Extract an item at the memory offset
            Type item = (Type*)(data + offset);

            // Do something with item here (eg. print it)
        }
    }
}

当您应用转置时,Numpy 会更改步幅,以便交换 iStridejStride。它还会更新形状(view.shape[0]view.shape[1] 也被交换)。代码将执行就像交换两个循环一样,除了内存访问效率较低,因为它们不连续。这是一个例子:

arr = np.arange(16).reshape((2, 2, 4))
arr.strides   # (32, 16, 4)
view = arr.transpose((1, 0, 2))
view.strides  # (16, 32, 4)  <--  note that 16 and 32 have been swapped

请注意,步幅以字节为单位(而不是项目数)。

关于numpy - 步幅如何帮助遍历 numpy 中的数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70366891/

相关文章:

python - -1 在 numpy reshape 中是什么意思?

python - 如何将 ndarray 值附加到特定列的数据帧行中?

python - 使用Python创建三维矩阵结构并写入mat文件

linux - 如何跟踪Linux中进程的CPU/内存使用情况?

python - 获取 scipy.stats 分布的参数名称

r - 强制 R(和 Rstudio)在 Windows 上使用虚拟内存

multithreading - 上下文切换中保存了什么?

python - Numpy 将简单字符串与 numpy 数组的值连接起来

python - 混淆 Pandas 中的日期时间对象

numpy - RAY Python 框架内存不足