繁体   English   中英

在 pandas 中 groupby 之后的列上应用条件,然后聚合以获得 2 个最大值

[英]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列中的每个数据AB ,将cspq字段与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.replacegroupby中的所有数字字符替换为空:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM