python,如何通过copy()获得互不影响的ndarray复制品?
发布于 作者:苏南大叔 来源:程序如此灵动~ 我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...
编程语言越高级,就越容易发生一些不可控的奇异事件。其中,一些奇异事件的典型代表就是变量复制,使用传统的=
操作符对于高级类型的变量来说,不是生成一个新的值,而仅仅是变量引用,是同一个变量!那么,接下来引发的问题就是:改变原值的时候,后面的被等号处理的新变量也发生了改变!
大家好,这里是苏南大叔的程序如此灵动博客,本文讲述python
代码中的ndarray
的变量复制问题。测试环境:win10
,python@3.11.0
,numpy@1.24.2
,pandas@1.5.3
。
问题重现
这里就重现一下"="处理新的变量的情况:
测试用例:
import numpy as np
s = np.array([list("苏南大叔"), ["su", "nan", "da", "shu"]])
s_ = s
s1 = s[1]
s2 = s[0][2]
s[1] = "苏"
s[0][3] = "da"
print(s, type(s)) # 本应该被修改的原版, <class 'numpy.ndarray'>
print(s_, type(s_)) # 不应该被修改的盗版, <class 'numpy.ndarray'>
print(s1, type(s1)) # 不应该被修改的目标切片,['苏' '苏' '苏' '苏'],<class 'numpy.ndarray'>
print(s2, type(s2)) # 不应该被修改的目标切片【实际没被修改】,大 <class 'numpy.str_'>
输出:
[['苏' '南' 'da' '叔']
['苏' '苏' '苏' '苏']] <class 'numpy.ndarray'>
[['苏' '南' 'da' '叔']
['苏' '苏' '苏' '苏']] <class 'numpy.ndarray'>
['苏' '苏' '苏' '苏'] <class 'numpy.ndarray'>
大 <class 'numpy.str_'>
从输出上来看,
- 作为备份的
s_
被修改了,【不符合预期】,numpy.ndarray
类型。 - 作为切片的
s1
被修改了,【不符合预期】,numpy.ndarray
类型。 - 作为切片的
s2
没有被修改,【符合预期】,numpy.str_
类型。
s1
和s2
同时作为切片,一个被修改另外一个确没有被修改,最大的主因就是数据类型。只要是数据类型是ndarray
,使用等号建立的新变量,就是引用,就存在着问题。
解决方案
解决方案就是.copy()
,新的变量的创建使用ndarray.copy()
,而不是使用传统的等号。
import numpy as np
s = np.array([list("苏南大叔"), ["su", "nan", "da", "shu"]])
s_ = s.copy()
s1 = s[1].copy()
s2 = s[0][5].copy()
s[1] = "苏"
s[0][6] = "da"
print(s, type(s)) # 本应该被修改的原版, <class 'numpy.ndarray'>
print(s_, type(s_)) # 不应该被修改的盗版【实际没被修改】, <class 'numpy.ndarray'>
print(s1, type(s1)) # 不应该被修改的切片【实际没被修改】,['su' 'nan' 'da' 'shu'],<class 'numpy.ndarray'>
print(s2, type(s2)) # 不应该被修改的切片【实际没被修改】,大 <class 'numpy.str_'>
输出:
[['苏' '南' 'da' '叔']
['苏' '苏' '苏' '苏']] <class 'numpy.ndarray'>
[['苏' '南' '大' '叔']
['su' 'nan' 'da' 'shu']] <class 'numpy.ndarray'>
['su' 'nan' 'da' 'shu'] <class 'numpy.ndarray'>
大 <class 'numpy.str_'>
从运行结果上来看,使用.copy()
形成的新变量,完全脱离了原变量的控制。原ndarray
的成员修改,并不会影响其复制版变量的值。符合预期。
字符串.copy()
按理说,字符串是没有.copy()
方法的。但是作为ndarray
切片存在的s2
变量是被numpy
包装过的numpy.str_
对象。所以,存在即为合理。
测试用例:
import numpy as np
s = np.str_("苏南大叔")
s_ = s.copy()
s2 = "苏南大叔"
s3 = s2.copy()
错误输出:
Traceback (most recent call last):
File "C:\Users\sunan\Desktop\demo\py\t.py", line 4, in <module>
s3 = s2.copy()
AttributeError: 'str' object has no attribute 'copy'
相关文章
结束语
更多python
相关文章,请点击苏南大叔的相关经验文章链接:
如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。