2013-11-21 2 views
2

некоторые группы, но не я использую панды groupby на моем DataFrame df, которая имеет столбцы type, subtype и 11 других. Я тогда вызове apply с моим combine_function (требуется лучшее название) на группы, как:Панды GroupBy применять функцию, которая сочетает в себе другие

grouped = df('type') 
    reduced = grouped.apply(combine_function) 

где мои combine_function проверяет, является ли какой-либо элемент в группе содержит какой-либо элемент с данным подтипом, скажем, 1, и выглядит следующим образом:

def combine_function(group): 
    if 1 in group.subtype: 
     return aggregate_function(group) 
    else: 
     return group 

combine_function затем может вызвать aggregate_function, который вычисляет суммарную статистику, сохраняет их в первом ряду, а затем устанавливает эту строку, чтобы быть группой. Это выглядит следующим образом:

def aggregate_function(group): 
    first = group.first_valid_index() 
    group.value1[group.index == first] = group.value1.mean() 
    group.value2[group.index == first] = group.value2.max() 
    group.value3[group.index == first] = group.value3.std() 

    group = group[(group.index == first)] 
    return group 

Я совершенно уверен, что это не самый лучший способ сделать это, но он давал мои желаемых результатов, 99,9% времени на тысячи DataFrames. Однако иногда выдает ошибку, что так или иначе связанную с группой, что я не хочу, чтобы агрегировать имеет ровно 2 строки:

ValueError: Shape of passed values is (13,), indices imply (13, 5) 

где моя качестве примера группа имела размер:

In [4]: grouped.size() 
Out[4]: 
type 
1   9288 
3   7667 
5   7604 
11   2 
dtype: int64 

Он обрабатывается три три штрафа, а затем дал ошибку, когда он попытался объединить все. Если я прокомментирую строку group = group[(group.index == first)], обновите ее, но не суммируйте или не назовите мой aggregate_function для всех групп.

Кто-нибудь знает, как правильно организовать такое объединение нескольких групп, но не других?

+0

Вы пробовали просто использовать заявку? –

ответ

3

Ваш aggregate_functions выглядит искаженным. Когда вы объединяете группу, она автоматически сводится к одной строке; вам не нужно делать это вручную. Может быть, мне не хватает смысла. (Вы делаете что-то особенное с индексом, который я не понимающего?) Но более нормальное использование будет выглядеть следующим образом:

agg_condition = lambda x: Series([1]).isin(x['subtype]').any() 
agg_functions = {'value1': np.mean, 'value2': np.max, 'value3': np.std} 

df1 = df.groupby('type').filter(agg_condition).groupby('type').agg(**agg_functions) 
df2 = df.groupby('type').filter(~agg_condition) 

result = pd.concat([df1, df2]) 

Примечание: agg_condition грязен, потому что (1) встроенный в Python in относится к индекс серии, а не его значения, и (2) результат должен быть сведен к скаляру на any().

+0

Это похоже на то, что я должен делать. Я играл с ним вчера, но все еще пинал много ошибок для меня. Я думаю, что это имеет какое-то отношение к моей обработке других 8 столбцов, где я просто хотел, чтобы агрегат использовал первое значение. Я уверен, что есть легкое исправление, и я обновлю, как только у меня это получится. – TristanMatthews

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