dataframe和list的深浅拷贝以及dataframe中存储list或list中存储dataframe时的深浅拷贝误区

本文讲述下python中dataframe和list的深浅拷贝以及dataframe中存储list或list中存储dataframe时的深浅拷贝误区。dataframe和list的深浅拷贝其实网上资料都有很多了,这个也容易搞懂,但是当dataframe中存储着list时,或list中存储着dataframe时,要注意此时即使进行了深拷贝,也不一定是你所想像的深拷贝。比如dataframe中存储着list时,对dataframe进行了深拷贝,修改list中的元素时,原来的dataframe中的list中的元素也会发生改变,因为本质上深拷贝对datyaframe而言却是是深拷贝,但是此时dataframe中的元素是list的引用,这个并没有进行深拷贝。详细说明还是用代码来进行把,文字解释终归不清楚。(要想完全透彻理解最好学下c语言的指针就可以了)

import copy 
import pandas as pd

1.list的深拷贝与浅拷贝

x = [1,2,3,4,5]
y=x
print(y)
[1, 2, 3, 4, 5]
y[2]=999
x
[1, 2, 999, 4, 5]

因此y=x的方式对于list来说,是做了一个引用,并没有真的拷贝list。

x = [1,2,3,4,5]
y=copy.copy(x)
print(y)
[1, 2, 3, 4, 5]
y[2]=999
x
[1, 2, 3, 4, 5]

因此y=copy.copy(x)的方式对于list来说,是真的做了拷贝。

x = [[1,2],
     [3,4],
     [5,6]]
y=copy.copy(x)
print(y)
[[1, 2], [3, 4], [5, 6]]
y[1][1]=9999
x
[[1, 2], [3, 9999], [5, 6]]
y[0][0]=9999
x
[[9999, 2], [3, 9999], [5, 6]]

因此y=copy.copy(x)的方式对于二维list来说,并没有真正做拷贝,只是做了引用。

x = [[1,2],
     [3,4],
     [5,6]]
y=copy.deepcopy(x)
print(y)
[[1, 2], [3, 4], [5, 6]]
y[1][1]=9999
x
[[1, 2], [3, 4], [5, 6]]

因此y=copy.deepcopy(x)的方式对于二维list来说,是真的做了拷贝。

2.series和dataframe的深拷贝与浅拷贝

df1 = pd.DataFrame([[1,2,3],[6,7,8]])
df2=df1
df2
012
0123
1678
df2[2]=999
df1
012
012999
167999

因此df2=df1的方式对于dataframe来说并没有真正做拷贝,只是做了引用。

df1 = pd.DataFrame([[1,2,3],[6,7,8]])
df2=copy.deepcopy(df1)
df2
012
0123
1678
df2[2]=999
df1
012
0123
1678

因此df2=copy.deepcopy(df1)的方式对于dataframe来说做了真正的拷贝。

s1 = pd.Series([1, 2, 3, 4])
s2=copy.deepcopy(s1)
s2
0    1
1    2
2    3
3    4
dtype: int64
s2[1]=999
s1
0    1
1    2
2    3
3    4
dtype: int64

series与dataframe一样。

s1 = pd.Series([1, 2, 3, 4])
s2=s1.copy()
s2
0    1
1    2
2    3
3    4
dtype: int64
del s2[1]
s1
0    1
1    2
2    3
3    4
dtype: int64
s1 = pd.Series([1, 2, 3, 4])
s2=s1.copy(deep=True)
s2
0    1
1    2
2    3
3    4
dtype: int64
del s2[1]
s1
0    1
1    2
2    3
3    4
dtype: int64

3. dataframe中有list时的深拷贝误区

df1 = pd.DataFrame({'A':[[1,2],[3,4],[5,6]],'B':[[7,8],[9,10],[11,12]]})
df1
AB
0[1, 2][7, 8]
1[3, 4][9, 10]
2[5, 6][11, 12]
df2=df1.copy(deep=True)
df3=copy.deepcopy(df1)
df2
AB
0[1, 2][7, 8]
1[3, 4][9, 10]
2[5, 6][11, 12]
# 现在对df2和df3中的list中的元素做修改
df2.iloc[0,0][0]=999
df3.iloc[1,0][0]=999
df2
AB
0[999, 2][7, 8]
1[999, 4][9, 10]
2[5, 6][11, 12]
df3
AB
0[999, 2][7, 8]
1[999, 4][9, 10]
2[5, 6][11, 12]
df1
AB
0[999, 2][7, 8]
1[999, 4][9, 10]
2[5, 6][11, 12]

可见我明明是对df1进行了深拷贝,可是当我改变深拷贝过来的df2和df3的list中的元素时,df1也会跟着改变,这是为什么呢?

因为我仅仅对dataframe进行了深拷贝,因此我得到了一个新的dataframe,该dataframe和原来的dataframe一样,每个元素存储的都是list的引用,注意是list的引用而不是list,因此我实际上是深拷贝了list的引用,但是并不是把里面的数据都拷贝了一遍,当我修改深拷贝过来的dataframe中的list中的元素时,我是真正的改掉了list中的元素,因此原来的dataframe和深拷贝的dataframe中的每个元素的引用中的元素都被改掉了,这就是出现上述现象的原因。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值