副本是一个数据的完整的拷贝,如果我们对副本进行修改,它不会影响到原始数据,物理内存不在同一位置。

视图是数据的一个别称或引用,通过该别称或引用亦便可访问、操作原有数据,但原有数据不会产生拷贝。如果我们对视图进行修改,它会影响到原始数据,物理内存在同一位置。

视图一般发生在:

  • 1、numpy 的切片操作返回原数据的视图。
  • 2、调用 ndarray 的 view() 函数产生一个视图。

副本一般发生在:

  • Python 序列的切片操作,调用deepCopy()函数。
  • 调用 ndarray 的 copy() 函数产生一个副本。

1、无复制

简单的赋值不会创建数组对象的副本。 相反,它使用原始数组的相同id()来访问它。 id()返回 Python 对象的通用标识符,类似于 C 中的指针。

此外,一个数组的任何变化都反映在另一个数组上。 例如,一个数组的形状改变也会改变另一个数组的形状。

 import numpy as np
a = np.arange(6)
print('我们的数组是:')
print(a)
print('调用 id() 函数:')
print(id(a))
print('a 赋值给 b:')
b = a
print(b)
print('b 拥有相同 id():')
print(id(b))
print('修改 b 的形状:')
b.shape = (3, 2)
print(b)
print('a 的形状也修改了:')
print(a)

执行结果:

我们的数组是:
[0 1 2 3 4 5]
调用 id() 函数:
1463892179824
a 赋值给 b:
[0 1 2 3 4 5]
b 拥有相同 id():
1463892179824
修改 b 的形状:
[[0 1]
[2 3]
[4 5]]
a 的形状也修改了:
[[0 1]
[2 3]
[4 5]]

2、视图或浅拷贝

ndarray.view() 方会创建一个新的数组对象,该方法创建的新数组的维数更改不会更改原始数据的维数。

 import numpy as np

 # 最开始 a 是个 3X2 的数组
a = np.arange(6).reshape(3, 2)
print('数组 a:')
print(a)
print('创建 a 的视图:')
b = a.view()
print(b)
print('两个数组的 id() 不同:')
print('a 的 id():')
print(id(a))
print('b 的 id():')
print(id(b))
# 修改 b 的形状,并不会修改 a
b.shape = (2, 3)
print('b 的形状:')
print(b)
print('a 的形状:')
print(a)

执行结果:

数组 a:
[[0 1]
[2 3]
[4 5]]
创建 a 的视图:
[[0 1]
[2 3]
[4 5]]
两个数组的 id() 不同:
a 的 id():
2213940021408
b 的 id():
2213969165728
b 的形状:
[[0 1 2]
[3 4 5]]
a 的形状:
[[0 1]
[2 3]
[4 5]]

3、使用切片创建视图修改数据会影响到原始数组:

 import numpy as np
arr = np.arange(12)
print('我们的数组:')
print(arr)
print('创建切片:')
a = arr[3:]
b = arr[3:]
a[1] = 123
b[2] = 234
print(arr)
print(id(a), id(b), id(arr[3:]))

执行结果:

