每次两个值匹配时求和

时间:2019-04-25 04:18:27

标签: python pandas dataframe

我的Google搜索使我失败了,我认为我的主要问题是不确定如何表达该问题(对不起的标题)。我试图每次有2个人以相同的方式投票时得出总数。在下面,您将看到一个有关数据外观和我一直在寻找的输出的示例。我有一个可行的解决方案,但它的速度非常慢(请参阅底部),并且想知道是否有更好的方法可以解决此问题。

This is how the data is shaped

----------------------------------
event   person  vote
 1        a      y
 1        b      n
 1        c      nv
 1        d      nv
 1        e      y
 2        a      n
 2        b      nv
 2        c      y
 2        d      n
 2        e      n
----------------------------------

This is the output im looking for

----------------------------------
Person  a   b   c   d   e
   a    2   0   0   1   2
   b    0   2   0   0   0
   c    0   0   2   1   0
   d    1   0   1   2   1
   e    2   0   0   1   2
----------------------------------


工作代码

df = df.pivot(index='event', columns='person', values='vote')

frame = pd.DataFrame(columns=df.columns, index=df.columns)

for person1, value in frame.iterrows():

    for person2 in frame:

        count = 0 
        for i, row in df.iterrows():

            person1_votes = row[person1]
            person2_votes = row[person2]

            if person1_votes == person2_votes:
                count += 1

        frame.at[person1, person2] = count

2 个答案:

答案 0 :(得分:3)

尝试以其他方式查看您的问题

df=df.assign(key=1)
mergedf=df.merge(df,on=['event','key'])
mergedf['equal']=mergedf['vote_x'].eq(mergedf['vote_y'])
output=mergedf.groupby(['person_x','person_y'])['equal'].sum().unstack()
output
Out[1241]: 
person_y    a    b    c    d    e
person_x                         
a         2.0  0.0  0.0  1.0  2.0
b         0.0  2.0  0.0  0.0  0.0
c         0.0  0.0  2.0  1.0  0.0
d         1.0  0.0  1.0  2.0  1.0
e         2.0  0.0  0.0  1.0  2.0

答案 1 :(得分:1)

@ Wen-Ben已经回答了您的问题。它基于以下概念:找到成对person的所有可能性,并计算具有相同vote的可能性。找出所有成对的笛卡尔积(交叉联接)。您可以在cartesian product (CROSS JOIN) with pandas

上阅读@ cs95上的精彩文章

在您遇到的问题中,您对每个event计票,因此,每个event的票数是交叉的。因此,您不需要像@ cs95帖子中那样添加辅助程序key列。您可以直接在列event上交叉加入。交叉连接后,使用vote过滤出那些具有相同query的成对人物<->人物。最后,使用crosstab逐对计数。

以下是我的解决方案:

df_match = df.merge(df, on='event').query('vote_x == vote_y')    
pd.crosstab(index=df_match.person_x, columns=df_match.person_y)

Out[1463]:
person_y  a  b  c  d  e
person_x
a         2  0  0  1  2
b         0  2  0  0  0
c         0  0  2  1  0
d         1  0  1  2  1
e         2  0  0  1  2