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 的独立副本时,建议使用深拷贝。

更新于: 2023年8月10日

225 次浏览

开启您的 职业生涯

通过完成课程获得认证

立即开始
广告