NumPy数组切片赋值后变量值同步变化原因及正确更新方法
问题原因
NumPy 中使用基础切片语法(比如你代码里的SP[:,0])获取的子数组是原数组的视图,不是独立拷贝,二者共享同一块内存空间。
你执行SP0 = SP[:,0]时,并没有把第一列的数据复制一份存到新变量里,只是让SP0指向了SP第一列对应的内存地址。后续修改SP[:,0]的值时,本质是修改这块共享内存里存储的数据,SP0读取到的自然就是更新后的值,这是NumPy为了降低内存占用、提升运算速度做的默认设计。
解决方法
你可以任选以下一种方式实现需求:
- 方法1:赋值暂存原始值时显式调用
.copy()生成独立副本,后续修改原数组不会影响副本内容
import numpy as np from math import cos, sin SP = np.array([[-0.4,.2,1],[-.34,.31,1],[-.22,-.2,0],[.8,.25,0],[.92,-.42,1]]) dt = 0.1 # 显式拷贝第一列的原始值,生成独立数组 SP0 = SP[:, 0].copy() SP[:,0] = SP[:,0] * cos(dt) + SP[:,1] * sin(dt) SP[:,1] = SP[:,1] * cos(dt) - SP0 * sin(dt)
- 方法2:先基于原始值计算完两列的所有新结果,再统一赋值回原数组,全程不覆盖计算需要用到的原始值,不需要额外拷贝
import numpy as np from math import cos, sin SP = np.array([[-0.4,.2,1],[-.34,.31,1],[-.22,-.2,0],[.8,.25,0],[.92,-.42,1]]) dt = 0.1 # 所有计算都基于原始值完成,不提前修改原数组 new_col0 = SP[:,0] * cos(dt) + SP[:,1] * sin(dt) new_col1 = SP[:,1] * cos(dt) - SP[:,0] * sin(dt) # 计算全部结束后再更新原数组 SP[:,0], SP[:,1] = new_col0, new_col1
- 方法3:针对你代码里的二维坐标旋转场景,直接用旋转矩阵做矩阵运算,逻辑更简洁,也不会出现值覆盖问题
import numpy as np SP = np.array([[-0.4,.2,1],[-.34,.31,1],[-.22,-.2,0],[.8,.25,0],[.92,-.42,1]]) dt = 0.1 # 构造二维旋转矩阵 rot_matrix = np.array([ [np.cos(dt), np.sin(dt)], [-np.sin(dt), np.cos(dt)] ]) # 对前两列坐标批量做旋转变换 SP[:, :2] = SP[:, :2] @ rot_matrix
内容的提问来源于stack exchange,提问作者Lost
相关产品推荐
相关产品推荐

