Como fazer um loop sobre o dataframe agrupado do Pandas?

146

Quadro de dados:

  c_os_family_ss c_os_major_is l_customer_id_i
0      Windows 7                         90418
1      Windows 7                         90418
2      Windows 7                         90418

Código:

print df
for name, group in df.groupby('l_customer_id_i').agg(lambda x: ','.join(x)):
    print name
    print group

Estou tentando apenas fazer um loop sobre os dados agregados, mas recebo o erro:

ValueError: muitos valores para descompactar

@ EdChum, aqui está a saída esperada:

                                                    c_os_family_ss  \
l_customer_id_i
131572           Windows 7,Windows 7,Windows 7,Windows 7,Window...
135467           Windows 7,Windows 7,Windows 7,Windows 7,Window...

                                                     c_os_major_is
l_customer_id_i
131572           ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,...
135467           ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,...

A saída não é o problema, desejo repetir todos os grupos.

Tjorriemorrie
fonte

Respostas:

224

df.groupby('l_customer_id_i').agg(lambda x: ','.join(x)) já retorna um quadro de dados, para que você não possa mais repetir os grupos.

Em geral:

  • df.groupby(...)retorna um GroupByobjeto (um DataFrameGroupBy ou SeriesGroupBy) e, com isso, você pode percorrer os grupos (conforme explicado nos documentos aqui ). Você pode fazer algo como:

    grouped = df.groupby('A')
    
    for name, group in grouped:
        ...
  • Quando você aplica uma função na groupby, no seu exemplo df.groupby(...).agg(...)(mas isso também pode ser transform, apply, mean, ...), você combinar o resultado de aplicar a função para os diferentes grupos juntos em uma trama de dados (a aplicar e combinar etapa do paradigma 'split-apply-combine' de groupby). Portanto, o resultado disso sempre será novamente um DataFrame (ou uma Série, dependendo da função aplicada).

joris
fonte
50

Aqui está um exemplo de iteração sobre um pd.DataFrameagrupado pela coluna atable. Para um exemplo de caso de usuário, instruções "create" para um banco de dados SQL são geradas no forloop:

import pandas as pd

df1 = pd.DataFrame({
    'atable':     ['Users', 'Users', 'Domains', 'Domains', 'Locks'],
    'column':     ['col_1', 'col_2', 'col_a', 'col_b', 'col'],
    'column_type':['varchar', 'varchar', 'int', 'varchar', 'varchar'],
    'is_null':    ['No', 'No', 'Yes', 'No', 'Yes'],
})

df1_grouped = df1.groupby('atable')

# iterate over each group
for group_name, df_group in df1_grouped:
    print('\nCREATE TABLE {}('.format(group_name))

    for row_index, row in df_group.iterrows():
        col = row['column']
        column_type = row['column_type']
        is_null = 'NOT NULL' if row['is_null'] == 'NO' else ''
        print('\t{} {} {},'.format(col, column_type, is_null))

    print(");")
Andrei Sura
fonte
8
Obrigado por demonstrar que você pode iterar através de uma pessoa groupusando for row, data in group.iterrows()!
tatlar
16

Você pode iterar sobre os valores do índice se o seu quadro de dados já tiver sido criado.

df = df.groupby('l_customer_id_i').agg(lambda x: ','.join(x))
for name in df.index:
    print name
    print df.loc[name]
Khiner
fonte