我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

编程语言越高级,就越容易发生一些不可控的奇异事件。其中,一些奇异事件的典型代表就是变量复制,使用传统的=操作符对于高级类型的变量来说,不是生成一个新的值,而仅仅是变量引用,是同一个变量!那么,接下来引发的问题就是:改变原值的时候,后面的被等号处理的新变量也发生了改变!

苏南大叔:python,如何通过copy()获得互不影响的ndarray复制品? - ndarray-复制品
python,如何通过copy()获得互不影响的ndarray复制品?(图4-1)

大家好,这里是苏南大叔的平行空间笔记本博客,本文讲述python代码中的ndarray的变量复制问题。测试环境:win10python@3.11.0numpy@1.24.2pandas@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_类型。

苏南大叔:python,如何通过copy()获得互不影响的ndarray复制品? - ndarray-copy-测试用例
python,如何通过copy()获得互不影响的ndarray复制品?(图4-2)

s1s2同时作为切片,一个被修改另外一个确没有被修改,最大的主因就是数据类型。只要是数据类型是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_'>

苏南大叔:python,如何通过copy()获得互不影响的ndarray复制品? - ndarray-copy-解决方案
python,如何通过copy()获得互不影响的ndarray复制品?(图4-3)

从运行结果上来看,使用.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,如何通过copy()获得互不影响的ndarray复制品? - numpy-str_-copy
python,如何通过copy()获得互不影响的ndarray复制品?(图4-4)

相关文章

结束语

更多python相关文章,请点击苏南大叔的相关经验文章链接:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python