我们的数组:
[ 0 1 2 3 4 5 6 7 8 9 10 11]
创建切片:
[ 0 1 2 3 123 234 6 7 8 9 10

变量 a,b 都是 arr 的一部分视图,对视图的修改会直接反映到原数据中。但是我们观察 a,b 的 id,他们是不同的,也就是说,视图虽然指向原数据,但是他们和赋值引用还是有区别的。

4、副本或深拷贝

ndarray.copy() 函数创建一个副本。 对副本数据进行修改,不会影响到原始数据,它们物理内存不在同一位置。

 import numpy as np
a = np.array([[10, 10], [2, 3], [4, 5]])
print('数组 a:')
print(a)
print('创建 a 的深层副本:')
b = a.copy()
print('数组 b:')
print(b)
# b 与 a 不共享任何内容
print('我们能够写入 b 来写入 a 吗?')
print(b is a)
print('修改 b 的内容:')
b[0, 0] = 100
print('修改后的数组 b:')
print(b)
print('a 保持不变:')
print(a)

执行结果:

数组 a:
[[10 10]
[ 2 3]
[ 4 5]]
创建 a 的深层副本:
数组 b:
[[10 10]
[ 2 3]
[ 4 5]]
我们能够写入 b 来写入 a 吗?
False
修改 b 的内容:
修改后的数组 b:
[[100 10]
[ 2 3]
[ 4 5]]
a 保持不变:
[[10 10]
[ 2 3]
[ 4 5]]

拓展:Python 中 list 的拷贝与 numpy 的 array 的拷贝

1.python中列表list的拷贝,会有什么需要注意的呢?

Python 变量名相当于标签名。

list2=list1 直接赋值,实质上指向的是同一个内存值。任意一个变量 list1(或list2)发生改变,都会影响另一个 list2(或list1)。

list1 = [i for i in range(4)]
list2 = list1
print('原列表为:\n', list1)
print('修改list2:')
list2[0] = 100
print('list1={}\nlist2={}'.format(list1, list2))

执行结果:

原列表为:
[0, 1, 2, 3]
修改list2:
list1=[100, 1, 2, 3]
list2=[100, 1, 2, 3]

17、NumPy——副本和视图的更多相关文章

  1. NumPy 副本和视图

    NumPy 副本和视图 副本是一个数据的完整的拷贝,如果我们对副本进行修改,它不会影响到原始数据,物理内存不在同一位置. 视图是数据的一个别称或引用,通过该别称或引用亦便可访问.操作原有数据,但原有数 ...

  2. NumPy副本和视图

    NumPy - 副本和视图 在执行函数时,其中一些返回输入数组的副本,而另一些返回视图. 当内容物理存储在另一个位置时,称为副本. 另一方面,如果提供了相同内存内容的不同视图,我们将其称为视图. 无复 ...

  3. 吴裕雄--天生自然Numpy库学习笔记:NumPy 副本和视图

    副本是一个数据的完整的拷贝,如果我们对副本进行修改,它不会影响到原始数据,物理内存不在同一位置. 视图是数据的一个别称或引用,通过该别称或引用亦便可访问.操作原有数据,但原有数据不会产生拷贝.如果我们 ...

  4. Numpy常用概念-对象的副本和视图、向量化、广播机制

    一.引言 在我们操作数组的时候,返回的是新数组还是原数组的链接,我们就需要了解对象副本和视图的区别. 向量化和广播是numpy内部实现的基础. 二.对象副本和视图 我们应该注意到,在操作数组的时候返回 ...

  5. Django入门与实践-第17章:保护视图(完结)

    http://127.0.0.1:8000/boards/1/ #boards/views.py from django.contrib.auth.decorators import login_re ...

  6. 数据分析 大数据之路 四 numpy 2

    NumPy 数学函数 NumPy 提供了标准的三角函数:sin().cos().tan(import numpy as np a = np.array([0,30,45,60,90])print (' ...

  7. Python之Numpy详细教程

    NumPy - 简介 NumPy 是一个 Python 包. 它代表 “Numeric Python”. 它是一个由多维数组对象和用于处理数组的例程集合组成的库. Numeric,即 NumPy 的前 ...

  8. 理解numpy中ndarray的内存布局和设计哲学

    目录 ndarray是什么 ndarray的设计哲学 ndarray的内存布局 为什么可以这样设计 小结 参考 博客:博客园 | CSDN | blog 本文的主要目的在于理解numpy.ndarra ...

  9. NumPy 排序、查找、计数

    章节 Numpy 介绍 Numpy 安装 NumPy ndarray NumPy 数据类型 NumPy 数组创建 NumPy 基于已有数据创建数组 NumPy 基于数值区间创建数组 NumPy 数组切 ...

随机推荐

  1. Email常用缩写

    Abbreviations Used in email Abbreviation Meanings ATM at the moment AFAIK as far as I know BTW by th ...

  2. node.js从入门到放弃《什么是node.js》

    1.什么是node.js Node.js是一个后端的Javascript运行环境(支持的系统包括*nux.Windows),这意味着你可以编写系统级或者服务器端的Javascript代码. Node. ...

  3. sqlmap 基本使用步骤(一)

    列出数据据信息:python sqlmap.py -u "http://ctf5.shiyanbar.com/web/index_3.php?id=1" --dbs 列出当前数据库 ...

  4. 调试IPV6

    从Mac分享IPV6 WIFI的方法: 按住opition + 系统设置中的share 进入 如果被拒了要上诉或者回复审核团队邮件,可以参考这个写: 尊敬的APP审查委员会: 您们好!我们希望将自己开 ...

  5. asp.net中的ORA-12154: TNS: 无法解析指定的连接标识符

    本机PL/SQL能正常连接,但是asp.net连接有问题. 临时解决方案: <add key="ConnectString" value="Data Source= ...

  6. Codeforces 846F - Random Query

    原题链接:http://codeforces.com/contest/846/problem/F 题意:给一个数列,任意取区间[l, r],问区间内不同数字的个数的期望是多少. 思路: 对于第i个数a ...

  7. FastDFS整合nginx模块报错

    之前在本地虚拟机用的都是5.1的版本和1.12的nginx,在服务器上尝试一下高版本的6.1 一直报错各种,例如: undeclared (first use in this function) 尝试 ...

  8. 组建MySQL集群的几种方案

    组建MySQL集群的几种方案LVS+Keepalived+MySQL(有脑裂问题?但似乎很多人推荐这个)DRBD+Heartbeat+MySQL(有一台机器空余?Heartbeat切换时间较长?有脑裂 ...

  9. webService接口的py文件打包成exe

    (一)webService接口的py文件打包成exe,在python3.5版本.pyInstaller3.2版本.pywin32-219.win-amd64-py3.5版本打包时报错,原因可能是pyi ...

  10. Jexus 強勁、堅固、免費、易用的Linux ASP.NET服務器

    Jexus 強勁.堅固.免費.易用的Linux ASP.NET服務器 Jexus是一款Linux平台上的高性能WEB服务器和负载均衡网关,以支持ASP.NET.ASP.NET CORE.PHP为特色, ...