2012-04-29 29 views
231

Sto iniziando con i dati di input come questoConversione di un oggetto Pandas GroupBy a dataframe

df1 = pandas.DataFrame({ 
    "Name" : ["Alice", "Bob", "Mallory", "Mallory", "Bob" , "Mallory"] , 
    "City" : ["Seattle", "Seattle", "Portland", "Seattle", "Seattle", "Portland"] }) 

Quali quando stampato appare come questa:

City  Name 
0 Seattle Alice 
1 Seattle  Bob 
2 Portland Mallory 
3 Seattle Mallory 
4 Seattle  Bob 
5 Portland Mallory 

raggruppamento è abbastanza semplice:

g1 = df1.groupby([ "Name", "City"]).count() 

e la stampa produce un oggetto GroupBy:

    City Name 
Name City 
Alice Seattle  1  1 
Bob  Seattle  2  2 
Mallory Portland  2  2 
     Seattle  1  1 

Ma quello che voglio alla fine è un altro oggetto DataFrame che contiene tutte le righe nell'oggetto GroupBy. In altre parole, voglio ottenere il seguente risultato:

    City Name 
Name City 
Alice Seattle  1  1 
Bob  Seattle  2  2 
Mallory Portland  2  2 
Mallory Seattle  1  1 

non riesco a vedere come realizzare questo nella documentazione panda. Qualsiasi suggerimento sarebbe benvenuto.

risposta

301

g1 qui è un DataFrame. Ha un indice gerarchico, però:

In [19]: type(g1) 
Out[19]: pandas.core.frame.DataFrame 

In [20]: g1.index 
Out[20]: 
MultiIndex([('Alice', 'Seattle'), ('Bob', 'Seattle'), ('Mallory', 'Portland'), 
     ('Mallory', 'Seattle')], dtype=object) 

Forse vuoi qualcosa del genere?

In [21]: g1.add_suffix('_Count').reset_index() 
Out[21]: 
     Name  City City_Count Name_Count 
0 Alice Seattle   1   1 
1  Bob Seattle   2   2 
2 Mallory Portland   2   2 
3 Mallory Seattle   1   1 

O qualcosa di simile:

In [36]: DataFrame({'count' : df1.groupby([ "Name", "City"]).size()}).reset_index() 
Out[36]: 
     Name  City count 
0 Alice Seattle  1 
1  Bob Seattle  2 
2 Mallory Portland  2 
3 Mallory Seattle  1 
+6

Grande risposta. Il secondo caso che hai mostrato con una singola colonna "count" era esattamente * quello di cui avevo bisogno. – saveenr

+6

'reset.index()' fa il lavoro, ottimo! – gented

+16

Si potrebbe avere usato: 'df1.groupby ([" Nome "," Città "]) .size(). To_frame (name = 'count'). Reset_index()' –

65

voglio po risposta cambiamento po 'di Wes, perché la versione 0.16.2 necessità impostato as_index=False. Se non lo si imposta, si ottiene un dataframe vuoto.

Source:

Funzioni di aggregazione non restituirà i gruppi che si stanno aggregando sopra se si chiamano colonne, quando as_index=True, l'impostazione predefinita. Le colonne raggruppate saranno gli indici dell'oggetto restituito.

Il passaggio as_index=False restituirà i gruppi su cui si sta aggregando, se sono denominati colonne.

funzioni di aggregazione sono quelli che riducono la dimensione degli oggetti restituiti, per esempio: mean, sum, size, count, std, var, sem, describe, first, last, nth, min, max. Questo è ciò che accade quando si esegue ad esempio DataFrame.sum() e si ottiene un Series.

n ° può funzionare come un riduttore o un filtro, vedere here.

import pandas as pd 

df1 = pd.DataFrame({"Name":["Alice", "Bob", "Mallory", "Mallory", "Bob" , "Mallory"], 
        "City":["Seattle","Seattle","Portland","Seattle","Seattle","Portland"]}) 
