Python Return 组中第一次出现

Python Return the First Occurrence in a Group

我一直在寻找一种方法来找到基于组的一系列行中的第一次出现。

首先,我检查并为每个组应用了一个 'group' 计数器。然后我想return状态下'sold'的第一个orruance的ID作为一个新列并将其应用于整个组。

示例如下。 Final_ID 是要创建的新列。

group  ID   status  Final_ID
1      100  view    103
1      101  show    103
1      102  offer   103
1      103  sold    103
1      104  view    103
2      105  view    106
2      106  sold    106
2      107  sold    106
3      108  pending 109
3      109  sold    109
3      110  view    109
4      111  sold    111
4      112  sold    111
4      113  sold    111
4      114  sold    111

我试过使用

df = pd.DataFrame ({'group':['1','1','1','1','1','2','2','2','3','3','3','4','4','4','4'], 
                    'ID':['100','101','102','103','104','105','106','107','108','109','110','111','112','113','114'],
                    'status':['view','show','offer','sold','view','view','sold','sold','pending','sold','view','sold','sold','sold','sold']
                    })


df2=df[( df.status=='sold')][['group','ID']].groupby('group'['ID'].apply(min).reset_index()

df2=df.merge(df2, on='group' , how='left')

但我不确定这样做是否正确。还有其他想法吗?

status 不是 sold 的地方屏蔽你的 ID 系列,然后将你的组分组并选择第一个非 transform first =17=] 每个组的值,在本例中是 sold

的第一次出现
df['ID'].mask(df['status'] != 'sold').groupby(df['group']).transform('first').astype(int)

0     103
1     103
2     103
3     103
4     103
5     106
6     106
7     106
8     109
9     109
10    109
11    111
12    111
13    111
14    111
Name: Final_ID, dtype: int32

您需要查找已售出的行,删除 status 列,在 group 上分组,而不是在 ID 上分组,执行 min.

df.merge(df.loc[df.status=='sold'].drop('status',1).groupby(['group'], as_index=False).min()
           .rename(columns={'ID': 'Final_ID'}))

输出:

   group   ID   status  Final_ID
0      1  100     view       103
1      1  101     show       103
2      1  102    offer       103
3      1  103     sold       103
4      1  104     view       103
5      2  105     view       106
6      2  106     sold       106
7      2  107     sold       106
8      3  108  pending       109
9      3  109     sold       109
10     3  110     view       109
11     4  111     sold       111
12     4  112     sold       111
13     4  113     sold       111
14     4  114     sold       111

假设ID列已经排序,你可以这样做:

(
    df.set_index('group')
    .assign(Final_ID=df.loc[df.status=='sold'].groupby(by='group').ID.first())
    .reset_index()
)

group   ID  status  Final_ID
0   1   100 view    103
1   1   101 show    103
2   1   102 offer   103
3   1   103 sold    103
4   1   104 view    103
5   2   105 view    106
6   2   106 sold    106
7   2   107 sold    106
8   3   108 pending 109
9   3   109 sold    109
10  3   110 view    109
11  4   111 sold    111
12  4   112 sold    111
13  4   113 sold    111
14  4   114 sold    111