Заголовок панели действий с более чем одной строкой?

Вторая половина принятого в настоящее время ответа устарела и имеет два отклонения. Прежде всего, вы больше не можете передавать словарь словарей в метод agg groupby. Во-вторых, никогда не используйте .ix.

Если вы хотите работать с двумя отдельными столбцами одновременно, я бы предложил использовать метод apply, который implicity передает DataFrame к прикладной функции. Давайте используем аналогичный блок данных, как тот, что приведен выше

df = pd.DataFrame(np.random.rand(4,4), columns=list('abcd'))
df['group'] = [0, 0, 1, 1]
df

          a         b         c         d  group
0  0.418500  0.030955  0.874869  0.145641      0
1  0.446069  0.901153  0.095052  0.487040      0
2  0.843026  0.936169  0.926090  0.041722      1
3  0.635846  0.439175  0.828787  0.714123      1

Словарь, сопоставленный с именами столбцов, для функций агрегации, по-прежнему отлично подходит для выполнения агрегации.

df.groupby('group').agg({'a':['sum', 'max'], 
                         'b':'mean', 
                         'c':'sum', 
                         'd': lambda x: x.max() - x.min()})

              a                   b         c         d
            sum       max      mean       sum  <lambda>
group                                                  
0      0.560541  0.507058  0.418546  1.707651  0.129667
1      0.187757  0.157958  0.887315  0.533531  0.652427

Если вам не нравится это уродливое имя столбца лямбда, вы можете использовать обычную функцию и указать специальное имя для специального атрибута __name__ следующим образом:

def max_min(x):
    return x.max() - x.min()

max_min.__name__ = 'Max minus Min'

df.groupby('group').agg({'a':['sum', 'max'], 
                         'b':'mean', 
                         'c':'sum', 
                         'd': max_min})

              a                   b         c             d
            sum       max      mean       sum Max minus Min
group                                                      
0      0.560541  0.507058  0.418546  1.707651      0.129667
1      0.187757  0.157958  0.887315  0.533531      0.652427

Используя apply и возвращая серию

Теперь, если у вас было несколько столбцов, которые должны были взаимодействовать друг с другом, вы не можете использовать agg, который неявно передает Серию в агрегирующую функцию. При использовании apply вся группа в качестве DataFrame передается в функцию.

Я рекомендую сделать одну настраиваемую функцию, которая возвращает Серию всех агрегатов. Используйте индекс Series в качестве меток для новых столбцов:

def f(x):
    d = {}
    d['a_sum'] = x['a'].sum()
    d['a_max'] = x['a'].max()
    d['b_mean'] = x['b'].mean()
    d['c_d_prodsum'] = (x['c'] * x['d']).sum()
    return pd.Series(d, index=['a_sum', 'a_max', 'b_mean', 'c_d_prodsum'])

df.groupby('group').apply(f)
          a_sum     a_max    b_mean  c_d_prodsum
group                                           
0      0.560541  0.507058  0.418546     0.118106
1      0.187757  0.157958  0.887315     0.276808

Если вы любите MultiIndexes, вы все равно можете вернуть серию с такими же:

    def f_mi(x):
        d = []
        d.append(x['a'].sum())
        d.append(x['a'].max())
        d.append(x['b'].mean())
        d.append((x['c'] * x['d']).sum())
        return pd.Series(d, index=[['a', 'a', 'b', 'c_d'], 
                                   ['sum', 'max', 'mean', 'prodsum']])

df.groupby('group').apply(f_mi)

              a                   b       c_d
            sum       max      mean   prodsum
group                                        
0      0.560541  0.507058  0.418546  0.118106
1      0.187757  0.157958  0.887315  0.276808
13
задан Goo 12 February 2013 в 11:55
поделиться