Integration mit Ibis
Ibis ist eine Python-Dataframe-Bibliothek mit Unterstützung für über 20 Backends; DuckDB ist das Standard-Backend. Ibis mit DuckDB bietet eine pythoneske Schnittstelle für SQL bei hoher Leistung.
Installation
Sie können Ibis mit dem DuckDB-Backend per pip installieren:
pip install 'ibis-framework[duckdb,examples]' # examples is only required to access the sample data Ibis providesoder conda verwenden:
conda install ibis-frameworkoder mamba verwenden:
mamba install ibis-frameworkEine Datenbankdatei anlegen
Ibis kann mit mehreren Dateitypen arbeiten, im Kern verbindet es sich aber mit bestehenden Datenbanken und interagiert dort mit den Daten. Sie können mit Ihren eigenen DuckDB-Datenbanken starten oder eine neue mit Beispieldaten anlegen.
import ibis
con = ibis.connect("duckdb://penguins.ddb")con.create_table( "penguins", ibis.examples.penguins.fetch().to_pyarrow(), overwrite = True)# Output:DatabaseTable: penguins species string island string bill_length_mm float64 bill_depth_mm float64 flipper_length_mm int64 body_mass_g int64 sex string year int64Sie können jetzt sehen, dass der Beispieldatensatz in die Datenbank kopiert wurde:
# reconnect to the persisted database (dropping temp tables)con = ibis.connect("duckdb://penguins.ddb")con.list_tables()# Output:['penguins']Es gibt eine Tabelle namens penguins. Wir können Ibis um ein Objekt bitten, mit dem wir interagieren können.
penguins = con.table("penguins")penguins# Output:DatabaseTable: penguins species string island string bill_length_mm float64 bill_depth_mm float64 flipper_length_mm int64 body_mass_g int64 sex string year int64Ibis wird verzögert ausgewertet, daher sehen wir statt der Daten das Schema der Tabelle. Um einen Blick auf die Daten zu werfen, können wir head und anschließend to_pandas aufrufen, um die ersten Zeilen der Tabelle als pandas-DataFrame zu erhalten.
penguins.head().to_pandas() species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex year0 Adelie Torgersen 39.1 18.7 181.0 3750.0 male 20071 Adelie Torgersen 39.5 17.4 186.0 3800.0 female 20072 Adelie Torgersen 40.3 18.0 195.0 3250.0 female 20073 Adelie Torgersen NaN NaN NaN NaN None 20074 Adelie Torgersen 36.7 19.3 193.0 3450.0 female 2007to_pandas nimmt den bestehenden verzögerten Tabellenausdruck und wertet ihn aus. Lassen wir es weg, sehen Sie die Ibis-Darstellung des Tabellenausdrucks, den to_pandas auswerten wird (wenn Sie soweit sind!).
penguins.head()# Output:r0 := DatabaseTable: penguins species string island string bill_length_mm float64 bill_depth_mm float64 flipper_length_mm int64 body_mass_g int64 sex string year int64
Limit[r0, n=5]Ibis gibt Ergebnisse mit to_pandas als pandas-DataFrame zurück, verwendet pandas aber nicht für die Berechnung. Die Abfrage wird von DuckDB ausgeführt. Erst wenn to_pandas aufgerufen wird, holt Ibis die Ergebnisse zurück und wandelt sie in ein DataFrame um.
Interaktiver Modus
Für den Rest dieser Einführung schalten wir den interaktiven Modus ein, der Abfragen teilweise ausführt, um eine Vorschau der Ergebnisse zu zeigen. Die Ausgabe ist etwas anders formatiert, ansonsten entspricht das dem Aufruf von to_pandas auf dem Tabellenausdruck mit einem Limit von 10 Ergebniszeilen.
ibis.options.interactive = Truepenguins.head()┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓┃ species ┃ island ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ sex ┃ year ┃┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩│ string │ string │ float64 │ float64 │ int64 │ int64 │ string │ int64 │├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┤│ Adelie │ Torgersen │ 39.1 │ 18.7 │ 181 │ 3750 │ male │ 2007 ││ Adelie │ Torgersen │ 39.5 │ 17.4 │ 186 │ 3800 │ female │ 2007 ││ Adelie │ Torgersen │ 40.3 │ 18.0 │ 195 │ 3250 │ female │ 2007 ││ Adelie │ Torgersen │ nan │ nan │ NULL │ NULL │ NULL │ 2007 ││ Adelie │ Torgersen │ 36.7 │ 19.3 │ 193 │ 3450 │ female │ 2007 │└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┘Häufige Operationen
Ibis bietet eine Sammlung nützlicher Tabellenmethoden, um Daten in einer Tabelle zu bearbeiten und abzufragen.
filter
Mit filter wählen Sie Zeilen anhand einer Bedingung oder mehrerer Bedingungen aus.
Wir können so filtern, dass nur Pinguine der Art Gentoo übrig bleiben:
penguins.filter(penguins.species == "Gentoo")┏━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓┃ species ┃ island ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ sex ┃ year ┃┡━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩│ string │ string │ float64 │ float64 │ int64 │ int64 │ string │ int64 │├─────────┼────────┼────────────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┤│ Gentoo │ Biscoe │ 46.1 │ 13.2 │ 211 │ 4500 │ female │ 2007 ││ Gentoo │ Biscoe │ 50.0 │ 16.3 │ 230 │ 5700 │ male │ 2007 ││ Gentoo │ Biscoe │ 48.7 │ 14.1 │ 210 │ 4450 │ female │ 2007 ││ Gentoo │ Biscoe │ 50.0 │ 15.2 │ 218 │ 5700 │ male │ 2007 ││ Gentoo │ Biscoe │ 47.6 │ 14.5 │ 215 │ 5400 │ male │ 2007 ││ Gentoo │ Biscoe │ 46.5 │ 13.5 │ 210 │ 4550 │ female │ 2007 ││ Gentoo │ Biscoe │ 45.4 │ 14.6 │ 211 │ 4800 │ female │ 2007 ││ Gentoo │ Biscoe │ 46.7 │ 15.3 │ 219 │ 5200 │ male │ 2007 ││ Gentoo │ Biscoe │ 43.3 │ 13.4 │ 209 │ 4400 │ female │ 2007 ││ Gentoo │ Biscoe │ 46.8 │ 15.4 │ 215 │ 5150 │ male │ 2007 ││ … │ … │ … │ … │ … │ … │ … │ … │└─────────┴────────┴────────────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┘Oder nach Gentoo-Pinguinen filtern, deren Körpermasse größer als 6 kg ist.
penguins.filter((penguins.species == "Gentoo") & (penguins.body_mass_g > 6000))┏━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓┃ species ┃ island ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ sex ┃ year ┃┡━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩│ string │ string │ float64 │ float64 │ int64 │ int64 │ string │ int64 │├─────────┼────────┼────────────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┤│ Gentoo │ Biscoe │ 49.2 │ 15.2 │ 221 │ 6300 │ male │ 2007 ││ Gentoo │ Biscoe │ 59.6 │ 17.0 │ 230 │ 6050 │ male │ 2007 │└─────────┴────────┴────────────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┘Sie können jeden booleschen Vergleich in einem Filter verwenden (wenn Sie allerdings etwas wie < auf einem String versuchen, beschwert sich Ibis).
select
Ihre Datenanalyse benötigt vielleicht nicht alle Spalten einer Tabelle. Mit select wählen Sie nur die Spalten aus, mit denen Sie arbeiten möchten.
Um eine Spalte auszuwählen, können Sie den Spaltennamen als String verwenden:
penguins.select("species", "island", "year").limit(3)┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓┃ species ┃ island ┃ year ┃┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩│ string │ string │ int64 │├─────────┼───────────┼───────┤│ Adelie │ Torgersen │ 2007 ││ Adelie │ Torgersen │ 2007 ││ Adelie │ Torgersen │ 2007 ││ … │ … │ … │└─────────┴───────────┴───────┘Oder Sie verwenden Spaltenobjekte direkt (das ist praktisch in Kombination mit Tab-Vervollständigung):
penguins.select(penguins.species, penguins.island, penguins.year).limit(3)┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓┃ species ┃ island ┃ year ┃┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩│ string │ string │ int64 │├─────────┼───────────┼───────┤│ Adelie │ Torgersen │ 2007 ││ Adelie │ Torgersen │ 2007 ││ Adelie │ Torgersen │ 2007 ││ … │ … │ … │└─────────┴───────────┴───────┘Oder Sie mischen beides:
penguins.select("species", "island", penguins.year).limit(3)┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓┃ species ┃ island ┃ year ┃┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩│ string │ string │ int64 │├─────────┼───────────┼───────┤│ Adelie │ Torgersen │ 2007 ││ Adelie │ Torgersen │ 2007 ││ Adelie │ Torgersen │ 2007 ││ … │ … │ … │└─────────┴───────────┴───────┘mutate
Mit mutate fügen Sie Ihrer Tabelle neue Spalten hinzu, die aus den Werten vorhandener Spalten abgeleitet werden.
penguins.mutate(bill_length_cm=penguins.bill_length_mm / 10)┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┓┃ species ┃ island ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ sex ┃ year ┃ bill_length_cm ┃┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━┩│ string │ string │ float64 │ float64 │ int64 │ int64 │ string │ int64 │ float64 │├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┼────────────────┤│ Adelie │ Torgersen │ 39.1 │ 18.7 │ 181 │ 3750 │ male │ 2007 │ 3.91 ││ Adelie │ Torgersen │ 39.5 │ 17.4 │ 186 │ 3800 │ female │ 2007 │ 3.95 ││ Adelie │ Torgersen │ 40.3 │ 18.0 │ 195 │ 3250 │ female │ 2007 │ 4.03 ││ Adelie │ Torgersen │ nan │ nan │ NULL │ NULL │ NULL │ 2007 │ nan ││ Adelie │ Torgersen │ 36.7 │ 19.3 │ 193 │ 3450 │ female │ 2007 │ 3.67 ││ Adelie │ Torgersen │ 39.3 │ 20.6 │ 190 │ 3650 │ male │ 2007 │ 3.93 ││ Adelie │ Torgersen │ 38.9 │ 17.8 │ 181 │ 3625 │ female │ 2007 │ 3.89 ││ Adelie │ Torgersen │ 39.2 │ 19.6 │ 195 │ 4675 │ male │ 2007 │ 3.92 ││ Adelie │ Torgersen │ 34.1 │ 18.1 │ 193 │ 3475 │ NULL │ 2007 │ 3.41 ││ Adelie │ Torgersen │ 42.0 │ 20.2 │ 190 │ 4250 │ NULL │ 2007 │ 4.20 ││ … │ … │ … │ … │ … │ … │ … │ … │ … │└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┴────────────────┘Die Tabelle ist jetzt etwas zu breit, um alle Spalten anzuzeigen (je nach Bildschirmgröße). bill_length liegt nun in Millimetern und Zentimetern vor. Mit einem select reduzieren Sie die Anzahl der betrachteten Spalten.
penguins.mutate(bill_length_cm=penguins.bill_length_mm / 10).select( "species", "island", "bill_depth_mm", "flipper_length_mm", "body_mass_g", "sex", "year", "bill_length_cm",)┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┓┃ species ┃ island ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ sex ┃ year ┃ bill_length_cm ┃┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━┩│ string │ string │ float64 │ int64 │ int64 │ string │ int64 │ float64 │├─────────┼───────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┼────────────────┤│ Adelie │ Torgersen │ 18.7 │ 181 │ 3750 │ male │ 2007 │ 3.91 ││ Adelie │ Torgersen │ 17.4 │ 186 │ 3800 │ female │ 2007 │ 3.95 ││ Adelie │ Torgersen │ 18.0 │ 195 │ 3250 │ female │ 2007 │ 4.03 ││ Adelie │ Torgersen │ nan │ NULL │ NULL │ NULL │ 2007 │ nan ││ Adelie │ Torgersen │ 19.3 │ 193 │ 3450 │ female │ 2007 │ 3.67 ││ Adelie │ Torgersen │ 20.6 │ 190 │ 3650 │ male │ 2007 │ 3.93 ││ Adelie │ Torgersen │ 17.8 │ 181 │ 3625 │ female │ 2007 │ 3.89 ││ Adelie │ Torgersen │ 19.6 │ 195 │ 4675 │ male │ 2007 │ 3.92 ││ Adelie │ Torgersen │ 18.1 │ 193 │ 3475 │ NULL │ 2007 │ 3.41 ││ Adelie │ Torgersen │ 20.2 │ 190 │ 4250 │ NULL │ 2007 │ 4.20 ││ … │ … │ … │ … │ … │ … │ … │ … │└─────────┴───────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┴────────────────┘selectors
Alle Spaltennamen außer einer auszutippen ist etwas lästig. Stattdessen können wir einen selector verwenden, um Gruppen von Spalten schnell aus- oder abzuwählen.
import ibis.selectors as s
penguins.mutate(bill_length_cm=penguins.bill_length_mm / 10).select( ~s.matches("bill_length_mm") # match every column except `bill_length_mm`)┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┓┃ species ┃ island ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ sex ┃ year ┃ bill_length_cm ┃┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━┩│ string │ string │ float64 │ int64 │ int64 │ string │ int64 │ float64 │├─────────┼───────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┼────────────────┤│ Adelie │ Torgersen │ 18.7 │ 181 │ 3750 │ male │ 2007 │ 3.91 ││ Adelie │ Torgersen │ 17.4 │ 186 │ 3800 │ female │ 2007 │ 3.95 ││ Adelie │ Torgersen │ 18.0 │ 195 │ 3250 │ female │ 2007 │ 4.03 ││ Adelie │ Torgersen │ nan │ NULL │ NULL │ NULL │ 2007 │ nan ││ Adelie │ Torgersen │ 19.3 │ 193 │ 3450 │ female │ 2007 │ 3.67 ││ Adelie │ Torgersen │ 20.6 │ 190 │ 3650 │ male │ 2007 │ 3.93 ││ Adelie │ Torgersen │ 17.8 │ 181 │ 3625 │ female │ 2007 │ 3.89 ││ Adelie │ Torgersen │ 19.6 │ 195 │ 4675 │ male │ 2007 │ 3.92 ││ Adelie │ Torgersen │ 18.1 │ 193 │ 3475 │ NULL │ 2007 │ 3.41 ││ Adelie │ Torgersen │ 20.2 │ 190 │ 4250 │ NULL │ 2007 │ 4.20 ││ … │ … │ … │ … │ … │ … │ … │ … │└─────────┴───────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┴────────────────┘Sie können einen selector auch zusammen mit einem Spaltennamen verwenden.
penguins.select("island", s.numeric())┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━┓┃ island ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ year ┃┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━┩│ string │ float64 │ float64 │ int64 │ int64 │ int64 │├───────────┼────────────────┼───────────────┼───────────────────┼─────────────┼───────┤│ Torgersen │ 39.1 │ 18.7 │ 181 │ 3750 │ 2007 ││ Torgersen │ 39.5 │ 17.4 │ 186 │ 3800 │ 2007 ││ Torgersen │ 40.3 │ 18.0 │ 195 │ 3250 │ 2007 ││ Torgersen │ nan │ nan │ NULL │ NULL │ 2007 ││ Torgersen │ 36.7 │ 19.3 │ 193 │ 3450 │ 2007 ││ Torgersen │ 39.3 │ 20.6 │ 190 │ 3650 │ 2007 ││ Torgersen │ 38.9 │ 17.8 │ 181 │ 3625 │ 2007 ││ Torgersen │ 39.2 │ 19.6 │ 195 │ 4675 │ 2007 ││ Torgersen │ 34.1 │ 18.1 │ 193 │ 3475 │ 2007 ││ Torgersen │ 42.0 │ 20.2 │ 190 │ 4250 │ 2007 ││ … │ … │ … │ … │ … │ … │└───────────┴────────────────┴───────────────┴───────────────────┴─────────────┴───────┘Mehr zu selectors finden Sie in der Dokumentation!
order_by
order_by ordnet die Werte einer oder mehrerer Spalten aufsteigend oder absteigend.
Standardmäßig sortiert ibis aufsteigend:
penguins.order_by(penguins.flipper_length_mm).select( "species", "island", "flipper_length_mm")┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓┃ species ┃ island ┃ flipper_length_mm ┃┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩│ string │ string │ int64 │├───────────┼───────────┼───────────────────┤│ Adelie │ Biscoe │ 172 ││ Adelie │ Biscoe │ 174 ││ Adelie │ Torgersen │ 176 ││ Adelie │ Dream │ 178 ││ Adelie │ Dream │ 178 ││ Adelie │ Dream │ 178 ││ Chinstrap │ Dream │ 178 ││ Adelie │ Dream │ 179 ││ Adelie │ Torgersen │ 180 ││ Adelie │ Biscoe │ 180 ││ … │ … │ … │└───────────┴───────────┴───────────────────┘Absteigend sortieren Sie mit der Methode desc einer Spalte:
penguins.order_by(penguins.flipper_length_mm.desc()).select( "species", "island", "flipper_length_mm")┏━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓┃ species ┃ island ┃ flipper_length_mm ┃┡━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩│ string │ string │ int64 │├─────────┼────────┼───────────────────┤│ Gentoo │ Biscoe │ 231 ││ Gentoo │ Biscoe │ 230 ││ Gentoo │ Biscoe │ 230 ││ Gentoo │ Biscoe │ 230 ││ Gentoo │ Biscoe │ 230 ││ Gentoo │ Biscoe │ 230 ││ Gentoo │ Biscoe │ 230 ││ Gentoo │ Biscoe │ 230 ││ Gentoo │ Biscoe │ 229 ││ Gentoo │ Biscoe │ 229 ││ … │ … │ … │└─────────┴────────┴───────────────────┘Oder Sie verwenden ibis.desc
penguins.order_by(ibis.desc("flipper_length_mm")).select( "species", "island", "flipper_length_mm")┏━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓┃ species ┃ island ┃ flipper_length_mm ┃┡━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩│ string │ string │ int64 │├─────────┼────────┼───────────────────┤│ Gentoo │ Biscoe │ 231 ││ Gentoo │ Biscoe │ 230 ││ Gentoo │ Biscoe │ 230 ││ Gentoo │ Biscoe │ 230 ││ Gentoo │ Biscoe │ 230 ││ Gentoo │ Biscoe │ 230 ││ Gentoo │ Biscoe │ 230 ││ Gentoo │ Biscoe │ 230 ││ Gentoo │ Biscoe │ 229 ││ Gentoo │ Biscoe │ 229 ││ … │ … │ … │└─────────┴────────┴───────────────────┘aggregate
Ibis bietet mehrere Aggregatfunktionen, um Daten zusammenzufassen.
mean, max, min, count, sum (die Liste geht weiter).
Um eine ganze Spalte zu aggregieren, rufen Sie die entsprechende Methode auf dieser Spalte auf.
penguins.flipper_length_mm.mean()# Output:200.91520467836258Mehrere Aggregate auf einmal berechnen Sie mit der Methode aggregate:
penguins.aggregate([penguins.flipper_length_mm.mean(), penguins.bill_depth_mm.max()])┏━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┓┃ Mean(flipper_length_mm) ┃ Max(bill_depth_mm) ┃┡━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━┩│ float64 │ float64 │├─────────────────────────┼────────────────────┤│ 200.915205 │ 21.5 │└─────────────────────────┴────────────────────┘Aber aggregate kommt erst richtig zur Geltung, wenn es mit group_by kombiniert wird.
group_by
group_by erzeugt Gruppierungen von Zeilen, die für eine oder mehrere Spalten denselben Wert haben.
Allein bewirkt es nicht viel – kombiniert mit aggregate erhalten Sie ein Ergebnis.
penguins.group_by("species").aggregate()┏━━━━━━━━━━━┓┃ species ┃┡━━━━━━━━━━━┩│ string │├───────────┤│ Adelie ││ Gentoo ││ Chinstrap │└───────────┘Wir haben nach der Spalte species gruppiert und einen „leeren“ Aggregate-Befehl übergeben. Das Ergebnis ist eine Spalte mit den eindeutigen Werten in der Spalte species.
Fügen wir eine zweite Spalte zum group_by hinzu, erhalten wir jede eindeutige Kombination der Werte in diesen Spalten.
penguins.group_by(["species", "island"]).aggregate()┏━━━━━━━━━━━┳━━━━━━━━━━━┓┃ species ┃ island ┃┡━━━━━━━━━━━╇━━━━━━━━━━━┩│ string │ string │├───────────┼───────────┤│ Adelie │ Torgersen ││ Adelie │ Biscoe ││ Adelie │ Dream ││ Gentoo │ Biscoe ││ Chinstrap │ Dream │└───────────┴───────────┘Wenn wir nun eine Aggregatfunktion hinzufügen, wird es richtig interessant.
penguins.group_by(["species", "island"]).aggregate(penguins.bill_length_mm.mean())┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓┃ species ┃ island ┃ Mean(bill_length_mm) ┃┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩│ string │ string │ float64 │├───────────┼───────────┼──────────────────────┤│ Adelie │ Torgersen │ 38.950980 ││ Adelie │ Biscoe │ 38.975000 ││ Adelie │ Dream │ 38.501786 ││ Gentoo │ Biscoe │ 47.504878 ││ Chinstrap │ Dream │ 48.833824 │└───────────┴───────────┴──────────────────────┘Durch das Hinzufügen von mean zu aggregate haben wir eine knappe Möglichkeit, Aggregate über jede der unterschiedlichen Gruppen im group_by zu berechnen. Und wir können so viele Aggregate berechnen, wie wir brauchen.
penguins.group_by(["species", "island"]).aggregate( [penguins.bill_length_mm.mean(), penguins.flipper_length_mm.max()])┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓┃ species ┃ island ┃ Mean(bill_length_mm) ┃ Max(flipper_length_mm) ┃┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩│ string │ string │ float64 │ int64 │├───────────┼───────────┼──────────────────────┼────────────────────────┤│ Adelie │ Torgersen │ 38.950980 │ 210 ││ Adelie │ Biscoe │ 38.975000 │ 203 ││ Adelie │ Dream │ 38.501786 │ 208 ││ Gentoo │ Biscoe │ 47.504878 │ 231 ││ Chinstrap │ Dream │ 48.833824 │ 212 │└───────────┴───────────┴──────────────────────┴────────────────────────┘Wenn wir spezifischere Gruppen brauchen, können wir den group_by erweitern.
penguins.group_by(["species", "island", "sex"]).aggregate( [penguins.bill_length_mm.mean(), penguins.flipper_length_mm.max()])┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓┃ species ┃ island ┃ sex ┃ Mean(bill_length_mm) ┃ Max(flipper_length_mm) ┃┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩│ string │ string │ string │ float64 │ int64 │├─────────┼───────────┼────────┼──────────────────────┼────────────────────────┤│ Adelie │ Torgersen │ male │ 40.586957 │ 210 ││ Adelie │ Torgersen │ female │ 37.554167 │ 196 ││ Adelie │ Torgersen │ NULL │ 37.925000 │ 193 ││ Adelie │ Biscoe │ female │ 37.359091 │ 199 ││ Adelie │ Biscoe │ male │ 40.590909 │ 203 ││ Adelie │ Dream │ female │ 36.911111 │ 202 ││ Adelie │ Dream │ male │ 40.071429 │ 208 ││ Adelie │ Dream │ NULL │ 37.500000 │ 179 ││ Gentoo │ Biscoe │ female │ 45.563793 │ 222 ││ Gentoo │ Biscoe │ male │ 49.473770 │ 231 ││ … │ … │ … │ … │ … │└─────────┴───────────┴────────┴──────────────────────┴────────────────────────┘Alles miteinander verketten
Wir haben bereits einige Ibis-Aufrufe verkettet. Wir haben mutate verwendet, um eine neue Spalte zu erzeugen, und anschließend select, um nur eine Teilmenge der neuen Tabelle zu betrachten. Ebenso haben wir group_by mit aggregate verkettet.
Nichts hindert uns daran, all diese Konzepte zu kombinieren, um Fragen an die Daten zu stellen.
Zum Beispiel:
- Welcher war der größte weibliche Pinguin (nach Körpermasse) auf jeder Insel im Jahr 2008?
penguins.filter((penguins.sex == "female") & (penguins.year == 2008)).group_by( ["island"]).aggregate(penguins.body_mass_g.max())┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓┃ island ┃ Max(body_mass_g) ┃┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩│ string │ int64 │├───────────┼──────────────────┤│ Biscoe │ 5200 ││ Torgersen │ 3800 ││ Dream │ 3900 │└───────────┴──────────────────┘- Und der größte männliche Pinguin (nach Körpermasse) auf jeder Insel für jedes Erhebungsjahr?
penguins.filter(penguins.sex == "male").group_by(["island", "year"]).aggregate( penguins.body_mass_g.max().name("max_body_mass")).order_by(["year", "max_body_mass"])┏━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━┓┃ island ┃ year ┃ max_body_mass ┃┡━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━┩│ string │ int64 │ int64 │├───────────┼───────┼───────────────┤│ Dream │ 2007 │ 4650 ││ Torgersen │ 2007 │ 4675 ││ Biscoe │ 2007 │ 6300 ││ Torgersen │ 2008 │ 4700 ││ Dream │ 2008 │ 4800 ││ Biscoe │ 2008 │ 6000 ││ Torgersen │ 2009 │ 4300 ││ Dream │ 2009 │ 4475 ││ Biscoe │ 2009 │ 6000 │└───────────┴───────┴───────────────┘Mehr erfahren
Das war’s für diesen Schnelleinstieg. Wenn Sie mehr erfahren möchten, schauen Sie in die Ibis-Dokumentation.