Comment faire une boucle sur une trame de données Pandas groupée?

146

Trame de données:

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

Code:

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

J'essaye juste de boucler sur les données agrégées, mais j'obtiens l'erreur:

ValueError: trop de valeurs à décompresser

@EdChum, voici le résultat attendu:

                                                    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           ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,...

La sortie n'est pas le problème, je souhaite boucler sur chaque groupe.

Tjorriemorrie
la source

Réponses:

224

df.groupby('l_customer_id_i').agg(lambda x: ','.join(x)) renvoie déjà un dataframe, donc vous ne pouvez plus boucler sur les groupes.

En général:

  • df.groupby(...)renvoie un GroupByobjet (un DataFrameGroupBy ou SeriesGroupBy), et avec cela, vous pouvez parcourir les groupes (comme expliqué dans la documentation ici ). Vous pouvez faire quelque chose comme:

    grouped = df.groupby('A')
    
    for name, group in grouped:
        ...
  • Lorsque vous appliquez une fonction sur le groupby, dans votre exemple df.groupby(...).agg(...)(mais cela peut aussi être transform, apply, mean, ...), vous combinez le résultat de l' application de la fonction aux différents groupes dans une trame de données (l'appliquer et moissonneuse - batteuse étape du paradigme 'split-apply-combine' de groupby). Ainsi, le résultat sera toujours à nouveau un DataFrame (ou une série selon la fonction appliquée).

joris
la source
50

Voici un exemple d'itération sur un pd.DataFramegroupé par colonne atable. Pour un exemple de cas d'utilisation, les instructions "create" pour une base de données SQL sont générées dans la forboucle:

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
la source
8
Merci d'avoir démontré que vous pouvez parcourir un individu en grouputilisant for row, data in group.iterrows()!
tatlar
16

Vous pouvez parcourir les valeurs d'index si votre dataframe a déjà été créée.

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