it-swarm.com.de

Konvertieren einer Pandas GroupBy-Ausgabe von Series in DataFrame

Ich beginne mit solchen Eingabedaten

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

Was beim Drucken so aussieht:

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

Die Gruppierung ist einfach genug:

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

und Drucken ergibt ein GroupBy Objekt:

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

Aber was ich irgendwann möchte, ist ein anderes DataFrame-Objekt, das alle Zeilen im GroupBy-Objekt enthält. Mit anderen Worten möchte ich das folgende Ergebnis erhalten:

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

Wie das geht, kann ich der Dokumentation pandas nicht ganz entnehmen. Hinweise wären willkommen.

405
saveenr

g1 hier ist ein DataFrame. Es hat jedoch einen hierarchischen Index:

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)

Vielleicht willst du so etwas?

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

Oder so etwas wie:

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
443
Wes McKinney

Ich möchte die Antwort von Wes etwas ändern, da für Version 0.16.2 _as_index=False_ erforderlich ist. Wenn Sie es nicht einstellen, erhalten Sie einen leeren Datenrahmen.

Quelle :

Aggregationsfunktionen geben die Gruppen, über die Sie aggregieren, nicht zurück, wenn sie Spalten heißen, wenn _as_index=True_ der Standardwert ist. Die gruppierten Spalten sind die Indizes des zurückgegebenen Objekts.

Wenn Sie _as_index=False_ übergeben, werden die Gruppen, über die Sie aggregieren, zurückgegeben, sofern sie Spalten heißen.

Aggregieren von Funktionen sind diejenigen, die die Dimension der zurückgegebenen Objekte zu reduzieren, zum Beispiel: mean, sum, size, count, std, var, sem, describe, first, last, nth, min, max. Dies ist der Fall, wenn Sie beispielsweise DataFrame.sum() ausführen und einen Series zurückerhalten.

nth kann als Reduzierer oder Filter wirken, siehe hier .

_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
#
_

BEARBEITEN:

In Version _0.17.1_ und höher können Sie subset in count und reset_index mit dem Parameter name in size verwenden:

_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
_

Der Unterschied zwischen count und size besteht darin, dass size NaN-Werte zählt, während count dies nicht tut.

98
jezrael

Dies sollte einfach die Aufgabe erfüllen:

import pandas as pd

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

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

Hier ruft grouped_df.size () die Anzahl der eindeutigen Gruppen auf, und die Methode reset_index () setzt den Namen der Spalte zurück, die Sie haben möchten. Schließlich wird die Funktion pandas Dataframe () aufgerufen, um ein DataFrame-Objekt zu erstellen.

12
Surya

Vielleicht verstehe ich die Frage falsch, aber wenn Sie die Gruppe zurück in einen Datenrahmen konvertieren möchten, können Sie .to_frame () verwenden. Ich wollte den Index zurücksetzen, als ich das tat, also bezog ich auch diesen Teil mit ein.

beispielcode ohne Bezug zur Frage

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

Ich fand, das hat bei mir funktioniert.

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
thefebruaryman

Der Schlüssel ist die Verwendung der reset_index () -Methode.

Verwenden:

import pandas

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

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

Jetzt haben Sie Ihren neuen Datenrahmen in g1 :

result dataframe

3
Ferd

Die folgende Lösung kann einfacher sein:

df1.reset_index().groupby( [ "Name", "City"],as_index=False ).count()
3
Xiao QianYu

Ich habe mit der Menge an Daten aggregiert und im Datenrahmen gespeichert

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

Diese Lösungen haben bei mir nur teilweise funktioniert, da ich mehrere Aggregationen durchgeführt habe. Hier ist eine Beispielausgabe meiner Gruppierung, die ich in einen Datenrahmen konvertieren wollte:

Groupby Output

Da ich mehr als die von reset_index () bereitgestellte Anzahl haben wollte, habe ich eine manuelle Methode zum Konvertieren des obigen Bildes in einen Datenrahmen geschrieben. Ich verstehe, dass dies nicht die pythonischste/pandas-Methode ist, da es ziemlich ausführlich und explizit ist, aber es war alles, was ich brauchte. Verwenden Sie im Allgemeinen die oben erläuterte Methode reset_index (), um einen "Gerüst" -Datenrahmen zu starten, und durchlaufen Sie dann die Gruppenpaarungen im gruppierten Datenrahmen, rufen Sie die Indizes ab, führen Sie Ihre Berechnungen mit dem nicht gruppierten Datenrahmen durch und setzen Sie den Wert in Ihrem neuen aggregierten Datenrahmen .

df_grouped = df[['Salary Basis', 'Job Title', 'Hourly Rate', 'Male Count', 'Female Count']]
df_grouped = df_grouped.groupby(['Salary Basis', 'Job Title'], as_index=False)

# Grouped gives us the indices we want for each grouping
# We cannot convert a groupedby object back to a dataframe, so we need to do it manually
# Create a new dataframe to work against
df_aggregated = df_grouped.size().to_frame('Total Count').reset_index()
df_aggregated['Male Count'] = 0
df_aggregated['Female Count'] = 0
df_aggregated['Job Rate'] = 0

def manualAggregations(indices_array):
    temp_df = df.iloc[indices_array]
    return {
        'Male Count': temp_df['Male Count'].sum(),
        'Female Count': temp_df['Female Count'].sum(),
        'Job Rate': temp_df['Hourly Rate'].max()
    }

for name, group in df_grouped:
    ix = df_grouped.indices[name]
    calcDict = manualAggregations(ix)

    for key in calcDict:
        #Salary Basis, Job Title
        columns = list(name)
        df_aggregated.loc[(df_aggregated['Salary Basis'] == columns[0]) & 
                          (df_aggregated['Job Title'] == columns[1]), key] = calcDict[key]

Wenn ein Wörterbuch nicht Ihr Ding ist, könnten die Berechnungen inline in der for-Schleife angewendet werden:

    df_aggregated['Male Count'].loc[(df_aggregated['Salary Basis'] == columns[0]) & 
                                (df_aggregated['Job Title'] == columns[1])] = df['Male Count'].iloc[ix].sum()
1
John Galt