代码之家  ›  专栏  ›  技术社区  ›  R zu

out=…参数和numpy中的直接重新分配之间的差异

  •  -1
  • R zu  · 技术社区  · 6 年前

    下面两个可以吗 np.dot 对一个正方形数组给出相同的结果 x ?

    import numpy as np
    x = np.arange(4 * 4).reshape(4, 4)
    np.dot(x, x.T, out=x)  # method 1
    x[:] = np.dot(x, x.T)  # method 2
    

    谢谢。

    为什么我问:

    x += x.T 与…不同 x += x.T.copy()

    我不知道np.dot的内部是如何工作的。 np.dot是否同样将out参数视为视图? 如果out是要相乘的矩阵之一,可以吗?

    我使用的numpy来自anaconda,它使用mkl作为后端。

    3 回复  |  直到 6 年前
        1
  •  3
  •   cs95 abhishek58g    6 年前

    是的,它们是相同的,但从性能上讲,我看到了整数数组的有趣结果:

    import perfplot
    
    def f1(x):
        x = x.copy()
        np.dot(x, x.T, out=x)
        return x
    
    def f2(x):
        x = x.copy()
        x[:] = np.dot(x, x.T)
        return x    
    
    perfplot.show(
        setup=lambda n: np.arange(n * n).reshape(n, n),
        kernels=[f1, f2],
        labels=['out=...', 're-assignment'],
        n_range=[2**k for k in range(0, 9)],
        xlabel='N',
        equality_check=np.allclose
    )
    

    enter image description here

    我已经用过 perfplot 生成绘图计时。


    对于浮点数组,绝对没有区别。

    perfplot.show(
        setup=lambda n: np.arange(n * n).reshape(n, n).astype(float),
        kernels=[f1, f2],
        labels=['out=...', 're-assignment'],
        n_range=[2**k for k in range(0, 9)],
        xlabel='N',
        equality_check=np.allclose
    )
    

    enter image description here

        2
  •  1
  •   Xukrao    6 年前

    是的,两种方法都产生相同的数组。

    import numpy as np
    
    def method_1():
        x = np.arange(4 * 4).reshape(4, 4)
        np.dot(x, x.T, out=x)
        return x
    
    def method_2():
        x = np.arange(4 * 4).reshape(4, 4)
        x[:] = np.dot(x, x.T)
        return x
    
    array_1 = method_1()
    array_2 = method_2()
    
    print(np.array_equal(array_1, array_2))
    

    给出输出:

        3
  •  1
  •   dariox    6 年前

    我安装了一个旧版本的numpy(1.11.0),方法1会产生一些奇怪的输出。我知道这不是预期的行为,在以后的版本中得到了修复;但只是为了防止其他人发生这种情况:

    Python 2.7.12 (default, Dec  4 2017, 14:50:18) 
    [GCC 5.4.0 20160609] on linux2
    >>> import numpy as np
    >>> x = np.arange(4 * 4).reshape(4, 4)
    >>> np.dot(x, x.T, out=x)
    array([[                  14,                   94,                 1011,
                           15589],
           [              115715,          13389961335,         120510577872,
                   1861218976248],
           [              182547,       21820147595568,  1728119013671256390,
             5747205779608970957],
           [              249379,       29808359122268,  7151350849816304816,
            -3559891853923251270]])
    >>> np.version.version
    '1.11.0'
    

    就我所能测试的而言,至少从numpy 1.14.1开始,方法1给出了预期的输出;正如方法2对两个版本所做的那样。