【问题标题】:Repeating a Numpy array to match dimension of another array重复一个 Numpy 数组以匹配另一个数组的维度
【发布时间】:2021-10-02 17:45:15
【问题描述】:

我想沿多个维度重复一个数组,使其与另一个数组的维度相匹配。

例如,让我们把:

import numpy as np

a = np.arange(300)
b = np.zeros((300, 10, 20, 40, 50))

我想扩展a 使其与b 的尺寸相匹配,考虑到可以有任意数量的任意长度的尺寸。

目前,我唯一能做的就是在维度上循环,例如:

c = np.copy(a)
for axis, length in enumerate(b.shape[1:]):
  c = np.repeat(c[..., None], length, axis + 1)

但是对于大量维度来说效率相当低......

【问题讨论】:

  • np.tile 可以做到,但它也可以重复 repeats。但它需要完全匹配,还是broadcasting 就足够了?还有一个broadcast_to
  • 问题不仅在于大量的维度,还在于该数组的最终大小。当我测试各种替代方案时(在一台相当普通的机器上),我一直在杀死我的终端。
  • 第一个评论请找原issuehere

标签: python arrays numpy


【解决方案1】:

reshape 和 expand_dims 可以创建一个broadcast 的数组,就像一个b 形状的数组

tile 可以扩展它。检查代码,但我认为它确实像你一样重复了repeats

d=np.tile(np.expand_dims(a,[1,2,3,4]),(1,)+b.shape[1:])

另一种将数组扩展为完整大小但不使用全部内存的方法是:

w = np.broadcast_to(np.expand_dims(a,[1,2,3,4]),b.shape)

w 应该具有相同的形状,但 strides 将是 (8, 0, 0, 0, 0),而 (3200000, 320000, 16000, 400, 8) 则为 bc

但是制作w.copy() 所花费的时间几乎与制作cd 一样长,因为它必须制作完整的 Gb 数组。

【讨论】:

  • 不确定您对w size 的评论是什么意思。我有(c == w).all() 哪个True
【解决方案2】:

一种选择是reshapea,这样它就可以针对b进行广播,然后将值分配给目标数组:

c = np.zeros(b.shape)
c[:] = a.reshape(b.shape[:1] + (1,) * (len(b.shape) - 1))

或者使用np.expand_dims重塑:

c[:] = np.expand_dims(a, axis=tuple(range(1, len(b.shape))))

【讨论】:

    【解决方案3】:

    您可以将np.empty_likenp.copyto 一起使用

    c = np.emtpy_like(b)
    np.copyto(c.T,a)
    
    #check:
    (c == a[:,None,None,None,None]).all()
    # True
    

    或者,如果您想保留 a 的 dtype:

    c = np.empty(b.shape,a.dtype)
    # etc.
    

    【讨论】:

      猜你喜欢
      • 2021-05-07
      • 1970-01-01
      • 1970-01-01
      • 2018-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-05
      • 2019-05-02
      相关资源
      最近更新 更多