我试图在3个或更多不同的数据帧之间进行加权求和。
3个数据帧中的每一个都具有相同的形式。
df1 = pd.DataFrame([
{'rowid':1,'predict1': 'choice1', 'predict2': 'choice2', 'predict3': 'choice3'},
{'rowid':2,'predict1': 'choice4', 'predict2': 'choice5', 'predict3': 'choice1'},
])
df2 = pd.DataFrame([
{'rowid':1,'predict1': 'choice1', 'predict2': 'choice3', 'predict3': 'choice4'},
{'rowid':2,'predict1': 'choice1', 'predict2': 'choice5', 'predict3': 'choice4'},
])
df3 = pd.DataFrame([
{'rowid':1,'predict1': 'choice2', 'predict2': 'choice3', 'predict3': 'choice1'},
{'rowid':2,'predict1': 'choice4', 'predict2': 'choice1', 'predict3': 'choice6'},
])
我正在尝试使用此数据进行计数(基于给定数据帧的权重和给定预测的权重。例如,每个数据帧的权重可能为:
weights_dataframe = { 'df1': 1.1, 'df2': 1.2, 'df3': 0.9 }
weights_predictions= { 'predict1': 1.0, 'predict2': 0.5, 'predict3': 0.333 }
每一行都有一个单独的基于所有数据帧的计数。例如,'choice1','rowid':1的计数器将是:
tally_row1_choice1 = 1.1*1.0 + 1.2*1.0 + 0.9*0.333
基于此操作,我正在尝试生成一个新的数据帧结果,该结果将显示前三个选项(最高总和到第三高总和)。
理想情况下,我想做这样的事情:
tally = getTop3ForEachRow(df1,df2,df3)
result = pd.DataFrame([
{'rowid':1, 'predict1': tally[0][0], 'predict2': tally[0][1], 'predict3': tally[0][2] },
{'rowid':2, 'predict1': tally[1][0], 'predict2': tally[1][1], 'predict3': tally[1][2] }
])
实现getTop3ForEachRow()的pythonic方法是什么?是否可以将其作为数据帧公式? numpy是解决此类制表的适当级别吗?
答案 0 :(得分:1)
def getTop3ForEachRow(df1, df2, df3):
df = pd.concat([d.set_index('rowid') for d in [df1, df2, df3]],
keys=['df1', 'df2', 'df3'])
wghts_df = pd.DataFrame([1.1, 1.2, 0.9], ['df1', 'df2', 'df3'])
wghts_pr = pd.DataFrame([1.0, 0.5, 0.333], ['predict1', 'predict2', 'predict3']).T
wghts = wghts_df.dot(wghts_pr)
wghts_by_group = df.groupby(level='rowid').apply(lambda x: wghts).unstack(0).stack()
bdf = pd.concat([df, wghts_by_group], axis=1, keys=['choices', 'weights'])
bdf1 = bdf.stack().set_index('choices', append=True)
bdf2 = bdf1.groupby(level=[1, 3]).sum().unstack(0)
sort = lambda x: x.sort_values(ascending=False).index
return bdf2.apply(sort).reset_index(drop=True).head(3).values.T
tally = getTop3ForEachRow(df1, df2, df3)
result = pd.DataFrame([
{'rowid':1, 'predict1': tally[0][0], 'predict2': tally[0][1], 'predict3': tally[0][2] },
{'rowid':2, 'predict1': tally[1][0], 'predict2': tally[1][1], 'predict3': tally[1][2] }
])
print result
predict1 predict2 predict3 rowid
0 choice1 choice2 choice3 1
1 choice4 choice1 choice5 2
def getTop3ForEachRow(df1, df2, df3):
# concat all 3 dataframes one after the other while setting
# the rowid as the index
df = pd.concat([d.set_index('rowid') for d in [df1, df2, df3]],
keys=['df1', 'df2', 'df3'])
# wghts_df is a column, wghts_pr is a row.
# the dot product with give all cross multiplied values.
wghts_df = pd.DataFrame([1.1, 1.2, 0.9], ['df1', 'df2', 'df3'])
wghts_pr = pd.DataFrame([1.0, 0.5, 0.333], ['predict1', 'predict2', 'predict3']).T
wghts = wghts_df.dot(wghts_pr)
# I just want to set all cross multiplied weights side
# by side with each rowid
wghts_by_group = df.groupby(level='rowid').apply(lambda x: wghts).unstack(0).stack()
bdf = pd.concat([df, wghts_by_group], axis=1, keys=['choices', 'weights'])
# pivot ['predict1', 'predict2', 'predict3'] into index
# append to index, 'choices'
bdf1 = bdf.stack().set_index('choices', append=True)
# groupby rowid and choices
bdf2 = bdf1.groupby(level=[1, 3]).sum().unstack(0)
# sort descending, take index value (the choice) take top 3
sort = lambda x: x.sort_values(ascending=False).index
return bdf2.apply(sort).reset_index(drop=True).head(3).values.T