当运算和处理数组时,它们的数据有时被拷贝到新的数组有时不是。这通常是新手的困惑之源。这有三种情况:
完全不拷贝
简单的赋值不拷贝数组对象或它们的数据,指向同一内存单元或者变量字符。
import numpy
# 不完全拷贝
'''
指向同一内存单元或者变量字符
'''
a = numpy.arange(12)
b = a
print(b is a)
b.shape = 3, 4
print(a.shape)
def f(x):
'''
Python 传递不定对象作为参考,所以函数调用不拷贝数组。
:param x:
:return: id(x)
'''
print(id(x))
print(id(a))
f(a)
True
(3, 4)
45319896
45319896
视图和浅复制
不同的数组对象分享同一个数据。视图方法创造一个新的数组对象指向同一数据。
视图和源数据,数据用的同一内存,但是组织形式不同。
import numpy
# 视图和浅复制
'''
数据用的同一内存,但是组织形式不同
'''
a = numpy.arange(12)
a.shape = 3, 4
c = a.view()
print("c: ", c)
print("c is a?: ", c is a)
print("c.base is a?: ", c.base is a) # C是A所拥有的数据的视图
print("c.flags.owndata?: ", c.flags.owndata) # C并不拥有数据
print("a.flags.owndata?: ", a.flags.owndata) # A拥有数据
c.shape = 2, 6
print(a.shape)
c[0, 4] = 123 # 视图数据改变,原矩阵数据改变
print("a: ", a)
a[0, 0] = 12
print("c: ", c) # 原矩阵数据改变,视图数据改变
"E:\Python 3.6.2\python.exe" F:/PycharmProjects/test.py
c: [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
c is a?: False
c.base is a?: True
c.flags.owndata?: False
a.flags.owndata?: True
(3, 4)
a: [[ 0 1 2 3]
[123 5 6 7]
[ 8 9 10 11]]
c: [[ 12 1 2 3 123 5]
[ 6 7 8 9 10 11]]
Process finished with exit code 0
深复制
这个复制方法完全复制数组和它的数据,数据和形式复制,新建内存。
import numpy
# 深复制
a = numpy.arange(12)
a.shape = 3, 4
d = a.copy()
print("d is a?: ", d is a)
print("d.base is a?: ", d.base is a)
d[0, 0] = 99
print("a: ", a)
"E:\Python 3.6.2\python.exe" F:/PycharmProjects/test.py
d is a?: False
d.base is a?: False
a: [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
Process finished with exit code 0