print df1 
# 
#  City  Name 
#0 Seattle Alice 
#1 Seattle  Bob 
#2 Portland Mallory 
#3 Seattle Mallory 
#4 Seattle  Bob 
#5 Portland Mallory 
# 
g1 = df1.groupby(["Name", "City"], as_index=False).count() 
print g1 
# 
#     City Name 
#Name City 
#Alice Seattle  1  1 
#Bob  Seattle  2  2 
#Mallory Portland  2  2 
#  Seattle  1  1 
# 

EDIT:

Nella versione 0.17.1 e successivamente è possibile utilizzare subset in count e reset_index con il parametro name in size:

print df1.groupby(["Name", "City"], as_index=False).count() 
#IndexError: list index out of range 

print df1.groupby(["Name", "City"]).count() 
#Empty DataFrame 
#Columns: [] 
#Index: [(Alice, Seattle), (Bob, Seattle), (Mallory, Portland), (Mallory, Seattle)] 

print df1.groupby(["Name", "City"])[['Name','City']].count() 
#     Name City 
#Name City     
#Alice Seattle  1  1 
#Bob  Seattle  2  2 
#Mallory Portland  2  2 
#  Seattle  1  1 

print df1.groupby(["Name", "City"]).size().reset_index(name='count') 
#  Name  City count 
#0 Alice Seattle  1 
#1  Bob Seattle  2 
#2 Mallory Portland  2 
#3 Mallory Seattle  1 

La differenza tra count e size è che size conta i valori NaN mentre count no.

+6

Penso che questo sia il modo più semplice - un solo liner che usa il bel fatto che puoi nominare la colonna della serie con reset_index: '' 'df1.groupby ([" Name "," City "]). Size(). Reset_index (name = "count") '' ' – Ben

+0

C'è una ragione per cui' as_index = False 'ha smesso di funzionare nelle ultime versioni? Ho anche provato a lanciare 'df1.groupby ([" Nome "," Città "], as_index = False) .size()' ma non influenza il risultato (probabilmente perché il risultato del raggruppamento è 'Serie' non' DataFrame' –

+1

Non sono sicuro, ma sembra che ci siano solo 2 colonne e 'groupby' da queste colonne.Ma non sono sicuro, perché non sono uno sviluppatore di pandas – jezrael

4

Ho trovato questo ha funzionato per me.

import numpy as np 
import pandas as pd 

df1 = pd.DataFrame({ 
    "Name" : ["Alice", "Bob", "Mallory", "Mallory", "Bob" , "Mallory"] , 
    "City" : ["Seattle", "Seattle", "Portland", "Seattle", "Seattle", "Portland"]}) 

df1['City_count'] = 1 
df1['Name_count'] = 1 

df1.groupby(['Name', 'City'], as_index=False).count() 
5

Semplicemente, questo dovrebbe fare il compito:

import pandas as pd 

grouped_df = df1.groupby([ "Name", "City"]) 

pd.DataFrame(grouped_df.size().reset_index(name = "Group_Count")) 

Qui, grouped_df.size() tira sul conteggio GroupBy unico, e reset_index() il metodo reimposta il nome della colonna che si desidera essere. Infine, la funzione Dataframe() di pandas viene chiamata per creare l'oggetto DataFrame.

+0

Controlla il metodo .to_frame(): grouped_df.size() .to_frame ('Group_Count') – Sealander

3

Forse ho frainteso la domanda, ma se vuoi riconvertire il gruppo in un dataframe puoi usare .to_frame(). Volevo resettare l'indice quando l'ho fatto, quindi ho incluso anche quella parte.

codice di esempio non correlato alla domanda

df = df['TIME'].groupby(df['Name']).min() 
df = df.to_frame() 
df = df.reset_index(level=['Name',"TIME"]) 
1

ho aggregato con Quantita dati saggi e negozio per dataframe

almo_grp_data = pd.DataFrame({'Qty_cnt' : 
almo_slt_models_data.groupby(['orderDate','Item','State Abv'] 
     )['Qty'].sum()}).reset_index()