如何使用for循环在一组数据帧上运行操作?

时间:2019-04-03 09:17:58

标签: python loops dataframe for-loop concat

这是我遇到的一个普遍问题,但我将以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循环时,则没有任何反应。我想念什么?

1 个答案:

答案 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,4l = [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就是这样做的。它是直接修改数据框,而不是创建它的副本。