python - 两个数据框的列表,如果我更改列表(数据框)的元素,数据框会改变
问题描述
我正在研究来自 kaggle 的泰坦尼克号问题。在数据预处理步骤中,我想结合训练和测试数据帧。所以,我做了一个这样的变量组合。
combine = [df_train, df_test]
我看到了不寻常的行为,如果我更改组合变量中的元素,训练和测试数据帧会自动更新。
for dataset in combine:
dataset['Title'] = dataset.Name.str.extract(' ([A-Za-z]+)\.', expand=False)
print(dataset["Title"].unique())
for dataset in combine:
dataset['Title'] = dataset['Title'].replace(['Lady', 'Countess','Capt', 'Col',\
'Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare')
dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss')
dataset['Title'] = dataset['Title'].replace('Ms', 'Miss')
dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs')
完成此操作后,我检查了 df_train,它有“标题”列。
然后,我尝试了这个。如果我通过这样做从 df_train 删除列
df_train = df_train.drop(["Ticket", "Cabin"], axis=1)
df_test = df_test.drop(["Ticket", "Cabin"], axis = 1)
直接从数据框中删除这两列后,组合变量不会自行更新。
我想了解当我更改 combine 变量中的元素时 df_train 是如何更新的。但是,如果我通过删除列直接更改 df_train 和 df_test ,则 combine 变量不会改变。
解决方案
在 Python 中,列表是可变的,每个对象都引用内存中的一些空间。
在这种情况下,您的组合引用与 df_train 和 df_test 相同的内存空间。实际上,您的组合在内存中有自己独特的空间,但它的索引 0 和索引 1 的内存,与 df_train 和 df_test 的内存空间相同。
这是一个例子:
arr_1 = [1, 3, 5]
arr_2 = [3, 6, 7]
arr_3 = [arr_1, arr_2]
print(id(arr_3), id(arr_1))
在这里,两个数组的内存位置不同,这是有道理的。arr_3 在内存中占据唯一的空间。但,
print(id(arr_3[0]), id(arr_1))
显示 arr_3 的第一个索引与 arr_1 具有完全相同的内存地址,这意味着它们都指向同一条数据。
因此,如果您更改 arr_3[0] 或 arr_1 中的任何内容,您将更改相同的数据。这就是可变性的本质。
现在在您的情况下,当您删除一列时,它不会影响组合对象,因为删除没有到位。您正在将 df_train 重新分配给一个新的数据帧,这实际上是内存中的一个新空间。
为避免这种行为,您可以导入复制库,并使用 copy.deepcopy 对两个数据集执行深层复制。深拷贝将为对象分配唯一的内存空间。
推荐阅读
- angular - 如何通过devapp在Ionic 4的firebase存储上上传手机拍摄的照片
- firebase - 用于服务器通信的 GCP Cloud Firestore
- c# - 如何制作一个代码,为数字 x 生成所有整数分区,其中 y 作为 C# 分区中可用的最大数字
- c++ - 无符号字符缓冲区的虚拟输出
- c# - 如何通过 TCP 连接获取 GPS 设备数据 GT06 CONCOX 协议
- c# - 在使用 DataTables 作为源的两个可排序 DataGrids 之间移动行
- c# - ListItem 在 .net 4.0 网络表单下拉列表中不起作用
- ls - grub2 没有列出 iso9660 内容
- c# - C# 统一 if 语句
- android - 显示倒数计时器