根据groupby shift更改列的值,并创建新的列 - Pandas

问题描述 投票:0回答:1

我有一个数据框架,如下图所示

Session      slot_num         ID    prob
s1           1                A     0.2
s1           2                B     0.9
s1           2                B     0.4
s1           3                C     0.7
s1           4                D     0.8
s1           4                D     0.3
s1           5                E     0.6
s1           6                F     0.5
s1           7                G     0.7
s2           1                A1    0.6
s2           2                B1    0.5
s2           3                C1    1.1
s2           3                C1    0.6
s2           4                D1    0.7
s2           5                E1    0.6
s2           6                F1    0.7
s2           7                G1    1.2
s2           7                G1    0.7

其排序如下图所示

df = df.sort_values(['Session', 'slot_num'], ascending=True)

然后我想创建一个新的列,叫做overbook,如下所述。

如果我们有多个相同的Session和slot_num,第一个是'yes',第二个是'booking',如果有更多的除了第一个以外的其他都是bookingelse: df['overbook']='no'

同时将第二行的ID替换为'TBF'。

预期的输出。

Session      slot_num         ID    prob    overbook
s1           1                A     0.2     no
s1           2                B     0.9     yes
s1           2               TBF    0.4     booking
s1           3                C     0.7     no
s1           4                D     0.8     yes
s1           4               TBF    0.3     booking
s1           5                E     0.6     no
s1           6                F     0.5     no
s1           7                G     0.7     no
s2           1                A1    0.6     no
s2           2                B1    0.5     no
s2           3                C1    1.1     yes
s2           3                TBF   0.6     booking
s2           4                D1    0.7     no
s2           5                E1    0.6     no
s2           6                F1    0.7     no
s2           7                G1    1.2     yes
s2           7                TBF   0.7     booking
pandas pandas-groupby
1个回答
1
投票

我的想法是使用 Series.map 计数器 GroupBy.cumcount,但只适用于重复排列的行,所以使用了 numpy.whereDataFrame.duplicated:

df = df.sort_values(['Session', 'slot_num'], ascending=True)

m = df.duplicated(['Session', 'slot_num'], keep=False)
s = df.groupby(['Session', 'slot_num']).cumcount()
d = {0:'yes', 1:'booking'}
df['overbook'] = np.where(m, s.map(d), 'no')
print (df)
   Session  slot_num  ID  prob overbook
0       s1         1   A   0.2       no
1       s1         2   B   0.9      yes
2       s1         2   B   0.4  booking
3       s1         3   C   0.7       no
4       s1         4   D   0.8      yes
5       s1         4   D   0.3  booking
6       s1         5   E   0.6       no
7       s1         6   F   0.5       no
8       s1         7   G   0.7       no
9       s2         1  A1   0.6       no
10      s2         2  B1   0.5       no
11      s2         3  C1   1.1      yes
12      s2         3  C1   0.6  booking
13      s2         4  D1   0.7       no
14      s2         5  E1   0.6       no
15      s2         6  F1   0.7       no
16      s2         7  G1   1.2      yes
17      s2         7  G1   0.7  booking
© www.soinside.com 2019 - 2024. All rights reserved.