Pandas DataFrame 中浅拷贝与深拷贝的区别
Pandas 中最实用的数据结构之一是 Pandas DataFrame,它是一个二维表格状结构,包含行和列来存储数据。它允许用户存储和操作数据,非常类似于电子表格或 SQL 表格。
它还提供了一个称为一维标记数组的串行或线性数据结构,可以保存任何数据类型的元素。
浅拷贝
顾名思义,浅拷贝创建一个新的 DataFrame 对象,该对象引用原始数据。换句话说,浅拷贝指向与原始 DataFrame 相同的内存位置。对浅拷贝所做的任何修改都会反映在原始 DataFrame 中,反之亦然。这种行为是由于原始对象和复制对象之间共享引用造成的。
语法
pandas.DataFrame.copy(deep=False)
如果 'deep=False',则创建 DataFrame 的浅拷贝,但数据和索引标签不会被复制,相反,原始 DataFrame 和新 DataFrame 都将引用相同的数据和索引标签。
深拷贝
深拷贝是指创建 DataFrame 的一个完全独立的副本,包括其所有数据和元数据。换句话说,深拷贝创建一个具有其自身内存空间的全新 DataFrame 对象,使其独立于原始 DataFrame。
语法
pandas.DataFrame.copy(deep=True)
参数“deep”:是可选的,其默认值为 True。如果 'deep=True',则创建 DataFrame 的深拷贝。因此,我们推断创建一个新的 DataFrame 对象,并将所有数据和索引标签从原始 DataFrame 复制到新 DataFrame。
示例
在此代码中,我们将创建一个 DataFrame 并进行深拷贝和浅拷贝,然后使用一些操作修改这三个 DataFrame,并演示原始 DataFrame、浅拷贝和深拷贝的不同变化。
算法
导入 pandas 库。
定义一个包含 DataFrame 数据的字典。
使用数据和 pd.DataFrame() 方法创建 DataFrame df。
使用 copy() 函数以及参数 deep=False 和 deep=True,创建原始 DataFrame 的浅拷贝和深拷贝。
要查看各种更改,请更改每个 DataFrame 中任何所需的值。
打印原始 DataFrame、浅拷贝和深拷贝。
我们显示原始 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
在这里,原始 DataFrame 通过将第一行的年龄从 25 更改为 30 来修改,这也会反映在浅拷贝中。浅拷贝的数据没有更改,因此独立于原始 DataFrame。
同样,当第二行的城市更改为“Chennai”时,它会影响浅拷贝和原始 DataFrame。另一方面,深拷贝是完全独立的,因此当第一行的年龄更改为 85 时,它不会影响原始 DataFrame。
ID 显示原始 DataFrame 及其副本是具有不同 ID 的不同对象,但浅拷贝确实与原始 DataFrame 共享大多数数据元素的内存空间,除了某些元数据。
因此,我们推断,深度复制的对象现在是一个全新的对象,而浅拷贝对象只是一个指向原始 DataFrame 的另一个别名指针。
示例
以下代码演示了在 pandas 中复制国家和人口 DataFrame 的概念,并展示了在原始 DataFrame 及其浅拷贝和深拷贝中进行更改时,浅拷贝和深拷贝之间的区别。
算法
导入 pandas 库。
创建一个字典数据,其中“国家”和“人口(百万)”作为键,并具有相应的键值。
使用字典数据创建一个 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。
打印原始 DataFrame 及其浅拷贝和深拷贝。
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
第一行的“国家”值从“USA”修改为“United States Of America”,第二行的“人口(百万)”值从 83 修改为 82,这反映在浅拷贝以及原始 DataFrame 中,而将深拷贝中的国家名称从 japan 更改为 India 以及其人口并不会影响原始 DataFrame。
原始 DataFrame 及其浅拷贝中新添加的行仅受其各自的 DataFrame 影响,因为在副本中添加新对象是私人的,不会影响原始 DataFrame,反之亦然。
浅拷贝和深拷贝的区别
浅拷贝 | 深拷贝 | |
---|---|---|
定义 | 创建一个新对象,该对象引用与原始对象相同的数据。 | 创建一个具有自身数据和元数据的完全独立的副本。 |
数据共享 | 在原始对象和复制对象之间共享数据。不与原始对象共享数据。 | 不与原始对象共享数据。 |
内存空间 | 与原始对象共享内存空间。 | 拥有独立于原始对象的内存空间。 |
可修改性 | 对副本进行的更改可能会影响原始对象,反之亦然。但是,添加特定于 DataFrame 的新项不会反映在原始 DataFrame 上。 | 对副本进行的更改不会影响原始对象,反之亦然。同样,添加特定于 DataFrame 的新项不会反映在原始 DataFrame 上。 |
性能 | 速度更快,并且需要更少的内存,因为它避免了复制数据。 | 速度较慢,并且需要更多内存,因为它需要复制数据。 |
结论
当我们想要创建一个与原始 DataFrame 共享相同内存空间的新 DataFrame 时,浅拷贝很合适。在处理大型数据集时,它效率更高,因为它避免了不必要的内存复制。当我们需要创建 DataFrame 的独立副本时,建议使用深拷贝。