为何np.multiply使用out=test[mask]无法实现原地操作?
为什么NumPy布尔索引的原地
multiply操作不生效? 核心原因是:布尔索引返回的是原数组的副本,而非视图。
问题重现
先还原你的测试代码:
import numpy as np test = np.arange(0, 10).reshape(2, 5) mask = test > 5 # 正常生效的操作 np.multiply(test, 3, out=test) # Output: # [[ 0 3 6 9 12] # [15 18 21 24 27]] # 重置原数组后测试不生效的操作 test = np.arange(0, 10).reshape(2, 5) np.multiply(test[mask], 3, out=test[mask]) print(test) # Output: # [[0 1 2 3 4] # [5 6 7 8 9]]
具体解释
- 直接操作整个数组
test时,np.multiply(..., out=test)是在原数组的内存空间上直接修改,所以改动会直接体现在原数组中。 - 但使用布尔索引
test[mask]时,NumPy会创建一个包含筛选后元素的临时副本——可以通过代码验证这一点:
所以# 切片返回的是视图,和原数组共享内存 arr_slice = test[:, :3] print(arr_slice.base is test) # 输出True # 布尔索引返回的是独立副本,不共享内存 arr_mask = test[mask] print(arr_mask.base is test) # 输出Falsenp.multiply(test[mask], 3, out=test[mask])实际上是把计算结果写入了这个临时副本,原数组的内存完全没被改动。语句执行完毕后临时副本被销毁,原数组自然没有变化。
正确写法
要实现对布尔筛选后的元素原地乘以3,直接用索引赋值即可:
test[mask] *= 3 # 或者等价写法 test[mask] = test[mask] * 3
这种方式会直接把计算结果写回原数组的对应内存地址,原数组会被正确修改。
内容的提问来源于stack exchange,提问作者LionCereals
相关产品推荐
相关产品推荐

