首页 > 解决方案 > 两个数据框的列表,如果我更改列表(数据框)的元素,数据框会改变

问题描述

我正在研究来自 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 变量不会改变。

标签: pythondataframe

解决方案


在 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 对两个数据集执行深层复制。深拷贝将为对象分配唯一的内存空间。


推荐阅读