我有一个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
此文件显示要创建两个名为newCol1
和newCol2
的新列。要制作newCol1
,请在col1
和col2
中添加数据。要使newCol2
提取col2
中的数据,并减去col3
和col4
。
净结果数据框应如下所示:
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"
,这样做很好,那么在添加新的列数据之后,我总是可以再次为其重新编制索引。
感谢所有帮助。
答案 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)