So greifen Sie auf Pandas Groupby Dataframe per Key zu

153

Wie greife ich mit dem Schlüssel auf den entsprechenden groupby-Datenrahmen in einem groupby-Objekt zu?

Mit folgender Gruppe:

rand = np.random.RandomState(1)
df = pd.DataFrame({'A': ['foo', 'bar'] * 3,
                   'B': rand.randn(6),
                   'C': rand.randint(0, 20, 6)})
gb = df.groupby(['A'])

Ich kann es durchlaufen, um die Schlüssel und Gruppen zu erhalten:

In [11]: for k, gp in gb:
             print 'key=' + str(k)
             print gp
key=bar
     A         B   C
1  bar -0.611756  18
3  bar -1.072969  10
5  bar -2.301539  18
key=foo
     A         B   C
0  foo  1.624345   5
2  foo -0.528172  11
4  foo  0.865408  14

Ich möchte über ihren Schlüssel auf eine Gruppe zugreifen können:

In [12]: gb['foo']
Out[12]:  
     A         B   C
0  foo  1.624345   5
2  foo -0.528172  11
4  foo  0.865408  14

Aber wenn ich das mit versuche, gb[('foo',)]bekomme ich dieses seltsame pandas.core.groupby.DataFrameGroupByObjekt, das keine Methoden zu haben scheint, die dem gewünschten DataFrame entsprechen.

Das Beste, was ich mir vorstellen kann, ist:

In [13]: def gb_df_key(gb, key, orig_df):
             ix = gb.indices[key]
             return orig_df.ix[ix]

         gb_df_key(gb, 'foo', df)
Out[13]:
     A         B   C
0  foo  1.624345   5
2  foo -0.528172  11
4  foo  0.865408  14  

Aber das ist irgendwie böse, wenn man bedenkt, wie nett Pandas normalerweise in diesen Dingen sind.
Was ist die eingebaute Methode, um dies zu tun?

Bart
quelle

Antworten:

191

Sie können die get_groupMethode verwenden:

In [21]: gb.get_group('foo')
Out[21]: 
     A         B   C
0  foo  1.624345   5
2  foo -0.528172  11
4  foo  0.865408  14

Hinweis: Dies erfordert nicht das Erstellen eines Zwischenwörterbuchs / einer Zwischenkopie jedes Unterdatenrahmens für jede Gruppe. Dies ist daher viel speichereffizienter als das Erstellen des naiven Wörterbuchs mit dict(iter(gb)). Dies liegt daran, dass Datenstrukturen verwendet werden, die bereits im groupby-Objekt verfügbar sind.


Sie können verschiedene Spalten mithilfe des Groupby-Slicing auswählen:

In [22]: gb[["A", "B"]].get_group("foo")
Out[22]:
     A         B
0  foo  1.624345
2  foo -0.528172
4  foo  0.865408

In [23]: gb["C"].get_group("foo")
Out[23]:
0     5
2    11
4    14
Name: C, dtype: int64
Andy Hayden
quelle
72

Wes McKinney (Pandas 'Autor) in Python for Data Analysis bietet das folgende Rezept:

groups = dict(list(gb))

Dies gibt ein Wörterbuch zurück, dessen Schlüssel Ihre Gruppenbezeichnungen sind und dessen Werte DataFrames sind, d. h

groups['foo']

wird ergeben, wonach Sie suchen:

     A         B   C
0  foo  1.624345   5
2  foo -0.528172  11
4  foo  0.865408  14
JD Margulici
quelle
1
Vielen Dank, das ist sehr nützlich. Wie kann ich den Code so ändern, dass groups = dict(list(gb))nur eine Spalte gespeichert wird C? Angenommen, ich interessiere mich nicht für die anderen Spalten und möchte sie daher nicht speichern.
Zhubarb
5
Antwort:dict(list( df.groupby(['A'])['C'] ))
Zhubarb
4
Hinweis: Die Verwendung ist effizienter (aber gleichwertig) dict(iter(g)). (obwohl get_groupes der beste Weg ist / da es nicht darum geht, ein Wörterbuch zu erstellen / hält dich in Pandas !: D)
Andy Hayden
Ich konnte keine Gruppen verwenden (dict (list (gb)), aber Sie können ein Wörterbuch folgendermaßen erstellen: gb_dict = {str(indx): str(val) for indx in gb.indx for val in gb.some_key}und dann den Wert übergb_dict[some_key]
user2476665
Verwenden Sie einfach get_group(), dieses Rezept wird seit Jahren nicht mehr benötigt.
smci
20

Eher, als

gb.get_group('foo')

Ich benutze lieber gb.groups

df.loc[gb.groups['foo']]

Denn auf diese Weise können Sie auch mehrere Spalten auswählen. beispielsweise:

df.loc[gb.groups['foo'],('A','B')]
LegitMe
quelle
4
Hinweis: Sie können verschiedene Spalten mit auswählen gb[["A", "B"]].get_group("foo").
Andy Hayden
6
gb = df.groupby(['A'])

gb_groups = grouped_df.groups

Wenn Sie nach selektiven Groupby-Objekten suchen, gehen Sie wie folgt vor: gb_groups.keys () und geben Sie den gewünschten Schlüssel in die folgende Schlüsselliste ein.

gb_groups.keys()

key_list = [key1, key2, key3 and so on...]

for key, values in gb_groups.iteritems():
    if key in key_list:
        print df.ix[values], "\n"
Surya
quelle
1

Ich suchte nach einer Möglichkeit, einige Mitglieder des GroupBy-Objekts zu befragen - musste die gestellte Frage beantworten, um dies zu erreichen.

Groupby-Objekt erstellen

grouped = df.groupby('some_key')

Wählen Sie N Datenrahmen und greifen Sie auf deren Angaben zu

sampled_df_i  = random.sample(grouped.indicies, N)

Schnapp dir die Gruppen

df_list  = map(lambda df_i: grouped.get_group(df_i), sampled_df_i)

Optional - verwandeln Sie alles wieder in ein einziges Datenrahmenobjekt

sampled_df = pd.concat(df_list, axis=0, join='outer')
Meyerson
quelle
1
Das funktioniert nicht:sampled_df_i = random.sample(grouped.indicies, N)
irene
@irene - Kannst du einen Link zu einem längeren Beispiel / mehr Kontext bereitstellen?
Meyerson
Ich erhalte die folgende Fehlermeldung:AttributeError: 'DataFrameGroupBy' object has no attribute 'indicies'
irene