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
我一直在寻找一种方法来找到基于组的一系列行中的第一次出现。
首先,我检查并为每个组应用了一个 '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