我的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
答案 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
在您遇到的问题中,您对每个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