将 groupby() 组中的每个元素与该组中的唯一值进行比较,并获得相等的位置

Compare each element in groupby() group to the unique values in that group and get the location of equality

我有一个数据框,其中包含某个测量的主题和日期。对于每个主题,我想查找该组每一行中的日期是否对应于第一 (1)、第二 (2)、第三 (3)... 该主题的唯一日期值。

澄清这就是我要找的东西:

    |subject | date | order|
    |A | 01.01.2020 | 1|
    |A | 01.01.2020 | 1|
    |A | 02.01.2020 | 2|
    |B | 01.01.2020 | 1|
    |B | 02.01.2020 | 2|
    |B | 02.01.2020 | 2|

我虽然有如下想法,但是 for 循环在应用函数中是不允许的:

df['order']=df.groupby(['subject']).apply(lambda x: i if x['date']=value for i, value in enumerate(x['date'].unique()))

有直接的方法吗?

使用factorize in GroupBy.transform

df['order1']=df.groupby(['subject'])['date'].transform(lambda x: pd.factorize(x)[0]) + 1
print (df)
  subject        date  order  order1
0       A  01.01.2020      1       1
1       A  01.01.2020      1       1
2       A  02.01.2020      2       2
3       B  01.01.2020      1       1
4       B  02.01.2020      2       2
5       B  02.01.2020      2       2

或者您可以使用 GroupBy.rank,但必须将列 date 转换为日期时间:

df['order2']=df.groupby(['subject'])['date'].rank(method='dense')
print (df)
  subject       date  order  order1
0       A 2020-01-01      1     1.0
1       A 2020-01-01      1     1.0
2       A 2020-02-01      2     2.0
3       B 2020-01-01      1     1.0
4       B 2020-02-01      2     2.0
5       B 2020-02-01      2     2.0

解决方案的不同之处在于是否更改了日期时间的顺序:

print (df)
  subject       date  order (disregarding temporal order of date)
0       A 2020-01-01      1
1       A 2020-03-01      2 <- changed datetime for sample
2       A 2020-02-01      3
3       B 2020-01-01      1
4       B 2020-02-01      2
5       B 2020-02-01      2

df['order1']=df.groupby(['subject'])['date'].transform(lambda x: pd.factorize(x)[0]) + 1
df['order2']=df.groupby(['subject'])['date'].rank(method='dense')
print (df)
  subject       date  order  order1  order2
0       A 2020-01-01      1       1     1.0
1       A 2020-03-01      1       2     3.0
2       A 2020-02-01      2       3     2.0
3       B 2020-01-01      1       1     1.0
4       B 2020-02-01      2       2     2.0
5       B 2020-02-01      2       2     2.0

总结:如果您不关心 date 的时间顺序反映在 order 输出中,请使用第一种方法,或者如果时间顺序很重要并且应该使用第二种方法反映在 order 输出中。