python - 重复numpy数组而不复制数据

Posted

技术标签:

【中文标题】python - 重复numpy数组而不复制数据【英文标题】:python - repeating numpy array without replicating data 【发布时间】:2014-07-04 22:34:08 【问题描述】:

之前有人问过这个问题,但该解决方案仅适用于 1D/2D 数组,我需要一个更一般的答案。

如何在不复制数据的情况下创建重复数组?这让我觉得这是一种通用的东西,因为它有助于在不影响内存的情况下对 python 操作进行矢量化。

更具体地说,我有一个 (y,x) 数组,我想多次平铺该数组以创建一个 (z,y,x) 数组。我可以用 numpy.tile(array, (nz,1,1)) 做到这一点,但我的内存不足。我的具体情况是 x=1500, y=2000, z=700。

【问题讨论】:

你打算用更大的数组做什么? array[None,:,:] 可能与平铺数组一样有用。除非您在 y 或 x 维度上执行某种 dot 产品,否则您仍然可能会出现内存错误。 我必须以 (time, y, x) 的形式将地理掩码应用于地球物理数据集。我正在使用的模块要求掩码与数据集的形状相同,这就是为什么我需要将 (y,x) 掩码复制到时间维度上。 【参考方案1】:

一个简单的技巧是使用np.broadcast_arrays 在第一维中针对z-long 向量广播您的(x, y)

import numpy as np

M = np.arange(1500*2000).reshape(1500, 2000)
z = np.zeros(700)

# broadcasting over the first dimension
_, M_broadcast = np.broadcast_arrays(z[:, None, None], M[None, ...])

print M_broadcast.shape, M_broadcast.flags.owndata
# (700, 1500, 2000), False

要概括为this answer 中的一维数组提供的stride_tricks 方法,您只需包含输出数组每个维度的形状和步长:

M_strided = np.lib.stride_tricks.as_strided(
                M,                              # input array
                (700, M.shape[0], M.shape[1]),  # output dimensions
                (0, M.strides[0], M.strides[1]) # stride length in bytes
            )

【讨论】:

广播的事情正是我想要的。在我看来,它比 stride_tricks 方法更简单/更合乎逻辑。 内部broadcast_arrays 正是以这种方式使用as_strided。查看numpy/lib/stride_tricks.py。这是第一个维度的0 步幅长度。 stride length in bytes 行应该是 (0, M.strides[0], M.strides[1]) @hpaulj 这很有趣,尽管我确信直接使用 stride_tricks 仍然比分配另一个数组来广播更有效。 M[None,:,:]shape: (1,...)strides: (0,..)。步幅相同,但在新的形状维度中只是一个1

以上是关于python - 重复numpy数组而不复制数据的主要内容,如果未能解决你的问题,请参考以下文章

将numpy结构化数组子集转换为numpy数组而不复制

连接 Numpy 数组而不复制

将相同numpy数组的两个视图组合成单个视图而不复制数组?

Python Numpy追加数组而不展平

使用numpy数组更改python pandas数据框切片中的元素[重复]

Numpy基础:数组和矢量计算