代码之家  ›  专栏  ›  技术社区  ›  HJA24

如何使用与pandas.groupby方法相反的方法将熊猫排捆在一起

  •  1
  • HJA24  · 技术社区  · 2 年前

    我有以下内容 pandas.DataFrame

       match_id  court
    0  50311513      1
    1  50313011      2
    2  50313009      2
    3  50317691      1
    4  50315247      2
    5  50318597      1
    6  50318877      1
    7  50318983      1
    8  50318831      1
    9  50318595      1
    

    正如你所看到的,总共有 2 课程。我想把每个“槽”捆在一起。 因此,第一个分组的df应该包含match 50311513 50313011 。第二个插槽应包含 50313009 50317691 在第三个槽之后,分组的df基本上是单行。

    我该怎么说 pandas.groupby() 球场上只能打一场比赛?

    谢谢

    1 回复  |  直到 2 年前
        1
  •  3
  •   mozway    2 年前

    IIUC,你可以组成两个连续的小组 cumcount :

    # start new group on identical values
    g1 = df['court'].eq(df['court'].shift()).cumsum()
    # in the previous groups, restart if the value was already seen
    g2 = df['court'].groupby([df['court'], g1]).cumcount()
    
    df['group'] = df.groupby([g1, g2]).ngroup()
    
    # variant
    # df['group'] = (g1.diff().ne(0)|g2.diff().ne(0)).cumsum().sub(1)
    

    输出

       match_id  court  group
    0  50311513      1      0
    1  50313011      2      0
    2  50313009      2      1
    3  50317691      1      1
    4  50315247      2      2
    5  50318597      1      2
    6  50318877      1      3
    7  50318983      1      4
    8  50318831      1      5
    9  50318595      1      6
    

    中间体:

       match_id  court  g1  g2  group
    0  50311513      1   0   0      0
    1  50313011      2   0   0      0
    2  50313009      2   1   0      1
    3  50317691      1   1   0      1
    4  50315247      2   1   1      2
    5  50318597      1   1   1      2
    6  50318877      1   2   0      3
    7  50318983      1   3   0      4
    8  50318831      1   4   0      5
    9  50318595      1   5   0      6
    

    一般化

    如果您需要处理更多的组,您可以使用一个自定义(迭代)函数,该函数带有一个集合来跟踪已经看到的项目。如果过去看到的项目集已经包含当前项目,则启动一个新组:

    def grouper(s):
        S = set()
        group = []
        n = 0
        for val in s:
            if val in S:
                n += 1
                S = {val}
            else:
                S.add(val)
            group.append(n)
        return group
    
    df['group'] = grouper(df['court'])
    

    实例

        match_id  court  group
    0   50311513      1      0
    1   50313011      2      0
    2   50313012      3      0
    3   50313009      2      1
    4   50317691      1      1
    5   50315247      2      2
    6   50315248      3      2
    7   50318597      1      2
    8   50318877      1      3
    9   50318983      1      4
    10  50319873      3      4
    11  50318831      1      5
    12  50318595      1      6