numpy ndarray diagonal()返回值与原数组关联但元素地址不同的疑问
问题:numpy diagonal()返回数组与原数组的引用关系疑惑
我对以下代码的行为感到困惑:我有一个numpy ndarray类型的矩阵mat,通过mat.diagonal()获取它的对角线并赋值给变量diag。修改mat的所有对角线元素为100后,diag的值也同步变成100,这看起来diag是直接引用了mat中的元素。但检查diag[0]和mat[0][0]的内存地址时,二者却不相同。该如何正确理解这一现象?
测试代码
import numpy as np import pandas as pd mat_df = pd.DataFrame(data=[[1,2,3], [4,5,6], [7,8,9]]) print(mat_df) mat = mat_df.values diag = mat.diagonal() print(diag) diag_loc = np.diag_indices_from(mat) mat[diag_loc] = 100 print(diag) print(diag[0]) print(id(diag[0])) print(mat[0][0]) print(id(mat[0][0]))
输出结果
mat初始状态:
0 1 2 0 1 2 3 1 4 5 6 2 7 8 9
初始diag:
[1 5 9]
修改mat后的diag:
[100 100 100]
元素与内存地址:
100 139863357577488 100 139863376059664
解答
1. diagonal()返回的是原数组的视图
numpy的diagonal()方法默认返回原数组的视图(View),它不会复制对角线元素的数据,只是通过特殊的索引映射指向原数组中对应的内存区域。你可以通过以下代码验证这一点:
print(diag.base is mat) # 输出True,说明diag是mat的视图
正因如此,当原数组mat的对角线元素被修改时,diag作为视图会直接反映底层内存的变化,所以值会同步更新。
2. 单个元素访问会创建临时Python标量
当你用diag[0]或mat[0][0]获取单个元素时,numpy会从底层的连续内存中读取数值,然后**创建一个新的Python标量对象(比如int类型)**返回给你。每次访问都会生成新的标量对象,所以这两个100的内存地址不同,但它们的数值都来自原数组同一块内存区域的内容。
内容的提问来源于stack exchange,提问作者captain_willard
相关产品推荐
相关产品推荐

