【问题标题】:Pandas dataframe, comparing weighted values across multiple dataframesPandas 数据框,比较多个数据框的加权值
【发布时间】:2016-10-15 19:58:14
【问题描述】:

我正在尝试在 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

基于此操作,我正在尝试生成一个新的数据框结果,该结果将显示前 3 个选项(最高总和到第三高总和)。

理想情况下,我想做这样的事情:

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() 的 Python 方法是什么?是否可以将其作为数据框公式执行? numpy 是否适合处理这种类型的制表?

【问题讨论】:

    标签: arrays python-2.7 numpy pandas weighted


    【解决方案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
    

    【讨论】:

    • 太棒了。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2020-05-15
    • 2017-03-08
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-03
    • 1970-01-01
    相关资源
    最近更新 更多