Python Pandas 按顺序计算多索引中唯一对的出现次数

Python Pandas Sequentially Count Up Occurrences For Unique Pairs in Multiindex

我完成了一个数据框日志记录练习,其中包含两列多索引:Day 和 Person。每天,每个人都会记录他们进行了哪些锻炼(如果他们进行了锻炼)。我想添加另一列,按顺序计算进入此日志的条目,如下所示。因此,对于每一对独特的日期和人,加 1。

Day   Person   Exercise    EntryNumber
1     Joe      Curls                 1
1     Joe      Squats                1
1     Sandy    Sprints               2
1     Sandy    Bench                 2
2     Joe      Curls                 3
2     Sandy    Squats                4
3     Bob      Pushups               5

这是生成上述数据框的代码。

import pandas as pd
df = pd.DataFrame({'Day':[1,1,1,1,2,2,3], 
                   'Person':['Joe','Joe','Sandy','Sandy','Joe','Sandy','Bob'], 
                   'Exercise':['Curls','Squats','Sprints','Bench','Curls','Squats','Pushups']})
df = df.set_index(['Day','Person'])

我将如何创建 EntryNumber 列?我已经尝试了各种 groupby 和 cumcount 但还没有弄明白。

谢谢!

也许你可以试试 groupby 然后 ngroup():

#Generating df from above
import pandas as pd
df = pd.DataFrame({'Day':[1,1,1,1,2,2,3], 
                   'Person':['Joe','Joe','Sandy','Sandy','Joe','Sandy','Bob'], 
                   'Exercise':['Curls','Squats','Sprints','Bench','Curls','Squats','Pushups']})
df = df.set_index(['Day','Person'])

# applying reset index and ngroup
df.reset_index(inplace=True)
df['Entry Number'] = df.groupby(['Day','Person']).ngroup() +1
df

结果:

    Day Person  Exercise    Entry Number
0   1   Joe      Curls      1
1   1   Joe      Squats     1
2   1   Sandy    Sprints    2
3   1   Sandy    Bench      2
4   2   Joe      Curls      3
5   2   Sandy    Squats     4
6   3   Bob      Pushups    5

另一种方法是 factorize 按索引而不用分组:

df['EntryNumber'] = df.index.factorize()[0]+1
#df = df.reset_index() -> if you want to reset theindex

print(df)
           Exercise  EntryNumber
Day Person                      
1   Joe       Curls            1
    Joe      Squats            1
    Sandy   Sprints            2
    Sandy     Bench            2
2   Joe       Curls            3
    Sandy    Squats            4
3   Bob     Pushups            5