Python 输出之间的差异=。。。NumPy中的参数和直接重新分配
以下两个Python 输出之间的差异=。。。NumPy中的参数和直接重新分配,python,arrays,numpy,Python,Arrays,Numpy,以下两个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是要相乘的矩阵之一,可以吗 我使用的
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作为后端。是的,它们是相同的,但从性能角度看,我看到了整数数组的有趣结果:
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
)
我曾经生成过绘图计时
对于浮点数组,绝对没有区别
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
)
是的,它们是相同的,但就性能而言,我看到了整数数组的有趣结果:
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
)
我曾经生成过绘图计时
对于浮点数组,绝对没有区别
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
)
是的,两种方法产生相同的数组
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))
给出输出:
真的
是的,两种方法都生成相同的数组
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))
给出输出:
真的
我安装了一个旧版本的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'
就我所能测试的而言,至少因为numpy1.14.1,方法#1给出了预期的输出;正如方法2对两个版本所做的那样。我安装了一个较旧版本的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'
就我所能测试的而言,至少因为numpy1.14.1,方法#1给出了预期的输出;正如方法#2对两个版本所做的那样。您尝试过吗?您可以检查数组的id,查看是否创建了新对象,并担心未定义的行为。尝试是不够的。它是python后面的c语言。它没有文档记录。我们没有未定义的行为。看到这两种方法是等效的,就等于相信一种方法已经为这项任务完全定义了行为。你认为结果会有所不同吗?是否存在不相似的特定情况?为什么考虑使用第二种情况-x[:]=…
?是否尝试过?您可以检查数组的id,查看是否创建了新对象,并担心未定义的行为。尝试是不够的。它是python后面的c语言。它没有文档记录。我们没有未定义的行为。看到这两种方法是等效的,就等于相信一种方法已经为这项任务完全定义了行为。你认为结果会有所不同吗?是否存在不相似的特定情况?为什么考虑使用第二种情况-x[:]=…
?x=x。copy()
内存分配可能是计时的主要部分。或者不。。。numpy可以秘密地重用它分配的数组。@Rzu我不这么认为,复制不是这里的瓶颈,它的复杂性是线性的,而计算点是O(N^3)。在任何情况下,这两个函数都会进行复制,因此这是公平的。我更担心的是这两种方法是否会产生相同的结果。第一种方法应始终至少与第二种方法一样快,如果不是更快的话。顺便问一下,您的numpy是否使用mkl作为后端?@Rzu I将equality\u check=np.allclose
作为参数添加到perfplot.show
。如果两个方法的输出不同,该函数将抛出一个AssertionError。您将看到没有抛出任何错误,这意味着它是有效的。这是一个没有实际意义的观点,因为它们是相同的操作,在重新分配的方式上有所不同,仅此而已。是的,我的NumPy使用MKL。x=x.copy()
内存分配可能是计时的主要部分。或者不。。。numpy可以秘密地重用它分配的数组。@Rzu我不这么认为,复制不是这里的瓶颈,它的复杂性是线性的,而计算点是O(N^3)。在任何情况下,这两个函数都会进行复制,因此这是公平的。我更担心的是这两种方法是否会产生相同的结果。第一种方法应始终至少与第二种方法一样快,如果不是更快的话。顺便问一下,您的numpy是否使用mkl作为后端?@Rzu I将equality\u check=np.allclose
作为参数添加到perfplot.show
。如果两个方法的输出不同,该函数将抛出一个AssertionError。您将看到没有抛出任何错误,这意味着它是有效的。这是一个没有实际意义的观点,因为它们是相同的操作,在重新分配的方式上有所不同,仅此而已。是的,我的NumPy使用MKL。您的NumPy使用MKL作为后端吗?是的,我的NumPy
构建使用MKL
。您的NumPy使用MKL作为后端吗?是的,我的NumPy
构建使用MKL
。谢谢。我要一个numpy版本>=1.14。谢谢。我会要求一个numpy版本>=1.14。