我写了一个函数,该功能以参数为dataframe( df
)及其两个列名( var1
, var2
)。然后,它为两个变量创建交互变量,并将这些列添加到原始数据框架中。当我硬编码时,代码可以工作,但是当我尝试调用函数时:
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)
执行df = ...
不会修改原始DF。它只是使用您的新DF制造了一个新的本地变量。
您可以从功能返回df
,然后像df = create_interactions(df, 'var1', 'var2')
一样使用它。
但是,如果您确实希望您的功能修改原始df
,则最好将最后一行更改为:
df[name] = pd.Series(variables[col1] * variables[col2], name=name)
这将插入新列中的现有数据框。
关于您的代码还有其他奇怪的事情。您创建一个称为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
来指示这一点!
您的问题在此行中:
df = pd.concat([df, pd.Series(variables[col1] * variables[col2], name=name)], axis=1)
您正在创建一个新的数据框架并将其分配给变量df
。df
不再指向通过的df
。更重要的是,您不返回它,您假设它编辑了原始df
。为了使其按照您想要的方式行事,请执行此操作:
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.loc[:, name] = variables[col1] * variables[col2]
您需要在变量上检查范围。在create_interactions函数中,您永远不会直接更改数据框架。首先,您将数据框架复制在:
中variables = df[[var1,var2]]
然后,您在以下位置分配了数据帧变量:
df = pd.concat([df, pd.Series(variables[col1] * variables[col2], name=name)], axis=1)
这将创建一个新的DF,您可以返回。另外,您可以直接更改DF,即。df ['foo'] ='bar'。
这是一个函数,该函数使用原始列以及独特的列对创建新的数据帧及其相应的产品:
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