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数组而不复制数据的主要内容,如果未能解决你的问题,请参考以下文章