从现有列中创建新列,其中输入文件指定要创建/使用的列

时间:2018-11-07 05:12:30

标签: python pandas dataframe

我有一个panda dataframe,其中包含多个索引和一堆列。

我想通过将dataframe中的2个或更多现有列加(减)在一起,来向此dataframe中添加新列。

通过单独的输入csv文件指定新的列名是什么,应使用的列以及应增加还是减少列。

例如:

我的初始数据帧

                 col1  col2   col3   col4
index1  index2
  A       X       10    100    50     20
  B       X       10    200    50     20
  C       X       10    300    50     20

列指令csv / dataframe

                       Factor
newCol      existingCol
  newCol1       col1     1
  newCol1       col2     1
  newCol2       col2     1
  newCol2       col3    -1
  newCol2       col4    -1

此文件显示要创建两个名为newCol1newCol2的新列。要制作newCol1,请在col1col2中添加数据。要使newCol2提取col2中的数据,并减去col3col4

结果数据框应如下所示:

                 col1  col2   col3   col4  newCol1  newCol2
index1  index2
  A       X       10    100    50     20    110       30
  B       X       10    200    50     20    210      130 
  C       X       10    300    50     20    310      230

在读取数据和列文件之前,我不知道列名将是什么或如何将它们组合在一起。

如果dataframe必须是"deindexed",这样做很好,那么在添加新的列数据之后,我总是可以再次为其重新编制索引。

感谢所有帮助。

1 个答案:

答案 0 :(得分:1)

这就是我要做的事情:

import pandas as pd
from io import StringIO

s = StringIO('''    index1  index2          col1  col2   col3   col4
  A       X       10    100    50     20
  B       X       10    200    50     20
  C       X       10    300    50     20 
''')


df1 = pd.read_csv(s, sep='\s+')

s = StringIO('''newCol      existingCol                      Factor
  newCol1       col1     1
  newCol1       col2     1
  newCol2       col2     1
  newCol2       col3    -1
  newCol2       col4    -1
''')
df2 = pd.read_csv(s, sep='\s+')

def add_new_cols(df1, df2):
    for new_col in set(df2.newCol):
        df_temp = df2[df2.newCol == new_col]
        df_temp.reset_index(drop=True, inplace=True)

        df1[new_col] = 0
        for row_ind in range(df_temp.shape[0]):
             df1[new_col] += df_temp.loc[row_ind, 'Factor']*df1.loc[:, df_temp.loc[row_ind, 'existingCol']]

        print(df_temp)
        print('___')

add_new_cols(df1, df2)

将df1修改为所需的形式。尽管这不是最有效的方法,但可以完成工作。

更好的解决方案

首先创建表示公式的字符串,然后在第一个数据帧上使用eval来应用此公式。

# Achieving the same using .eval
for new_col in set(df2.newCol):
    print(new_col)

    df_temp = df2[df2.newCol == new_col]
    df_temp.reset_index(drop=True, inplace=True)

    formula_ = '0'
    for row_ind in range(df_temp.shape[0]):
        if df_temp.loc[row_ind, "Factor"] >= 0:
            formula_ += '+' + f'{df_temp.loc[row_ind, "Factor"]}*{df_temp.loc[row_ind, "existingCol"]}'
        else:
            formula_ +=  f'{df_temp.loc[row_ind, "Factor"]}*{df_temp.loc[row_ind, "existingCol"]}'
    print(formula_)

    df1.eval(f'{new_col}={formula_}', inplace=True)

所需的输出: enter image description here