title: How to apply different functions to a groupby object?
body: <p>I have a dataframe like this:</p>
  
  <pre><code>import pandas as pd
  
  df = pd.DataFrame({'id': [1, 2, 1, 1, 2, 1, 2, 2],
                 'min_max': ['max_val', 'max_val', 'min_val', 'min_val', 'max_val', 'max_val', 'min_val', 'min_val'],
                 'value': [1, 20, 20, 10, 12, 3, -10, -5 ]})
  
     id  min_max  value
  0   1  max_val      1
  1   2  max_val     20
  2   1  min_val     20
  3   1  min_val     10
  4   2  max_val     12
  5   1  max_val      3
  6   2  min_val    -10
  7   2  min_val     -5
  </code></pre>
  
  <p>Each <code>id</code> has several maximal and minimal values associated with it. My <strong>desired output</strong> looks like this:</p>
  
  <pre><code>    max  min
  id          
  1     3   10
  2    20  -10
  </code></pre>
  
  <p>It contains the maximal <code>max_val</code> and the minimal <code>min_val</code> for each <code>id</code>.</p>
  
  <p>Currently I implement that as follows:</p>
  
  <pre><code>gdf = df.groupby(by=['id', 'min_max'])['value']
  
  max_max = gdf.max().loc[:, 'max_val']
  min_min = gdf.min().loc[:, 'min_val']
  
  final_df = pd.concat([max_max, min_min], axis=1)
  final_df.columns = ['max', 'min']
  </code></pre>
  
  <p>What I don't like is that I have to call <code>.max()</code> and <code>.min()</code> on the grouped dataframe <code>gdf</code>, separately where I throw away 50% of the information (since I am not interested in the maximal <code>min_val</code> and the minimal <code>min_val</code>). </p>
  
  <p>Is there a way to do this in a more straightforward manner by e.g. passing the function that should be applied to a group directly to the <code>groupby</code> call?</p>
  
  <p>EDIT:</p>
  
  <pre><code>df.groupby('id')['value'].agg(['max','min'])
  </code></pre>
  
  <p>is not sufficient as there can be the case that a group has a <code>min_val</code> that is higher than all <code>max_val</code> for that group or a <code>max_val</code> that is lower than all <code>min_val</code>. Thus, one also has to group based on the column <code>min_max</code>.</p>
  
  <p>Result for </p>
  
  <pre><code>df.groupby('id')['value'].agg(['max','min'])
  
      max  min
  id          
  1    20    1
  2    20  -10
  </code></pre>
  
  <p>Result for the code from above:</p>
  
  <pre><code>    max  min
  id          
  1     3   10
  2    20  -10
  </code></pre>