Pandas 浅拷贝 vs 深拷贝在DataFrame中的区别
Pandas中最有用的数据结构之一就是Pandas DataFrame,它是一个类似于二维表的结构,包含行和列来存储数据。它允许用户存储和操作数据,非常类似于电子表格或SQL表。
它还提供了一个连续或线性的数据结构,称为一维标记数组,可以包含任何数据类型的元素。
浅拷贝
浅拷贝,正如其名称所示,创建一个引用原始数据的新DataFrame对象。换句话说,浅拷贝指向与原始DataFrame相同的内存位置。对浅拷贝所做的任何修改都会反映在原始DataFrame中,反之亦然。这种行为是由原始对象和拷贝对象之间的共享引用导致的。
语法
pandas.DataFrame.copy(deep=False)
如果’meep=false’,则创建一个DataFrame的浅复制,但不复制数据和索引标签,而是原始DataFrame和新DataFrame都将引用相同的数据和索引标签。
深拷贝
深拷贝是指开发一个非常独立的数据框的副本,其中包括所有的数据和元数据。换句话说,深复制创建一个全新的数据框对象,具有自己的内存空间,独立于原始数据框。
语法
pandas.DataFrame.copy(deep=True)
参数“deep”:是可选的,其默认值设置为True。如果“deep=True”,则创建DataFrame的深拷贝。因此,我们推断出创建了一个新的DataFrame对象,并将所有数据和索引标签从原始DataFrame复制到新的DataFrame中。
示例
在这个代码中,我们将创建一个数据框,并进行深拷贝和浅拷贝,然后使用一些操作修改这三个数据框,并演示原始浅拷贝和深拷贝数据框中的不同变化。
步骤
- 引入pandas库。
-
定义一个包含DataFrame数据的字典。
-
使用数据和pd.DataFrame()方法创建DataFrame df。
-
使用copy()函数,参数分别为deep=False和deep=True,对原始数据框进行浅拷贝和深拷贝。
-
为了查看不同的变化,更改每个数据框中所需的值。
-
打印原始数据框、浅拷贝和深拷贝。
-
显示原始DataFrame及其深拷贝和浅拷贝的ID。
示例
import pandas as pd
# Create a DataFrame
data = {'Name': ['Rahul', 'Priya', 'Amit'],
'Age': [25, 28, 22],
'City': ['Mumbai', 'Delhi', 'Kolkata']}
df = pd.DataFrame(data)
# Shallow copy
shallow_copy = df.copy(deep=False)
# Deep copy
deep_copy = df.copy(deep=True)
# Modify a value in the original DataFrame
df.loc[0, 'Age'] = 30
shallow_copy.loc[1, 'City'] = 'Chennai'
deep_copy.loc[0, 'Age'] = 85
# Print the original DataFrame and its ID
print("Original DataFrame:\n", df)
print("Shallow Copy:\n", shallow_copy)
print("Deep Copy:\n", deep_copy)
print()
print("Original DataFrame ID:", id(df))
print("Shallow Copy ID:", id(shallow_copy))
print("Deep Copy ID:", id(deep_copy))
输出
Original DataFrame:
Name Age City
0 Rahul 30 Mumbai
1 Priya 28 Chennai
2 Amit 22 Kolkata
Shallow Copy:
Name Age City
0 Rahul 30 Mumbai
1 Priya 28 Chennai
2 Amit 22 Kolkata
Deep Copy:
Name Age City
0 Rahul 85 Mumbai
1 Priya 28 Delhi
2 Amit 22 Kolkata
Original DataFrame ID: 140268239802704
Shallow Copy ID: 140269600767952
Deep Copy ID: 140269600767904
这里,通过将第一行的年龄从25岁改为30岁来修改原始DataFrame,并反映在浅拷贝中。浅拷贝的数据没有改变,因此与原始DataFrame是独立的。
当将第二行的城市改为“Chennai”时,它会影响浅拷贝和原始DataFrame。另一方面,深拷贝是完全独立的,所以当将第一行的年龄改为85岁时,它不会影响原始DataFrame。
ID显示原始DataFrame及其副本是具有不同ID的不同对象,但浅拷贝与原始DataFrame共享大部分数据元素的内存空间,除了一些元数据。
因此,我们可以推断出,经过深度复制的对象现在是一个全新的对象,而浅拷贝的对象只是指向原始数据帧的另一个别名指针。
示例
以下代码演示了在pandas中复制国家和其人口的DataFrame的概念,并展示了在原始数据及其浅拷贝和深拷贝中进行更改时的差异。
步骤
- 导入pandas库。
-
使用’Country’和’Population (Millions)’作为键和相应值创建一个名为data的字典数据。
-
使用字典数据创建DataFrame df_original。
-
使用copy()方法和deep=False创建df_original的浅拷贝,并将其赋值给df_shallow_copy。
-
使用copy()方法和deep=True创建df_original的深拷贝,并将其赋值给df_deep_copy。
-
使用loc[]在特定行中修改浅拷贝和深拷贝的值。
-
使用append()方法将新行添加到原始DataFrame df_original和浅拷贝DataFrame df_shallow_copy中。
-
打印原始数据帧及其浅拷贝和深拷贝。
import pandas as pd
# Create a DataFrame
data = {'Country': ['USA', 'Germany', 'Japan'],
'Population (Millions)': [328, 83, 126]}
df_original = pd.DataFrame(data)
# Shallow copy
df_shallow_copy = df_original.copy(deep=False)
# Deep copy
df_deep_copy = df_original.copy(deep=True)
# Modify the shallow copy
df_shallow_copy.loc[0, 'Country'] = 'United States Of America'
df_shallow_copy.loc[1, 'Population (Millions)'] = 82
# Modify the deep copy
df_deep_copy.loc[2, 'Country'] = 'India'
df_deep_copy.loc[2, 'Population (Millions)'] = 1400
# Add a new row to the original DataFrame
new_row = {'Country': 'Canada', 'Population (Millions)': 38}
df_original = df_original.append(new_row, ignore_index=True)
# Print the original DataFrame
print("Original DataFrame:")
print(df_original)
# Print the shallow copy
print("\nShallow Copy:")
print(df_shallow_copy)
# Print the deep copy
print("\nDeep Copy:")
print(df_deep_copy)
# Add a new row to the shallow copy DataFrame
new_row_shallow = {'Country': 'Australia', 'Population (Millions)': 25}
df_shallow_copy = df_shallow_copy.append(new_row_shallow, ignore_index=True)
# Print the modified shallow copy DataFrame
print("\nModified Shallow Copy:")
print(df_shallow_copy)
输出
Original DataFrame:
Country Population (Millions)
0 United States Of America 328
1 Germany 82
2 Japan 126
3 Canada 38
Shallow Copy:
Country Population (Millions)
0 United States Of America 328
1 Germany 82
2 Japan 126
Deep Copy:
Country Population (Millions)
0 USA 328
1 Germany 83
2 India 1400
Modified Shallow Copy:
Country Population (Millions)
0 United States Of America 328
1 Germany 82
2 Japan 126
3 Australia 25
首行的’Country’值从’USA’被修改为 ‘United States Of America’ ,第二行的’Population (Millions)’值从83被修改为82,浅复制反映了这些修改,同时也影响到了原始数据框,而深复制中国家名称从日本修改为印度和人口的改变没有影响到原始数据框。
原始数据框和其浅复制中新添加的行只受各自数据框的影响,因为在复制品中添加新对象是个人的,不会对原始数据框产生影响,反之亦然。
浅复制和深复制的区别
对比项 | 浅拷贝 | 深拷贝 |
---|---|---|
定义 | 创建一个新对象,引用与原对象相同的数据。 | 创建一个完全独立的副本,具有自己的数据和元数据。 |
数据共享 | 在原对象和副本对象之间共享数据。不与原对象共享数据。 | 不与原对象共享数据。 |
内存空间 | 与原对象共享内存空间。 | 拥有自己的内存空间,与原对象分离。 |
可修改性 | 对副本进行的更改可能会影响原对象,反之亦然。但是向数据框添加一个新项目并不能反映在原数据框中。 | 对副本进行的更改不会影响原对象,反之亦然。同样,向数据框添加一个新项目并不能反映在原数据框中。 |
性能 | 更快,需要较少的内存,因为避免了数据的复制。 | 较慢,需要更多的内存,因为会复制数据。 |
结论
当我们希望创建一个与原始DataFrame共享同一内存空间的新DataFrame时,浅拷贝是适用的。当处理大型数据集时,它是高效的,因为它避免了不必要的内存复制。当我们需要创建一个独立的DataFrame副本时,建议使用深拷贝。