![](/img/trans.png)
[英]pandas groupby apply with condition on the first occurrence of a column value
[英]Apply condition on a column after groupby in pandas and then aggregate to get 2 max value
data field bcorr
0 A cs1 0.8
1 A cs2 0.9
2 A cs3 0.7
3 A pq1 0.4
4 A pq2 0.6
5 A pq3 0.5
6 B cs1 0.8
7 B cs2 0.9
8 B cs3 0.7
9 B pq1 0.4
10 B pq2 0.6
11 B pq3 0.5
对于data
列中的每个数据A
和B
,将cs
和pq
字段与field
列分离,然后聚合以获得bcorr
的 2 个最大值。
示例结果如下:
data field bcorr
0 A cs1 0.8
1 A cs2 0.9
4 A pq2 0.6
5 A pq3 0.5
6 B cs1 0.8
7 B cs2 0.9
10 B pq2 0.6
11 B pq3 0.5
为此,一种选择是在创建记录列表时执行此操作,这显然具有很高的复杂性。
其次,我想用 pandas dataframe 来做到这一点,我在data
列上使用了groupby
,然后应用startswith
来获取源field
,然后应用max
首先,提取每个字段的公共部分(第一个字母),然后对值进行排序(最高值 go 底部)。 最后按data
列和field
系列分组,然后保留最后两个值(最高):
field = df['field'].str.extract('([^\d]+)', expand=False)
out = df.sort_values('bcorr').groupby(['data', field]).tail(2).sort_index()
print(out)
# Output
data field bcorr
0 A cs1 0.8
1 A cs2 0.9
4 A pq2 0.6
5 A pq3 0.5
6 B cs1 0.8
7 B cs2 0.9
10 B pq2 0.6
11 B pq3 0.5
如果您的字段只有两个固定字母来确定字段,则可以使用df['field'].str[:2]
而不是df['field'].str.extract(...)
。
您可以使用str[:2]
对日期和groupby
字段列进行分组,它可以抓取第二个字符,并使用head(2)
。
head
返回前n
行,因此您需要先对数据进行排序。
df.sort_values(by=['data','bcorr'],ascending=False).groupby(['data',df.field.str[:2]]).head(2).sort_index()
data field bcorr
0 A cs1 0.8
1 A cs2 0.9
4 A pq2 0.6
5 A pq3 0.5
6 B cs1 0.8
7 B cs2 0.9
10 B pq2 0.6
11 B pq3 0.5
按照上述逻辑,使用tail(2)
并对数据进行排序,得到相同的 output:
df.sort_values(by=['data','bcorr']).groupby(['data',df.field.str[:2]]).tail(2).sort_index()
编辑如果您想概括以允许在字段列中使用任意数量的非数字字符,您可以使用str.replace
将groupby
中的所有数字字符替换为空:
df.sort_values(by=['data','bcorr']).groupby(['data',df.field.str.replace(r"[0-9]",'')]).tail(2).sort_index()
我相信这是您正在努力实现的目标
import pandas as pd
df = {'data': ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B'],
'fie': ['cs1', 'cs2', 'cs3', 'pq1', 'pq2', 'pq3', 'cs1', 'cs2', 'cs3', 'pq1', 'pq2', 'pq3'],
'bcorr': [0.8, 0.9, 0.7, 0.4, 0.6, 0.5, 0.8, 0.9, 0.7, 0.4, 0.6, 0.5]}
df = {'data': df['data'], 'fie_c': [x[:2] for x in df['fie']], 'fie_n': [x[2] for x in df['fie']],
'bcorr': df['bcorr']}
df = pd.DataFrame(data=df)
df = df.sort_values('bcorr', ascending=False).groupby(by=['data', 'fie_c']).head(2).sort_values('data')
df['fie'] = df[['fie_c', 'fie_n']].apply(lambda x: '{}{}'.format(x[0], x[1]), axis=1)
df = df.drop(columns=['fie_c', 'fie_n'])
df = df[['data', 'fie', 'bcorr']]
print(df)
Output
data fie bcorr
1 A cs2 0.9
0 A cs1 0.8
4 A pq2 0.6
5 A pq3 0.5
7 B cs2 0.9
6 B cs1 0.8
10 B pq2 0.6
11 B pq3 0.5
请注意,前几行可能更清晰,但我的重点是在线
df = df.sort_values('bcorr', ascending=False).groupby(by=['data', 'fie_c']).head(2).sort_values('data')
它完成了大部分重要的工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.