为何NumPy数组x做标量乘法后,引用数组y不再与x关联?
为什么NumPy数组标量乘法后引用不再关联?
关键在于两种修改操作的本质完全不同:
1. 索引赋值是原地修改数组对象
当执行x[0] = 0这类操作时,你并没有改变变量x指向的对象——x依然指向最初创建的那个NumPy数组。你只是直接修改了这个数组对象内部存储的元素值。
因为y = x是让变量y和x指向同一个数组对象,所以y自然能看到元素的变化,两者的内存地址(id())也完全一致。
import numpy as np x = np.array([1, 2, 3]) y = x z = np.copy(x) x[0] = 0 print(x) # 输出: array([0, 2, 3]) print(y) # 输出: array([0, 2, 3]) print(id(x) == id(y)) # 输出: True
2. 标量乘法会创建全新的数组对象
x = x * 2操作分为两步:
- 首先,
x * 2会生成一个独立的新NumPy数组,里面的元素是原数组的2倍,这个新数组在内存中拥有单独的地址。 - 然后,
x = ...把变量x的引用从原来的旧数组,重新指向了这个新创建的数组。
而变量y没有被重新赋值,它仍然指向最初的旧数组。此时x和y指向的是两个完全不同的对象,内存地址自然不一样,y的值也不会跟着变化。
import numpy as np x = np.array([1, 2, 3]) y = x z = np.copy(x) x = x * 2 print(x) # 输出: array([2, 4, 6]) print(y) # 输出: array([1, 2, 3]) print(id(x) == id(y)) # 输出: False
补充:想要原地修改的替代写法
如果希望标量乘法后x和y依然关联,可以用原地操作符*=,或者np.multiply的out参数,它们会直接修改原数组的内容,不会创建新对象:
import numpy as np x = np.array([1, 2, 3]) y = x x *= 2 print(x) # 输出: array([2, 4, 6]) print(y) # 输出: array([2, 4, 6]) print(id(x) == id(y)) # 输出: True
内容的提问来源于stack exchange,提问作者Höni
相关产品推荐
相关产品推荐

