这是我遇到的一个普遍问题,但我将以Titanic数据集为例。为了允许同时在火车和测试台上进行操作,我将它们组合在一起:
combined = [train_df, test_df]
我还简化了每个乘客的标题,因此每个标题现在是8种可能之一。对于train_df和test_df,我现在都想为“标题”列创建虚拟变量,将它们添加到数据框中,然后删除原始的“标题”列。我建议的代码是:
for df in combined:
df = pd.concat([df,pd.get_dummies(df.Title)],axis=1)
df = df.drop('Title',axis=1)
当我在单个数据帧上手动执行这些操作时,这些操作确实起作用,但是在运行for循环时,则没有任何反应。我想念什么?
答案 0 :(得分:0)
这不起作用,因为您正在修改列表中变量的副本,并且永远不要将其分配回列表中。
例如:
a = [0,1,2,3]
for i in a:
i = i+1
a
>>> [0, 1, 2, 3]
您需要的是访问列表的元素:
a = [0,1,2,3]
for i in range(len(a)):
a[i] = a[i]+1
a
>>> [1, 2, 3, 4]
或更简单的方式:
a = [0,1,2,3]
a = [i+1 for i in a]
a
>>> [1, 2, 3, 4]
所以在您的情况下:
for df in range(len(combined)):
combined[df] = pd.concat([combined[df],pd.get_dummies(combined[df].Title)],axis=1)
combined[df] = combined[df].drop('Title',axis=1)
或更简单的方式(使用迭代器免费编制索引)
combined = [pd.concat([df,pd.get_dummies(df.Title)],axis=1).drop('Title',axis=1) for df in combined]
编辑
似乎您对python中的内存如何工作以及如何更新变量有误解。
让我们a,b = 3,4
和l = [a,b]
,然后更改a或b将不更改l。一旦创建,它将独立于a和b生存。因此,请串联。因此,更新列表不会更新用于创建列表的变量。您必须将新值分配给变量。为此,由于您不希望列表在使用后存在,因此最好的方法是执行一个功能:
def my_func(df):
df = pd.concat([df,pd.get_dummies(df.Title)],axis=1)
df = df.drop('Title',axis=1)
return df
,然后将其应用于两个数据框:
train_df = my_func(train_df)
test_df= my_func(test_df)
第二次修改:
那为什么起作用呢?再说一次关于内存如何在python中工作的问题,尤其是迭代器。我们将不详细介绍,但让我们以列表为例(类似于此处的数据框):
a = [[0,1],[2,3,4]]
for i in a:
i.pop(0)
a
>>> [[1], [3, 4]]
您看到我们已经修改了列表内的变量。这是因为我们在任何时候都没有创建迭代器的命名副本。我们在内存中修改了当前对象。因此,使用Inplace=True
就是这样做的。它是直接修改数据框,而不是创建它的副本。