text: Title: Chunks of `df.groupby().apply(func)` can be auto merged if the func is actually an aggregation func
  Body: <!--
  Thank you for your contribution!
  
  Please review https://github.com/mars-project/mars/blob/master/CONTRIBUTING.rst before opening an issue.
  -->
  
  Chunks of `df.groupby().apply(func)` can be auto merged if the func is actually an aggregation func.
  
  ```
  In [1]: import pandas as pd; import numpy as np
  
  In [3]: import mars
  
  In [4]: mars.new_session()
  Web service started at http://0.0.0.0:60764
  Out[4]: <mars.deploy.oscar.session.SyncSession at 0x7fa7826dd670>
  
  In [6]: import mars.dataframe as md
  
  In [10]: def f(df):
      ...:     return df.sum()
  
  In [19]: pdf = pd.DataFrame({'a': rs.randint(2, size=20_0000), 'b': rs.rand(20_0
      ...: 000)})
  
  In [20]: df = md.DataFrame(pdf, chunk_size=1_0000).execute()
  100%|██████████████████████████████████████| 100.0/100 [00:00<00:00, 440.41it/s]
  
  In [21]: %time df.groupby('a', as_index=False).apply(f).sort_values('a').execute
      ...: ()
  100%|███████████████████████████████████████| 100.0/100 [00:02<00:00, 38.95it/s]
  CPU times: user 1.83 s, sys: 150 ms, total: 1.98 s
  Wall time: 2.58 s
  Out[21]: 
            a             b
  0       0.0  49795.075985
  0  100326.0  50159.168985
  
  In [22]: %time df.groupby('a', as_index=False).apply(f).rebalance(num_partitions
      ...: =1).sort_values('a').execute()
  100%|███████████████████████████████████████| 100.0/100 [00:01<00:00, 60.80it/s]
  CPU times: user 1.19 s, sys: 94 ms, total: 1.29 s
  Wall time: 1.66 s
  Out[22]: 
            a             b
  0       0.0  49795.075985
  0  100326.0  50159.168985
  
  ```
  
  Here we manually call rebalance to merge the chunks, and the performance's elevation can be observable.
  