从这样的数据框中
import pandas as pd
import numpy as np
df = pd.DataFrame({
'col1': ['a'] * 20 + ['b'] * 20,
'col2': (['c'] * 10 + ['d'] * 10)*2,
'col3': ( ['x'] * 3 + ['y'] * 7)*4,
'col4': np.random.rand(40),
'col5': np.random.rand(40),
}
)
我想获取'col3'的值,其中'col4'为最大值,如果有两行或更多行具有相同的'col4'值,则选择其中'col5'为最小值的行。
dg = df.groupby(('col1', 'col2'), sort=False)['col4'].max()
dh = df.groupby(('col1', 'col2'), sort=False)['col5'].min()
到目前为止,我已经提出了,
dg = df.groupby(('col1', 'col2'), sort=False)\
.agg({'col4':'max', 'col5':'min'})
但是它分别给我最大的“ col4”和最小的“ col5”,而我希望“ col5”的值是对应于最大“ col4”的值(如果最大行只有一个“ col4”)
另外,我想让'col3'值对应于最大'col4'。我现在有这个:
df.loc[df.groupby(('col1', 'col2'), sort=False)['col4'].idxmax()]['col3'].reset_index()['col3']
这给了我我想要的列,但是当我将其放入新的数据框中时,我没有得到我期望的值,这将是最大的“ col4”和最小的“ col5”以及它们对应的“ col3”值:
dg['col3'] = df.loc[df.groupby(('col1', 'col2'), sort=False)['col4'].idxmax()]['col3'].reset_index()['col3']
示例:
import numpy as np
import pandas as pd
np.random.seed(2020)
df = pd.DataFrame({ 'col1': ['a'] * 10 + ['b'] * 10, 'col2': (['c'] * 5 + ['d'] * 5)*2, 'col3': ( ['x'] * 5 + ['y'] * 5)*2, 'col4': np.random.randint(5, size=20), 'col5': np.random.randint(5, size=20), } )
col1 col2 col3 col4 col5
0 a c x 0 4
1 a c x 0 1
2 a c x 3 1
3 a c x 3 2
4 a c x 3 1
5 a d y 3 2
6 a d y 0 4
7 a d y 0 4
8 a d y 0 2
9 a d y 0 3
10 b c x 2 4
11 b c x 1 1
12 b c x 3 4
13 b c x 3 1
14 b c x 2 3
15 b d y 3 2
16 b d y 0 0
17 b d y 4 1
18 b d y 4 1
19 b d y 0 2
预期输出为:
col1 col2 col3 col4 col5
a c x 3 1
a c x 3 1
a d y 3 2
b c x 3 1
b d y 4 1
b d y 4 1
答案 0 :(得分:2)
使用:
np.random.seed(2020)
df = pd.DataFrame({ 'col1': ['a'] * 10 + ['b'] * 10, '
col2': (['c'] * 5 + ['d'] * 5)*2,
'col3': ( ['x'] * 5 + ['y'] * 5)*2,
'col4': np.random.randint(5, size=20),
'col5': np.random.randint(5, size=20), } )
print (df)
col1 col2 col3 col4 col5
0 a c x 0 4
1 a c x 0 1
2 a c x 3 1
3 a c x 3 2
4 a c x 3 1
5 a d y 3 2
6 a d y 0 4
7 a d y 0 4
8 a d y 0 2
9 a d y 0 3
10 b c x 2 4
11 b c x 1 1
12 b c x 3 4
13 b c x 3 1
14 b c x 2 3
15 b d y 3 2
16 b d y 0 0
17 b d y 4 1
18 b d y 4 1
19 b d y 0 2
首先用boolean indexing
过滤所有行,最大col4
过滤GroupBy.transform
,然后用Series.eq
与col4
比较
df1 = df[df.groupby(['col1', 'col2'])['col4'].transform('max').eq(df['col4'])]
print (df1)
col1 col2 col3 col4 col5
2 a c x 3 1
3 a c x 3 2
4 a c x 3 1
5 a d y 3 2
12 b c x 3 4
13 b c x 3 1
17 b d y 4 1
18 b d y 4 1
#if need only some columns filter by list
cols = ['col1','col2','col3', 'col4','col5']
mask = df1.groupby(['col1', 'col2'], sort=False)['col5'].transform('min').eq(df1['col5'])
df2 = df1.loc[mask, cols]
print (df2)
col1 col2 col3 col4 col5
2 a c x 3 1
4 a c x 3 1
5 a d y 3 2
13 b c x 3 1
17 b d y 4 1
18 b d y 4 1