Jak zapętlić zgrupowaną ramkę danych Pandas?

146

Ramka danych:

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

Kod:

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

Próbuję po prostu zapętlić zagregowane dane, ale pojawia się błąd:

ValueError: zbyt wiele wartości do rozpakowania

@EdChum, oto oczekiwane dane wyjściowe:

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

Wyjście nie jest problemem, chciałbym zapętlić każdą grupę.

Tjorriemorrie
źródło

Odpowiedzi:

224

df.groupby('l_customer_id_i').agg(lambda x: ','.join(x)) zwraca już ramkę danych, więc nie możesz już zapętlić grup.

Ogólnie:

  • df.groupby(...)zwraca GroupByobiekt (DataFrameGroupBy lub SeriesGroupBy) i dzięki temu możesz iterować po grupach (jak wyjaśniono w dokumentacji tutaj ). Możesz zrobić coś takiego:

    grouped = df.groupby('A')
    
    for name, group in grouped:
        ...
    
  • Po zastosowaniu funkcji na GroupBy, w Twojej przykład df.groupby(...).agg(...)(ale może to być również transform, apply, mean, ...), należy połączyć wyniku stosowania funkcji dla różnych grup razem w jednym dataframe (Zastosuj i połączyć kroku paradygmat „podziel-zastosuj-połącz” grupowania). Tak więc wynikiem tego zawsze będzie ponownie DataFrame (lub Series w zależności od zastosowanej funkcji).

joris
źródło
50

Oto przykład iteracji po grupie pd.DataFramezgrupowanej według kolumny atable. Na przykład w forpętli generowane są instrukcje „create” dla bazy danych SQL :

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
źródło
8
Dziękujemy za zademonstrowanie, że możesz iterować po indywidualnym groupużyciu for row, data in group.iterrows()!
tatlar
16

Możesz iterować po wartościach indeksu, jeśli twoja ramka danych została już utworzona.

df = df.groupby('l_customer_id_i').agg(lambda x: ','.join(x))
for name in df.index:
    print name
    print df.loc[name]
khiner
źródło