获取一列的值,其中一列为最大值,另一列为最小值

时间:2020-02-04 11:40:15

标签: python pandas dataframe

从这样的数据框中

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

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.eqcol4比较


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