【问题标题】:Fastest way to insert a 2D array into a (larger) 2D array将二维数组插入(更大)二维数组的最快方法
【发布时间】:2017-01-26 17:57:05
【问题描述】:

假设有两个二维数组,ab

import numpy as np
a = np.random.rand(3, 4)
b = np.random.zeros(8, 8)

并且b 在两个轴上总是大于a

(编辑:b 被初始化为一个零数组,以反映所有未被a 占用的元素将保持为零。)

问题。将a“插入”到b 中的最快最Pythonic方式是什么?

到目前为止,我已经尝试了 2 件事:

  1. 使用np.pada“转”成形状数组(8, 8)
  2. 遍历a 中的每一行并将其放置在b 中的相应行中

没有尝试的是使用双重嵌套循环来迭代 a 的每个元素,因为我认为这对性能不友好。

动机。每个数组a 都是一个小字符,我想将每个字符提供给一个接受扁平 形状(8, 8) 数组的神经网络,即。形状为(64,) 的数组。 (我认为我不能简单地将a 扁平化为一维并用零填充它,因为这样它的二维结构就会扭曲,所以我必须首先将其“重塑”为@ 987654340@,对吗?)有几百万个字符。

【问题讨论】:

  • 您在最后一段中提到了用零填充,但在示例中您使用随机值呈现 b。那么你需要什么:a 用来自b 的值填充,或者用零填充?填充在右边和底部吗?
  • “插入”是什么意思?
  • 为什么不b[?:?, ?:?] = a?那就是将b 的匹配块切片作为放置a的地方
  • 您想在 b 的中心或角落或其他地方插入 a 吗?你用 0 填充其他元素还是保持不变?你能举一个 a 和 b 以及结果数组的例子吗?
  • @trincot 哎呀,b 实际上应该是 np.zeros。此外,理想情况下,内边距应该居中,但左上角也不错。

标签: python numpy


【解决方案1】:

我认为最好的方法是使用填充。

如果你想在左上角放置a:

np.pad(a,((0,5),(0,4)),'constant') 

如果你想在中间放置一个:

np.pad(a,((2,3),(2,2)),'constant')

【讨论】:

  • 但是这是最快最自然的方式吗?这不是动态创建一个新数组(我不想这样做)吗?
【解决方案2】:

更一般地,如果您创建切片元组,您可以确定要插入数组的位置(这适用于任意尺寸):

>>> a = np.random.random((5,5))
>>> b = np.ones((3,3))

>>> edge_coordinate = (0,0)
>>> slicer = tuple(slice(edge, edge+i) for edge, i in zip(edge_coordinate, b.shape))
>>> a[slicer] = b
>>> a
array([[ 1.        ,  1.        ,  1.        ,  0.14206495,  0.36385016],
       [ 1.        ,  1.        ,  1.        ,  0.08861402,  0.7888898 ],
       [ 1.        ,  1.        ,  1.        ,  0.1975496 ,  0.13345192],
       [ 0.550487  ,  0.22471952,  0.47050879,  0.04669643,  0.13480528],
       [ 0.25139511,  0.06499812,  0.42247189,  0.05840351,  0.74735495]])

通过改变edge_coordinate,您可以改变位置:

>>> a = np.random.random((5,5))
>>> b = np.ones((3,3))

>>> edge_coordinates = (1,1)  # changed
>>> slicer = tuple(slice(edge, edge+i) for edge, i in zip(edge_coordinates, b.shape))
>>> a[slicer] = b
>>> a
array([[ 0.21385714,  0.68789872,  0.3915475 ,  0.67342566,  0.05642307],
       [ 0.19778658,  1.        ,  1.        ,  1.        ,  0.70717406],
       [ 0.73678924,  1.        ,  1.        ,  1.        ,  0.90285997],
       [ 0.39709332,  1.        ,  1.        ,  1.        ,  0.96959814],
       [ 0.89627195,  0.21295355,  0.72598992,  0.80749348,  0.76660287]])

理想情况下,如果您经常使用它,您可以使用它。

【讨论】:

  • 但这不是花哨的索引,通常会创建一个新数组吗?我只想获得一个先前分配的数组的 view 并写入它。
  • @étale-cohomology 不,切片元组是常规索引并返回视图。
【解决方案3】:

怎么样:

b[:a.shape[0],:a.shape[1]] = a

请注意,我假设 a 将放在 b 的开头,但您可以稍微改进一下以将 a 放在任何位置:

a0,a1=1,1
b[a0:a0+a.shape[0],a1:a1+a.shape[1]] = a

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-27
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多