【问题标题】:Combining two numpy arrays组合两个 numpy 数组
【发布时间】:2020-08-17 15:01:10
【问题描述】:

我有一个尺寸为 (1196, 14, 64, 1) 的 numpy 数组 ar1

我有一个尺寸为 (1196,) 的 numpy 数组 ar2

我想将这两者结合起来,因为我想稍后将它们洗牌。我认为这就是 zip 的用途,但是当我将它们拉在一起时:

ar3 = np.asarray(zip(ar1,ar2))

然后print(ar3.shape) 给出()

我也尝试过np.concatenate,但显然是all the input array dimensions for the concatenation axis must match exactly

我尝试了np.hstack,但我得到了all the input arrays must have same number of dimensions

如何组合这两个沿轴 0 具有相同大小的数组?也许那时我不需要组合,而应该使用相同的索引分别对它们进行洗牌。

(我实际上已经使用 numpy.savez 组合并保存了这些数组,但是当我将此文件加载到我的代码中时,我假设我必须先将它们分开,然后按照我的尝试将它们重新组合到一个数组中。如果我可以从 .npz 文件中提取一个组合数组,那就更好了)

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    np.concatenatenp.broadcast_to 一起使用,因为连接需要所有数组具有相同的维数。这应该可以解决问题:

    x = np.ones((1196, 14, 64, 1))
    y = np.arange(1196)
    output = np.concatenate((x, np.broadcast_to(y[:, None, None, None], x.shape[:-1] + (1,))), axis=-1)
    # output.shape --> (1196, 14, 64, 2)
    

    【讨论】:

      【解决方案2】:
      In [111]: ar1 = np.ones((1196,14,62,1))                                                              
      In [112]: ar2 = np.zeros((1196))  
      

      在 py3 中,zip 类似于生成器。你已经用list 扩展它以获得一个数组:

      In [113]: np.array(zip(ar1,ar2))                                                                     
      Out[113]: array(<zip object at 0x7f188a465a48>, dtype=object)
      

      这是一个单元素数组,形状为 ()。

      如果你展开 zip,并创建一个数组,结果是一个对象 dtype 数组:

      In [119]: A = np.array(list(zip(ar1,ar2)))                                                           
      /usr/local/bin/ipython3:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
        #!/usr/bin/python3
      In [120]: A.shape                                                                                    
      Out[120]: (1196, 2)
      In [121]: A.dtype                                                                                    
      Out[121]: dtype('O')
      In [122]: A[0,0].shape                                                                               
      Out[122]: (14, 62, 1)
      In [123]: A[0,1].shape                                                                               
      Out[123]: ()
      

      一列是 (14,62,1) 数组,另一列是 ar2 值。

      另一个答案建议扩展ar2 以匹配ar1 的形状,并在最后一个轴上连接。结果是ar1 大小的两倍。 broadcast_to 进行“虚拟”复制(不增加内存),但这不会在连接中延续。您将获得每个 ar2 值的 14*62 个副本。

      但是 ar2 可以广播到 (1196,1,62,1) 并在轴 1 上连接(62x 复制),或 (1196,14,1,1) 和轴 2 连接 (14x)。要连接,数组必须在除一个轴之外的所有轴上匹配。

      但是对于savezload,您不需要连接数组。您可以单独保存和加载它们。 savez 将它们放在单独的 npy 文件中。 savez 展示了如何加载每个数组。

      你可以单独洗牌。

      做一个洗牌索引:

      In [124]: idx = np.arange(1196)                                                                      
      In [125]: np.random.shuffle(idx)                                                                     
      In [126]: idx[:10]                                                                                   
      Out[126]: array([ 561,  980,   42,   98, 1055,  375,   13,  771,  832,  787])
      

      并将其应用于每个数组:

      In [127]: ar1[idx,:,:,:];                                                                            
      In [128]: ar2[idx]; 
      

      【讨论】:

        猜你喜欢
        • 2017-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-27
        • 2017-05-26
        • 1970-01-01
        相关资源
        最近更新 更多