groupby (). sum () в столбце, groupby (). mean () на другом [дубликат]

  • Когда компилятор не знает, когда делать функцию / метод «inline»?

Это зависит от используемого компилятора. Не слепо доверяйте, что в наши дни компиляторы лучше знают людей, как внедряться, и вы никогда не должны использовать его по соображениям производительности, потому что это директива linkage, а не подсказка оптимизации. Хотя я согласен с тем, что идеологически эти аргументы правильной встречей с реальностью может быть другой.

После прочтения нескольких потоков вокруг я опробовал из любопытства эффекты встроенного кода, который я только что работал, и результаты были что я получил измеримое ускорение для GCC и не ускоряюсь для компилятора Intel.

(Подробнее: математическое моделирование с несколькими критическими функциями, определенными вне класса, GCC 4.6.3 (g ++ -O3), ICC 13.1.0 (icpc-O3), добавив inline к критическим точкам, вызвав + 6% ускорение с кодом GCC).

Итак, если вы квалифицируете GCC 4.6 как современный компилятор, результатом является то, что директива inline по-прежнему имеет значение, если вы пишете CPU интенсивные задачи и знать, где именно находится узкое место.

101
задан beardc 25 January 2013 в 22:26
поделиться

3 ответа

Для первой части вы можете передать имя столбца для ключей и список функций для значений:

In [28]: df
Out[28]:
          A         B         C         D         E  GRP
0  0.395670  0.219560  0.600644  0.613445  0.242893    0
1  0.323911  0.464584  0.107215  0.204072  0.927325    0
2  0.321358  0.076037  0.166946  0.439661  0.914612    1
3  0.133466  0.447946  0.014815  0.130781  0.268290    1

In [26]: f = {'A':['sum','mean'], 'B':['prod']}

In [27]: df.groupby('GRP').agg(f)
Out[27]:
            A                   B
          sum      mean      prod
GRP
0    0.719580  0.359790  0.102004
1    0.454824  0.227412  0.034060

UPDATE 1:

Поскольку агрегатная функция работает над Series, ссылки на другие имена столбцов теряются. Чтобы обойти это, вы можете ссылаться на полный блок данных и индексировать его с помощью индексов группы в лямбда-функции.

Вот хакерский обход:

In [67]: f = {'A':['sum','mean'], 'B':['prod'], 'D': lambda g: df.loc[g.index].E.sum()}

In [69]: df.groupby('GRP').agg(f)
Out[69]:
            A                   B         D
          sum      mean      prod  <lambda>
GRP
0    0.719580  0.359790  0.102004  1.170219
1    0.454824  0.227412  0.034060  1.182901

Здесь результирующий ' D 'состоит из суммированных значений «E».

UPDATE 2:

Вот такой метод, который, я думаю, сделает все, что вы просите. Сначала создайте пользовательскую лямбда-функцию. Ниже, g ссылается на группу. При агрегировании g будет Серией. Передача g.index в df.ix[] позволяет выбрать текущую группу из df. Затем я тестирую, если столбец C меньше 0,5. Возвращенная логическая серия передается в g[], которая выбирает только те строки, которые соответствуют критериям.

In [95]: cust = lambda g: g[df.loc[g.index]['C'] < 0.5].sum()

In [96]: f = {'A':['sum','mean'], 'B':['prod'], 'D': {'my name': cust}}

In [97]: df.groupby('GRP').agg(f)
Out[97]:
            A                   B         D
          sum      mean      prod   my name
GRP
0    0.719580  0.359790  0.102004  0.204072
1    0.454824  0.227412  0.034060  0.570441
140
ответ дан RK1 23 August 2018 в 20:34
поделиться

Ответ Теда потрясающий. Я закончил тем, что использовал меньшую версию, если кто-то заинтересован. Полезно, если вы ищете одно агрегирование, которое зависит от значений из нескольких столбцов:

создает группировку данных

df=pd.DataFrame({'a': [1,2,3,4,5,6], 'b': [1,1,0,1,1,0], 'c': ['x','x','y','y','z','z']})


   a  b  c
0  1  1  x
1  2  1  x
2  3  0  y
3  4  1  y
4  5  1  z
5  6  0  z

и агрегирование с применением (используя несколько столбцов)

df.groupby('c').apply(lambda x: x['a'][(x['a']>1) & (x['b']==1)].mean())

c
x    2.0
y    4.0
z    5.0

группировка и агрегация с помощью агрегата (с использованием нескольких столбцов)

Мне нравится этот подход, поскольку я все еще могу использовать агрегат. Возможно, люди скажут мне, почему применение необходимо для получения нескольких столбцов при выполнении группировок по группам.

Теперь это кажется очевидным, но пока вы не выбираете интересующий столбец напрямую после groupby у вас будет доступ ко всем столбцам фреймворка из вашей функции агрегации.

имеет доступ только к выбранному столбцу

df.groupby('c')['a'].aggregate(lambda x: x[x>1].mean())

доступа к все столбцы, так как выбор - это все волшебство

df.groupby('c').aggregate(lambda x: x[(x['a']>1) & (x['b']==1)].mean())['a']

или аналогично

df.groupby('c').aggregate(lambda x: x['a'][(x['a']>1) & (x['b']==1)].mean())

Надеюсь, это поможет.

0
ответ дан campo 23 August 2018 в 20:34
поделиться

Вторая половина принятого в настоящее время ответа устарела и имеет два отклонения. Прежде всего, вы больше не можете передавать словарь словарей в метод 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
52
ответ дан Ted Petrou 23 August 2018 в 20:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: