创建交互变量的函数:代码有什么问题?

时间:2016-06-24 17:27:57

标签: python function pandas

我在下面写了一个函数,它接受一个数据帧(df)和两个列名(var1var2)作为参数。然后,它为两个变量创建交互变量,并将这些列添加到原始数据帧。代码在我硬编码时起作用,但是当我尝试调用函数时:

create_interactions(my_dataframe, 'variable1', 'variable2')
my_dataframe

我没有收到任何错误,但新列未添加到数据框中 - 它返回原始数据帧。我究竟做错了什么?谢谢。

def create_interactions(df,var1,var2):
    variables = df[[var1,var2]] 
    for i in range(0, variables.columns.size):
        for j in range(0, variables.columns.size):
            col1 = str(variables.columns[i])
            col2 = str(variables.columns[j])
            if i <= j:
                name = col1 + "*" + col2
                df = pd.concat([df, pd.Series(variables[col1] * variables[col2], name=name)], axis=1)

4 个答案:

答案 0 :(得分:2)

你的问题在这一行:

Bird

您正在创建新的数据框并将其分配给变量df = pd.concat([df, pd.Series(variables[col1] * variables[col2], name=name)], axis=1) df不再指向已通过的df。更重要的是,你没有退回它,你认为它编辑了原始的df。为了让它按照您想要的方式运行,请执行以下操作:

df

答案 1 :(得分:2)

执行df = ...不会修改原始df。它只是用你的新df创建一个新的局部变量。

您可以从函数返回df,然后像df = create_interactions(df, 'var1', 'var2')一样使用它。

但如果您确实希望自己的功能修改原始版本df,最好将最后一行更改为:

df[name] = pd.Series(variables[col1] * variables[col2], name=name)

这会将新列插入现有的DataFrame。

您的代码还有其他一些奇怪的事情。您创建了一个名为variables的新变量,该变量只包含原始df的两列。然后你循环range(0, variables.columns.size)。但是,由于您将variables定义为只有两列,variables.columns.size将始终为两列。稍后,您会抓取variables中的列,但df中已存在这些相同的列,因此您可以从df抓取它们。

此外,您的代码会创建每个变量与自身的“交互”,这看起来有点奇怪。我认为您的代码可以简化为:

def create_interaction(df,var1,var2):
    name = var1 + "*" + var2
    df[name] = pd.Series(df[var1] * df[var2], name=name)

由于您只接受两个变量,因此只有一个交互,因此您根本不需要任何循环。 (我将其重命名为create_interaction以表明这一点!:-)只需获取两个指定的变量并将它们相乘。

答案 2 :(得分:1)

您需要检查变量的范围。在create_interactions函数中,您永远不会直接更改数据框。首先,复制数据框:

variables = df[[var1,var2]] 

然后在以下位置分配dataframe变量:

 df = pd.concat([df, pd.Series(variables[col1] * variables[col2], name=name)], axis=1)

这会创建一个新的df,您可以返回。或者,您可以直接更改df,即。 df [&#39; foo&#39;] =&#39; bar&#39;。

答案 3 :(得分:0)

这是一个函数,该函数使用原始列以及唯一的成对的列及其对应的乘积创建一个新的数据框:

def create_interactions(df):
    df_int = df.copy()
    for i in range(0, len(df.columns)-1):
        for j in range(i+1, len(df.columns)):
            name = str(df.columns[i]) + ' * ' + str(df.columns[j])
            df_int.loc[:, name] = df[str(df.columns[i])] * df[str(df.columns[j])]
    return df_int