多列值的条件求和

2024-06-10 11:26:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我想返回一个总计数的胜利基于不同风格的人互相战斗。例如,假设一个战士有两种战斗方式:XX和JJ。我想计算一下一架XX型战斗机打败另一架XX型战斗机的次数,以及这架战斗机打败JJ型战斗机的次数。你知道吗

name  style   opp1   style   result1   opp2   style   result2   opp3  style   result3    
 A      XX     C      JJ       win      D      XX      loss       B     JJ      draw
 B      JJ     A      XX       draw     C      JJ      loss       D     XX       win
 C      JJ     A      XX       loss     B      JJ       win       D     XX       win
 D      XX     A      XX        win     B      JJ      loss       C     JJ      loss

这是期望的输出

     XX    JJ
XX          1
JJ   2

我知道我可以通过价值计算得到总的胜负和平局

df['result1'].value_counts()

但我不知道如何进行条件求和。你知道吗


Tags: namestyle风格方式次数win计数draw
1条回答
网友
1楼 · 发布于 2024-06-10 11:26:17

你那里的数据格式几乎完全不可用。尤其是同名的列是pandas无法处理的,因为您总是会遇到命名冲突。为了使用它,您应该尝试将它转换为一种称为“长格式”的格式:

In [39]: df                                                                                                                                                                                                 
Out[39]: 
  name style opp1 style.1 result1 opp2 style.2 result2 opp3 style.3 result3
0    A    XX    C      JJ     win    D      XX    loss    B      JJ    draw
1    B    JJ    A      XX    draw    C      JJ    loss    D      XX     win
2    C    JJ    A      XX    loss    B      JJ     win    D      XX     win
3    D    XX    A      XX     win    B      JJ    loss    C      JJ    loss

In [40]: df2 = pd.concat([df[['name', 'style', 'opp1', 'style.1', 'result1']].rename(columns={'opp1' : 'opponent', 'style.1' : 'style.y', 'result1' : 'result'}), df[['name', 'style', 'opp2', 'style.2', 'r
    ...: esult2']].rename(columns={'opp2' : 'opponent', 'style.2' : 'style.y', 'result2' : 'result'}), df[['name', 'style', 'opp3', 'style.3', 'result3']].rename(columns={'opp3' : 'opponent', 'style.3' : 
    ...: 'style.y', 'result3' : 'result'})])
Out[40]: 
  name style opponent style.y result
0    A    XX        C      JJ    win
1    B    JJ        A      XX   draw
2    C    JJ        A      XX   loss
3    D    XX        A      XX    win
0    A    XX        D      XX   loss
1    B    JJ        C      JJ   loss
2    C    JJ        B      JJ    win
3    D    XX        B      JJ   loss
0    A    XX        B      JJ   draw
1    B    JJ        D      XX    win
2    C    JJ        D      XX    win
3    D    XX        C      JJ   loss

一旦你知道了,剩下的基本上是一条直线

In [4]: df3 = df2[df2['result'] == 'win'].groupby(['style', 'style.y'])['result'].count().reset_index()                                                                                                                                                                                                                                                                                                  
Out[4]: 
  style style.y  result
0    JJ      JJ       1
1    JJ      XX       2
2    XX      JJ       1
3    XX      XX       1

In [38]: pd.pivot(df3, index='style', columns='style.y')                                                              
Out[38]: 
        result   
style.y     JJ XX
style            
JJ           1  2
XX           1  1

顺序是按字母顺序排列的,因此不完全是您的输出,但值是相同的。你知道吗

如果您想使用value_counts(),您也可以这样做

In [7]: df3 = df2.groupby(['style', 'style.y'])['result'].value_counts().reset_index(['style', 'style.y']).loc['win', :]

Out[7]: 
       style style.y  result
result                      
win       JJ      JJ       1
win       JJ      XX       2
win       XX      JJ       1
win       XX      XX       1 

pivot之后得到相同的结果。你知道吗

编辑: 在How can I unpivot or stack a pandas dataframe in the way that I asked?中,我找到了一种更优雅的方法来重塑初始数据帧

In [10]: df2 = df.rename(columns={'style.1' : 'oppstyle1', 'style.2' : 'oppstyle2', 'style.3' : 'oppstyle3'})                                                                                                     
Out[10]: 
  name style opp1 oppstyle1 result1 opp2 oppstyle2 result2 opp3 oppstyle3 result3
0    A    XX    C        JJ     win    D        XX    loss    B        JJ    draw
1    B    JJ    A        XX    draw    C        JJ    loss    D        XX     win
2    C    JJ    A        XX    loss    B        JJ     win    D        XX     win
3    D    XX    A        XX     win    B        JJ    loss    C        JJ    loss

In [15]: pd.wide_to_long(df2, ['opp', 'oppstyle', 'result'], i=['name', 'style'], j='i', sep='')                                                                                                            
Out[15]: 
             opp oppstyle result
name style i                    
A    XX    1   C       JJ    win
           2   D       XX   loss
           3   B       JJ   draw
B    JJ    1   A       XX   draw
           2   C       JJ   loss
           3   D       XX    win
C    JJ    1   A       XX   loss
           2   B       JJ    win
           3   D       XX    win
D    XX    1   A       XX    win
           2   B       JJ   loss
           3   C       JJ   loss

相关问题 更多 >