2017-01-04 2 views
1

Это мой кадр данных:группы строк и вычислить среднее значение и подсчет

df = 
UD QTY GRADE TIME_1 TIME_2 
1 20 5  22.5  16.1 
1 20 5  26.2  19.5 
1 20 5  30.0  14.0 
1 20 4  20.0  18.5 
2 25 4  23.3  19.9 

Мне нужно рассчитать средние значения TIME_1 и TIME_2 в каждой комбинации UD и QTY. Затем я хочу добавить новый столбец GRADE_COUNT, который будет хранить общее количество строк в группе. Например, в приведенных выше данных установлено существует 4 строки в каждой группе, определенной UD = 1 и QTY = 20.

Результат должен быть такой:

df = 

UD QTY MEAN_TIME_1 MEAN_TIME_2 COUNT 
1 20 24.67   17.02   4 
2 25 23.3   19.9   1 

Я написал этот код, какие группы строк, вычисляет средние значения и значения count.

groupby_object = df[['UD', 'QTY', 'GRADE', 'TIME_1', 'TIME_2']].groupby(['TIME_1', 'TIME_2]) 

df = groupby_object.agg('mean').rename(columns = lambda x: x + ' mean').join(pd.DataFrame(groupby_object.size(),columns=['counts'])).reset_index() 

Но вместо расчета средних времен, он вычисляет значит QTY и GRADE, также столбец UD исчезает.

+0

'df.groupby ([ 'УД', 'КОЛ']) [[ 'TIME_1', 'TIME_2' ]].mean() '- это то, что вы хотите? – MaxU

+0

@MaxU: см. Мое обновление. Я опубликовал ожидаемый результат. – Dinosaurius

+0

@DavidZ: Я использую последнюю версию панд: 0.19.1 – Dinosaurius

ответ

4

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

df1 = df.groupby(['UD', 'QTY']).agg({'TIME_1': 'mean', 
            'TIME_2': 'mean', 
            'GRADE':'count'}).reset_index() 

    UD QTY TIME_1 GRADE TIME_2 
0 1 20 24.675  4 17.025 
1 2 25 23.300  1 19.900 
+0

Может ли окончательное решение содержать только строки, которые я указал в качестве ожидаемого результата в моем вопросе? – Dinosaurius

+2

Похоже, вы только группируете UD и QTY, а не GRADE. Ваш последний файл данных не соответствует тому, что вы написали –

+0

Я обновил свое решение до чего-то простого –

1

Аргумент к DataFrame.groupby() специфицирует, какие столбцы должны быть использованы для объединения строк в группы. Так что, если вы пишете

df.groupby([['TIME_1', 'TIME_2']]) 

затем Панда совместит строки, которые имеют одинаковые значения TIME_1 и TIME_2. Но вы хотите объединить строки, которые имеют одинаковые значения UD и QTY. (Если вы хотите использовать GRADE сгруппировать строки, только добавить, что в случае необходимости.) Таким образом, использовать

>>> g = df.groupby([['UD', 'QTY']]) 

Тогда вы можете просто вызвать mean() на полученном объекте, чтобы получить средства из групп.

>>> g.mean() 
     GRADE TIME_1 TIME_2 
UD QTY      
1 20 4.75 24.675 17.025 
2 25 4.00 23.300 19.900 

Кроме того, вы можете позвонить count() получить число строк.

>>> g.count() 
     GRADE TIME_1 TIME_2 
UD QTY      
1 20  4  4  4 
2 25  1  1  1 

Теперь вы можете собрать эти части в новую DataFrame используя pandas.concat().

>>> m = g.mean() 
>>> c = g.count() 
>>> new_df = concat([m, c], axis=1) 
>>> new_df 
     TIME_1 TIME_2 GRADE 
UD QTY      
1 20 24.675 17.025  4 
2 25 23.300 19.900  1 

Все, что осталось изменить UD и QTY из столбцов индекса регулярных колонок, которые вы можете сделать с new_df.reset_index() и изменить имена столбцов по своему вкусу, что вы можете сделать, назначая список new_df.columns.

1

попробовать это:

In [295]: g = df.groupby(['UD','QTY'], as_index=False) 

In [297]: (pd.merge(g[['TIME_1','TIME_2']].mean(), 
    ...:   g.size().to_frame('COUNT').reset_index(), 
    ...:   on=['UD','QTY']) 
    ...:) 
    ...: 
Out[297]: 
    UD QTY TIME_1 TIME_2 COUNT 
0 1 20 24.675 17.025  4 
1 2 25 23.300 19.900  1 

или немного лучше один:

In [301]: g[['TIME_1','TIME_2']].mean().assign(COUNT=g.size().values) 
Out[301]: 
    UD QTY TIME_1 TIME_2 COUNT 
0 1 20 24.675 17.025  4 
1 2 25 23.300 19.900  1 
+0

Правильно ли я понимаю, что если, например, мне не нужно вычислять среднее время, тогда я должен просто запустить 'g.assign (COUNT = g [['TIME_1', 'TIME_2']]. Size(). Values) 'исключая' [['TIME_1', 'TIME_2']]. mean() '? – Dinosaurius

+0

@Dinosaurius, я бы попробовал это: 'g.size(). To_frame ('COUNT'). Reset_index()' – MaxU

+1

@Dinosaurius, вы должны, вероятно, отметить [Ted's solution] (http://stackoverflow.com/a/ 41474022/5741205) как правильное - это намного лучше и более идиоматично – MaxU

Смежные вопросы