Numpy 为什么把a+=b和a=a+b视为不同的操作

Numpy 为什么把a+=b和a=a+b视为不同的操作

在使用Numpy时,我们会遇到一个问题:为什么Numpy把a+=b和a=a+b视为不同的操作?在本文中,我们将深入研究这个问题,并通过示例说明。

阅读更多:Numpy 教程

等式操作的区别

在Numpy中,如果我们执行以下操作:

import numpy as np

a = np.zeros((3,3))
b = np.ones((3,3))
a += b

则a的值将变成一个3×3数组,其值均为1。

然而,如果我们执行以下操作:

import numpy as np

a = np.zeros((3,3))
b = np.ones((3,3))
a = a + b

则a的值将变成一个3×3数组,其值均为1,但这个调用会返回一个不同的数组。

这种行为的原因是,Numpy在执行上述操作时,在内部会创建一个临时数组,用于保存a+b的结果,并在内部计算中使用该临时数组。然后,将a中的值更新为临时数组中的值。这种行为可能会影响性能,因此,Numpy要求在执行类似于a=a+b的操作时,创建一个新的数组,并将其分配给a,而不是在内部使用临时数组。

这里有一个示例,在这个示例中,我们定义了两个 10000×10000 的数组A和B,并计算它们的和。在使用+=操作符时,Numpy几乎可以立即返回结果,但是,使用=操作符时,Numpy则需要显示地创建和分配一个新的数组,并将B的值复制到该数组中。

import numpy as np
import time

# 使用+=进行计算
a = np.zeros((10000,10000))
b = np.ones((10000,10000))

t1 = time.time()
a += b
t2 = time.time()

print("Using += operator: "+str(t2-t1)+" seconds")

# 使用=进行计算
a = np.zeros((10000,10000))
b = np.ones((10000,10000))

t1 = time.time()
a = a + b
t2 = time.time()

print("Using = operator: "+str(t2-t1)+" seconds")

赋值问题

当然,这种行为也会导致其他问题。例如,在Numpy中,如果我们使用=操作符进行赋值,则赋值的是这个对象的一个新副本,而不是地址。这意味着,如果我们更改a,则不会更改b,如下所示:

import numpy as np

a = np.zeros((3,3))
b = a

a += np.ones((3,3))

print(a)
print(b)

这段代码的输出是:

array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])

然而,如果我们使用=进行赋值操作,则无论更改a还是b都会更改另一个变量的值,如下所示:

import numpy as np

a = np.zeros((3,3))
b = a

a = np.ones((3,3))

print(a)
print(b)

这段代码的输出是:

array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])

可变对象的问题

注意,在Numpy中,不可变对象的行为是不同的。例如,如果我们执行以下操作:

a = 1
b = a
a += 1

print(a)
print(b)

这段代码的输出是:

2
1

这是因为在Python中,整数是不可变对象,因此a += 1的结果是创建一个新的整数对象,而不是在原始对象上进行操作。

总结

Numpy在处理a+=b和a=a+b时有所不同,是因为后者需要显示地创建和分配一个新的数组,并将B的值复制到该数组中,可能会影响性能。另外,在Numpy中,使用=进行赋值的行为与Python中不可变对象的行为相同,但在可变对象中则不同。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程