【问题标题】:How to add multiple extra columns to a NumPy array如何向 NumPy 数组添加多个额外的列
【发布时间】:2018-09-01 21:28:55
【问题描述】:

假设我有两个 NumPy 数组,ab

a = np.array([
    [1, 2, 3],
    [2, 3, 4]
    ])

b = np.array([8,9])

我想将相同的数组 b 附加到每一行(即添加多列)以获得一个数组 c

b = np.array([
    [1, 2, 3, 8, 9],
    [2, 3, 4, 8, 9]
    ])

如何在 NumPy 中轻松高效地完成这项工作?

我特别担心它在大数据集上的行为(其中ab 大得多),有没有办法创建b 的多个副本(即a.shape[0])?

this question 相关,但具有多个值。

【问题讨论】:

    标签: python arrays numpy data-science


    【解决方案1】:

    这是一种方法。我认为它是有效的,因为它是矢量化的。它依赖于这样一个事实,即在矩阵乘法中,将行与列 (1, 1) 预乘将产生该行的两个堆叠副本。

    import numpy as np
    
    a = np.array([
        [1, 2, 3],
        [2, 3, 4]
        ])
    
    b = np.array([[8,9]])
    
    np.concatenate([a, np.array([[1],[1]]).dot(b)], axis=1)
    
    Out: array([[1, 2, 3, 8, 9],
                [2, 3, 4, 8, 9]])
    

    请注意,b 的指定方式略有不同(作为二维数组)。

    有没有办法创建多个 b 的副本?

    最终结果包含那些副本(numpy 数组实际上是内存中的值数组),所以我不知道如何。

    【讨论】:

    • 虽然这听起来不太像 Python,但可以想象 'b' 的值将存储在磁盘上,而 'c' 仅包含指向指向值的指针数组的指针'b'。
    • 是的——不过,使用此类对象的操作速度较慢,这就是我所知道的numpy 使用简单的连续值数组的原因。
    • 是否可以概括您的答案,例如对于给定的 'n' 和 'm,'a' 的尺寸是 '[3,3]' 或 '[n,m]' '?
    • 当然,它只要求向量的向量与a的高度相同,即np.ones([1, a.shape[0]], dtype=int)
    • 我明白了,但那不是np.ones([a.shape[0],1], dtype=int)吗?
    【解决方案2】:

    concatenate 的替代方法是创建一个接收者数组,并将值复制到其中:

    In [483]: a = np.arange(300).reshape(100,3)
    In [484]: b=np.array([8,9])
    In [485]: res = np.zeros((100,5),int)
    In [486]: res[:,:3]=a
    In [487]: res[:,3:]=b
    

    采样时间

    In [488]: %%timeit
         ...: res = np.zeros((100,5),int)
         ...: res[:,:3]=a
         ...: res[:,3:]=b
         ...: 
         ...: 
    6.11 µs ± 20.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    
    In [491]: timeit np.concatenate((a, b.repeat(100).reshape(2,-1).T),1)
    7.74 µs ± 15.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    
    In [164]: timeit np.concatenate([a, np.ones([a.shape[0],1], dtype=int).dot(np.array([b]))], axis=1) 
    8.58 µs ± 160 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    

    【讨论】:

      【解决方案3】:

      我最初解决这个问题的方法是:

      c = np.concatenate([a, np.tile(b, (a.shape[0],1))], axis = 1)
      

      但这感觉效率很低……

      【讨论】:

      • 没有 Python 级别的循环!应该是a.shape[0] 不是吗?
      • 一组快速的时间表明repeat 是创建 (n,2) 数组的最快方法:b.repeat(n).reshape(2,-1).Trepeat 是内置的。
      猜你喜欢
      • 2012-01-19
      • 1970-01-01
      • 2019-05-15
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      • 2019-06-25
      相关资源
      最近更新 更多