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

问题描述 投票:1回答:1

这是我遇到的一般问题,但我将以泰坦尼克号数据集为例。为了允许在列车和测试装置上进行操作,我将它们组合在一起:

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循环时,没有任何事情发生。我错过了什么?

python loops dataframe for-loop concat
1个回答
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正是这样做的。它正在直接修改数据框,而不是创建它的副本。

© www.soinside.com 2019 - 2024. All rights reserved.