numpy 深拷贝、浅拷贝和视图总结和例子

numpy 深拷贝、浅拷贝和视图总结和例子

ndarray类的索引和切片方法
组切片得到的是原始数组的视图,所有修改都会直接反映到源数组。如果需要得到的ndarray 切片的一份副本,需要进行复制操作
比如
arange[5:8].copy()

Python的列表序列不同,通过下标范围获取的新的数组是原始数组的一个视图。它与原始数组共享同一块数据空间.

import numpy as np
a=np.arange(10)
a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
b=a[3:7]
b
array([3, 4, 5, 6])
b[2]=-10
b
array([  3,   4, -10,   6])
a
array([  0,   1,   2,   3,   4, -10,   6,   7,   8,   9])
id(b)
1829350963400

数据的浅拷贝与深拷贝

1.深浅拷贝都是对源对象的复制,占用不同的内存空间。

2.不可变类型的对象,对于深浅拷贝毫无影响,最终的地址值和值都是相等的。

3.可变类型的对象:值相等,地址不相等 。

**浅拷贝 **

定义:浅拷贝是对另外一个变量的内存地址的拷贝,这两个变量指向同一个内存地址的变量值。

共享内存地址的两个变量,当其中一个变量的值改变时另一个变量的值也随之改变。此时,变量间的“搓”是
“浅拷贝”

a=np.array([-45,-66,2,25,-33])
b=a
b is a#True
id(a)#2150984309776
id(b)#2150984309776
a==b
array([ True,  True,  True,  True,  True])
a[0]=6
a
array([  6, -66,   2,  25, -33])
b
array([  6, -66,   2,  25, -33])
#如果内存地址不一样
c=np.array([-45,-66,2,99,-33])
d=np.array([-45,-66,2,99,-33])
id(c)#2150984309776
id(d)#2150984307600
c==d
array([ True,  True,  True,  True,  True])
c[1]=666
c
array([-45, 666,   2,  99, -33])
d
array([-45, -66,   2,  99, -33])

浅拷贝-ndarray.view()

共享“视图”(view)的两个变量,当其中一个变量的值改变时,另一个变量的值也随之改变此时,变量间的“拷贝”也是“浅拷贝”

e=np.array([-45,-66,2,25,99,-33])
f=e.view()#f与e“共享视图”
id(e)
1829592944464
id(f)
1829592993928
f.shape=(2,3)
f
array([[-45, -66,   2],
       [ 25,  99, -33]])
e[0]=0
e
array([  0, -66,   2,  25,  99, -33])
f
array([[  0, -66,   2],
       [ 25,  99, -33]])
f[1,1]=88
f
array([[  0, -66,   2],
       [ 25,  88, -33]])
e
array([  0, -66,   2,  25,  88, -33])

深拷贝

Nummpy中的深拷贝—np.copy

定义:一个变量对另外一个变量的值拷贝。

注:拷贝的是目标变量的值,是真实的拷贝,新的变量产生了新的内存地址。

通过“深拷贝”得到的变量互不干扰,其中一个变量的值改变时,不影响其他变量的值。

e
array([  0, -66,   2,  25,  88, -33])
g=np.copy(e)
g
array([  0, -66,   2,  25,  88, -33])
e[0]=8
e
array([  8, -66,   2,  25,  88, -33])
g
array([  0, -66,   2,  25,  88, -33])
id(e)
1829592944464
id(g)
1829592943672
  • 存取元素

    存取元素中的“浅拷贝”与“深拷贝”

    使用整数序列

    当使用整数序列对数组元素进行存取时,将使用整数序列中的每个元素作为下标,整数序列可以是列表或者数组。使用整数序列作为下标获得的数组不和原始数组共享数据空间。

x=np.arange(10,1,-1)
x
array([10,  9,  8,  7,  6,  5,  4,  3,  2])
x[[3,3,1,8]]
array([7, 7, 9, 2])
b=x[np.array([3,3,-3,8])]
b
array([7, 7, 4, 2])
b[2]=100
b
array([  7,   7, 100,   2])
x #由于b和lx不共享数据空间,因此x中的值并没有改变b
array([10,  9,  8,  7,  6,  5,  4,  3,  2])
x[[3,5,1]] = -1,-2,-3 #整数序列下标也可以用来修改元素的值
x
array([10, -3,  8, -1,  6, -2,  4,  3,  2])
  • 当使用布尔数组b作为下标存取数组x中的元素时,将收集数组x中所有在数组b中对应下标为True的元素。使用布尔数组作为下标获得的数组不和原始数组共享数据空间,注意这种方式只对应于布尔数组,不能使用布尔列表。
x=np.arange(5,0,-1)
x
array([5, 4, 3, 2, 1])
x[np.array([True,False,True,False,False])]#布尔数组中下标为0,2的元素为True,因此获取x中下标为0,2的元素
array([5, 3])
x[np.array([True,False,True,True,False])] =-1,-2,-3#布尔数组下标也可以用来修改元素
x
array([-1,  4, -2, -3,  1])
x=np.random.rand(10)#产生一个长度为10,元素值为0-1的随机数的数组
x
array([0.30361704, 0.06640523, 0.1108192 , 0.28438393, 0.81049677,
       0.30720847, 0.73616764, 0.95115896, 0.76405874, 0.75693159])
x[x>0.5]
array([0.81049677, 0.73616764, 0.95115896, 0.76405874, 0.75693159])

  • np.asarray()与np.array()的区别

在numpy中,asarray()函数与array()函数都可迭代对象转换为ndarray类型,它们之间的区别是:

1.当传入的参数是list等一般数组类型时,两者没有区别

a=[1,2,3]

b1=np.array(a) 深拷贝

b2=np.asarray(a)

a[0]=4

print(a)

print(b1)

print(b2)

输入:

[4,2,3]

[1,2,3]

[1,2,3]

2.当传入参数是ndarray类型时,array()函数会拷贝原数据,开辟新的内存在储存它,就是新建了一个ndarray对象。而asarray与原参数共享容一个内存

a = np.arange(3)

bl = np.array (a)

b2 = np.asarray (a)

a[0]=4

print(a)

print(bl)

print(b2)

输出:

[4 1 2]

[0 1 2]

[4 1 2]

从asarray()的源代码也可以看出asarray()和array()的区别:

def asarray (a,dtype-None,order=None,*, like=None):

if like is not None:

    return _ asarray_with_like(a,dtype=dtype,order=order,like=like)
    
    return array(a,dtype,copy=False,order=order)

还可以改变 array()函数的copy参数来控制它是否拷贝传入的数组

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值