【问题标题】:Numpy broadcast arrayNumpy广播数组
【发布时间】:2010-09-06 11:35:29
【问题描述】:

我在 NumPy 中有以下数组:

A = array([1, 2, 3])

如何获得以下矩阵(没有显式循环)?

B = [ 1 1 1
      2 2 2
      3 3 3 ]

C = [ 1 2 3
      1 2 3
      1 2 3 ]

谢谢!

【问题讨论】:

    标签: python arrays numpy broadcast


    【解决方案1】:

    Edit2:OP 在 cmets 中询问如何计算

    n(i, j) = l(i, i) + l(j, j) - 2 * l(i, j)
    

    我可以想到两种方法。我喜欢这种方式,因为它很容易概括:

    import numpy as np
    
    l=np.arange(9).reshape(3,3)
    print(l)
    # [[0 1 2]
    #  [3 4 5]
    #  [6 7 8]]
    

    这个想法是使用np.ogrid。这定义了两个 numpy 数组的列表,一个是形状 (3,1),一个是形状 (1,3):

    grid=np.ogrid[0:3,0:3]
    print(grid)
    # [array([[0],
    #        [1],
    #        [2]]), array([[0, 1, 2]])]
    

    grid[0] 可以用作索引i 的代理,并且 grid[1] 可以用作索引j 的代理。

    所以在表达式l(i, i) + l(j, j) - 2 * l(i, j) 的任何地方,您只需替换i-->grid[0]j-->grid[1],其余的由numpy 广播处理:

    n=l[grid[0],grid[0]] + l[grid[1],grid[1]] + 2*l
    print(n)
    # [[ 0  6 12]
    #  [10 16 22]
    #  [20 26 32]]
    

    但是,在这种特殊情况下,由于 l(i,i)l(j,j) 只是 l 的对角线元素,您可以这样做:

    d=np.diag(l)
    print(d)
    # [0 4 8]
    

    d[np.newaxis,:]d 的形状提升到 (1,3),并且 d[:,np.newaxis]d 的形状提升到 (3,1)。

    Numpy 广播将 d[np.newaxis,:]d[:,np.newaxis] 提升为 (3,3),并根据需要复制值。

    n=d[np.newaxis,:] + d[:,np.newaxis] + 2*l
    print(n)
    # [[ 0  6 12]
    #  [10 16 22]
    #  [20 26 32]]
    

    Edit1:通常不需要形成BC。 Numpy 广播的目的是允许您使用A 代替BC。如果您向我们展示您打算如何使用 BC,我们也许可以向您展示如何使用 A 和 numpy 广播。


    (原答案):

    In [11]: B=A.repeat(3).reshape(3,3)
    
    In [12]: B
    Out[12]: 
    array([[1, 1, 1],
           [2, 2, 2],
           [3, 3, 3]])
    
    In [13]: C=B.T
    
    In [14]: C
    Out[14]: 
    array([[1, 2, 3],
           [1, 2, 3],
           [1, 2, 3]])
    

    In [25]: C=np.tile(A,(3,1))
    
    In [26]: C
    Out[26]: 
    array([[1, 2, 3],
           [1, 2, 3],
           [1, 2, 3]])
    
    In [27]: B=C.T
    
    In [28]: B
    Out[28]: 
    array([[1, 1, 1],
           [2, 2, 2],
           [3, 3, 3]])
    

    来自恶作剧部门:

    In [57]: np.lib.stride_tricks.as_strided(A,shape=(3,3),strides=(4,0))
    Out[57]: 
    array([[1, 1, 1],
           [2, 2, 2],
           [3, 3, 3]])
    
    In [58]: np.lib.stride_tricks.as_strided(A,shape=(3,3),strides=(0,4))
    Out[58]: 
    array([[1, 2, 3],
           [1, 2, 3],
           [1, 2, 3]])
    

    但请注意,这些是A视图,而不是副本(与上述解决方案一样)。更改B,更改A

    In [59]: B=np.lib.stride_tricks.as_strided(A,shape=(3,3),strides=(4,0))
    
    In [60]: B[0,0]=100
    
    In [61]: A
    Out[61]: array([100,   2,   3])
    

    【讨论】:

    • 我想为所有 i、j 计算 n(i, j) = l(i, i) + l(j, j) - 2 * l(i, j) 并在矩阵 N 中得到结果
    • 非常感谢您的完整回答!
    • ++ for i,j = ogrid[...],一种通用方法。 (你有没有想过收集你的优秀帖子,例如在 scipy.org/Cookbook 下?)
    • @Denis:我很高兴能为scipy.org/Cookbook 做出贡献,但我受到了阻碍。加载首页需要我 133 秒。尽管那里有很多很棒的信息,而且我不确定我的是否符合要求,但从实际情况来看,该网站对我来说是行不通的。
    • @Unutbu,悲伤但真实;必须寻找另一个网站。但是目标很重要。沿着“组织编程 wiki 的建议和示例”行的 SO 问题怎么样:你有组织编程 wiki 的建议、好的例子、好的实践吗?大多数 wiki 都是特定 Q+As 的松散集合;如何将这些内容组织成具有概述、教程和 Q+As 的连贯章节? (是的,这与编程有关——优秀的程序员一起学习。)
    【解决方案2】:

    非常古老的线程,但以防万一有人关心......

    C,B = np.meshgrid(A,A)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-26
      • 1970-01-01
      • 1970-01-01
      • 2017-06-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多