Transcript: PP06 - Pandas

· Back to episode

Full episode transcript. Timestamps refer to the audio playback.

Ja, hallo liebe Hörerinnen und Hörer. Willkommen beim Python-Podcast in der mittlerweile sechsten Episode.

Heute geht es um Pandas. Ja, was machen wir eigentlich? Wir sind, wie fast immer, in Jochens Hintergarten.

Ich bin der Dominik, dabei ist wie immer der Jochen und unser Gast, der Simon.

Ja, hallo Simon. Vielleicht kannst du dich einfach mal kurz vorstellen, bevor wir über das Thema reden.

Klar. Ja, ich bin Simon. Ich bin von Haus aus Biologe, immer mit Interesse für Informatik und Spieleentwicklung gesegnet gewesen

und habe das dann irgendwie auch zu meinem Beruf gemacht. Also ich habe nach meinem Biostudium ein bisschen geforscht in der Bioinformatik.

Da ging es dann viel um Datenanalyse von DNA-Sequenzen und so Dingen.

Game of Life. Game of Life, ja, quasi. Nur in echt echt.

Ja, genau. Und zusammen mit dem Wissen, was ich daraus getragen habe und meinem Interesse an Informatik und Spieleentwicklung

mache ich heute als selbstständiger IT-Trainer Trainings für Game Engines und Trainings für Softwareentwicklung

und parallel noch ein paar Softwareprojekte.

Das Gaming haben wir uns ja schon ein bisschen unterhalten. Das machen wir auch nach der Folge ein bisschen intensiver.

Aber heute soll es ja um Pandas gehen. Genau, heute...

Deswegen, ja, super, dass du das auch ganz viel mit deinem zu tun hattest in deinem Fach.

In deiner Wissenschaft.

Bevor wir aber jetzt auf das Pandas-Thema eingehen, würde ich gerne noch so ein bisschen wieder Formalkrams abarbeiten.

Wenn ihr Fragen, Anmerkungen habt, Lobkommentare, Hass, dann schreibt uns doch an hallo-podcast.de.

Ihr findet natürlich die Links und alle zusätzlichen Informationen wie in den Shownotes.

Es gab noch ein bisschen User-Feedback und zwar sollten wir irgendwann mal eine Folge machen über Do's und Don'ts im Programmieren.

Also seid doch bitte so nett und schickt uns einfach per E-Mail eure Do's und Don'ts.

Das wäre super. Dann schneiden wir das ein bisschen zusammen und fragen euch in einer der nächsten Folgen bestimmt irgendwann mal danach.

Ja, doch, es gab noch ein anderes eben zu der Datenbank-Folge, dass das gar nicht so schlimm gewesen wäre mit der Länge.

Und das ist übrigens vielleicht ganz interessant.

Also wenn man sich anguckt, welche Folgen komplett runtergeladen wurden, dann hat die beste Quote tatsächlich die Datenbank-Folge zurzeit.

Was ich ein bisschen überraschend finde.

Ich hätte jetzt auch erwartet, dass es eher ein bisschen runtergeht.

Vielleicht müssen wir noch mehr so Buzzword-Bingo-Sachen machen.

Nein, wir machen das natürlich für alle unsere Hörer.

Vor allen Dingen für die, die sich dafür wirklich interessieren.

Und natürlich auch für die Leute, die was lernen wollen und für alle Leute, die einfach so reinhören oder denen langweilig ist.

Oder ihr wisst ja, morgens, abends, nachts, beim Aufstehen im Flugzeug könnt ihr immer hören.

Ja, bevor wir in das Thema gehen, ist weiterhin noch ein paar News aus der Szene.

Und zwar gab es so ein bisschen was Neues.

Daubig.

Python 3.8, zweite Alpha.

Ja.

Ja, da gab es so ein paar coole neue Sachen mit Shared Memory for Multiprocessing.

Jochen, was ist das denn?

Ja, das ist eine gute Frage.

Das ist eine gute Frage.

Wann habe ich denn das da reingeschrieben?

Oh, ja, das ist auch schon ein bisschen her.

Ah doch, ja, alles klar.

Das war ja immer so ein Problem.

Also man muss ja, wenn man jetzt über mehrere Prozessoren Berechnungen verteilen will in Python, das auf mehreren Prozessen machen.

Weil man ja irgendwie so ein Global Interpreter-Log hat, das halt verhindert, dass man das innerhalb von einem Prozess irgendwie mehrere Prozessoren benutzen kann.

Und ja, früher hat man halt dann immer so das, oder hat man jetzt immer noch in der stabilen Version, aber vielleicht hat man das mit 3.8 dann nicht mehr so das Problem, dass man, wenn man jetzt eine Funktion aufrufen möchte und, sagen wir mal so, man startet halt ein Pool von fünf Prozessen oder sowas oder zehn.

Und eben so viele üblicherweise, wie man Prozessoren hat und ruft jetzt eine Funktion auf jedem Prozessor sozusagen auf.

Also man hat jetzt eine Liste von Dingen, die man irgendwie abarbeiten möchte.

Man hat eine Funktion, die das dann halt tut.

Dann sagt man, okay, starte mit diesem.

Job irgendwie diese Funktion.

Und das geht dann halt irgendwie auf die, auf den, auf jeden Prozess, der halt in diesem Pool ist, wird dann halt das irgendwie gestartet.

Also wie man im Supermarkt ganz viele verschiedene Kassen aufmacht und macht ein paar Kassen auf einmal auf.

Ja, ja, ja.

Das Problem ist jetzt, dass man, wenn man da irgendwie auch Daten hat, auf denen da gearbeitet wird, dann muss man die Daten irgendwie zu diesen Prozessen bringen.

Das ist jetzt ein anderer Prozess.

Das heißt, man kann nicht einfach das in, also.

In Code ist es schon so, dass man einfach einen Funktionsaufruf macht.

Aber was dann im Hintergrund passieren muss, ist ja irgendwie, dass die Daten serialisiert werden.

Dann müssen sie irgendwie durch die Gegend geschoben werden.

Und dann auf der anderen Seite wird der deserialisiert werden.

In so kleine Häppchen.

Und dass alle, die ganze große Bestellung an verschiedenen Kassen abgearbeitet wird, um danach wieder in der richtigen Reihenfolge im Einkaufskorb zu landen.

So ungefähr?

Ja, man kann.

15 Fehler wieder.

Nein, ich glaube, ich weiß nicht, ob die Analogie da an der Stelle so gut passt.

Ich weiß auch nicht genau.

Ja, man muss es.

Ja, man kann sich vielleicht vorstellen, dass man, wenn man jetzt einen riesen Einkaufswagen voll Zeug hat und möchte jetzt das an fünf Kassen aber bezahlen, dann muss man halt auch fünf Einkaufswagen haben, indem man das jetzt aufteilt.

Und mit jedem Einkaufswagen einzeln zu einer Kasse.

Und.

Muss die irgendwer umpacken.

Dann muss man die umpacken.

Und das ist halt alles halbwegs aufwendig und kann halt auch zu Problemen führen, wenn die Daten sehr groß werden.

Zum Beispiel kann es sein, dass irgendwelche Dinge dazwischen halt aussteigen und das ist alles nicht so schön.

Und es ist halt unter Umständen auch etwas, was Dinge langsam macht.

Und jetzt geht es aber transparent mit Chat Memory sozusagen.

Das heißt, man hat halt die Daten.

Genau, das ist ja auch so ein Problem.

Wenn man jetzt Daten serialisiert und deserialisieren muss, dann kopiert man sie damit natürlich auch.

Das heißt, wenn man große Daten hat, die jetzt vielleicht insgesamt nur einmal in den Hauptspeicher passen, aber nicht zweimal.

Wenn man sie kopiert, dann hat man sie halt zweimal drin und dann hat man zu wenig Hauptspeicher.

Ist ja auch blöd.

Und was halt schon immer viel, viel cooler war, ist, wenn man halt einfach Shared Memory reservieren kann

und sagt dann den einzelnen Prozessen, gibt denen nur einen Pointer auf diese Shared Memory und sagt so,

da sind deine Datenstrukturen drin.

Also das heißt, jemand nimmt sich einfach so einen Unterkorb aus dem Einkaufswagen raus, der schon fertig ist

und der Einkaufskorb, der fährt dann automatisch auf das richtige Förderband.

Ja, nee, aber das ist, ja, mal überlegen, ob man diese Analogie da noch irgendwie...

Ja, Shared Memory, ein eigener Teil der Einkaufswagen.

Das wäre der eine Einkaufswagen, der an allen fünf Kassen steht.

Jede Kasse greift nur auf einen Teil von dem Korb selber zu.

Stimmt, wir haben eine Ruhre von Kassen.

Die Kasse ist oben, unten, rechts und links.

Man kann einfach eingreifen.

Das ist schön, ja.

Genau, so könnte man sich das vorstellen, ja.

Und das heißt, man hat halt, wenn man jetzt Daten hat, die so gerade in den Hauptspeicher vielleicht passen,

dann kann man die trotzdem auf mehreren Prozessen verarbeiten.

Und das macht natürlich Multiprocessing auf Python deutlich attraktiver.

Und das ist irgendwie eine ziemlich coole Geschichte, wenn die jetzt in drei abkommen,

und...

Dann wird Python ja schneller.

Ja, also, oder es wird einfacher damit.

Also, man kann ja auch, das konnte man auch sowieso schon immer machen.

Man kann ja auch einfach Shared Memory reservieren, da Dinge reinpacken.

Da gibt es übrigens auch ein schönes Modul in der Standardbibliothek, das heißt Struct.

Struct.

Genau, damit kann man zum Beispiel Daten halt so binär irgendwie in den Hauptspeicher schreiben.

Und das zum Beispiel so tun,

dass das halt C-Structs sind.

Ah.

Und dann kann man das halt, also das ist halt so etwas, so haben wir das früher halt gemacht,

wenn wir Daten nicht so groß waren, dass man da nicht einfach irgendwas mit tun konnte.

Das heißt, man hat halt irgendwie einen Shared Memory Bereich,

und den schreibt man halt irgendwie per Struct irgendwie, sozusagen C-Struct Daten irgendwie rein,

und hat dann Python-Prozesse, die wiederum einen Pointer auf diese Shared Memory kriegen,

und die dann halt wieder ein C-Modul haben, das dann halt irgendwas mit den Daten macht und so.

Und dann geht das auch schon, aber das ist halt viel Handarbeit.

Und jetzt kriegt man das quasi so geschenkt, und das passiert dann dann automatisch, und das ist halt schon sehr nett.

Cool.

Ja.

Ich hörte ja auch gerade diese Hintergrundmusik, das ist so ein bisschen wie in Battlestar Galactica, ne, diese

Ah, super.

Keine Opelide.

Ja, also die nächsten News aus der Szene.

Doppelte Keys, gab ein Post von Guido irgendwo, der hat irgendwas geshared.

Es gibt ein neues Python-Enhancement-Proposal, das ist eine ganz interessante,

äh, äh, äh, Geschichte vorschlägt, und zwar geht's darum, dass man halt, äh, für Dicts vielleicht auch die, äh,

äh, also Plus und Minus als Operatoren, äh, haben möchte, sodass man halt sagen kann, irgendwie Dict A plus Dict B,

und dann, äh, werden sozusagen die Keys hinzugefügt, oder halt, äh, wird das eine, äh, werden halt die Keys, die in dem einen Ding drin sind, entfernt,

wenn man das halt abzieht, und das ist natürlich auch eine ganz, also ist eigentlich relativ naheliegend,

es wundert mich, dass da bisher noch niemand draufgekommen ist, dass man das irgendwie mal machen könnte, aber

das ist auf jeden Fall eine ganz interessante Idee.

Und, ähm, Kido hat da einen Artikel zugeschrieben.

Ja, genau, irgendwie, der hat zweimal den Key irgendwie draus zugewiesen, und dann quasi einen Dictionary mit zwei identischen Keys erzeugt,

wo dann nur einer von überlebt hat.

Äh, ja.

Irgendwie so, also, wenn man halt, ich glaub, welcher Post war das, ähm, wo er A einmal die Nullen, A einmal die Eins zugewiesen hat,

und dann war Eins übrig, weil das die letzte Zuweisung war.

Weil ich das richtig verstanden habe.

Genau, das war das Verhalten.

Das war das Verhalten, was mich irgendwie gewundert hat, aber das ist, das ist, äh, das ist generell, äh, so, das war schon immer so, offenbar,

wenn man halt, ähm, also insofern ist es halt kompatibel mit diesem Verhalten, ähm, äh, dass wenn man jetzt irgendwie einen Key mehrfach entdeckt hat,

dass dann halt immer das letzte genommen wird.

Und, ähm, das war mir auch gar nicht klar, dass das so ist, aber, äh...

Also kein, ähm, Duplicate Value oder Key Error oder sowas.

Nee, es wird einfach das letzte genommen.

Und da hat er halt dazu, oder von mir nehmen wir es so geschrieben, dass, äh, ja, er hat damals lange drüber nachgedacht, äh, dass das,

weil irgendjemand die Frage gestellt hat, ob das Absicht wäre oder nicht.

Dann hat er so, ich hab damals noch lange drüber nachgedacht und das ist Absicht.

Ja.

Und damit...

Ich erinnere mich an irgendein Programm, wo ich das dachte, wo ich irgendwie komischen Fehler hatte und das, glaube ich, genau daran gelegen hat.

Weil, ja, irgendwelche Duplikate dann zwar drin waren, ich das aber nicht gemerkt habe, erst irgendwann später, als mir um die Ohren flog.

Ja, äh, aber, ähm, Guido hatte auch noch, ähm, ähm, einen Blogpost, äh, dazu geschrieben, wo er, äh, überlegt hat, ob das mit diesen Operatoren...

halt eine gute Idee ist oder nicht.

Wie heißt das wieder? Code Active State?

Ähm.

Python Ideas.

Ja, nee, in seinem Blog war das Ding drin.

Ja.

Und, äh, ja, da macht er tatsächlich den Punkt, dass das halt schon eine gute Idee ist und, äh, ähm, hat er so das als Beispiel quasi, wenn man jetzt mathematische, also arithmetische Geschichten halt nicht als, äh, Operatoren hätte, sondern wenn man da Funktionen, das mit Funktionen ausschreiben würde,

dann würde es halt sehr viel unklarer, was eigentlich gemeint ist, jedenfalls wenn das irgendwie komplizierter wird, weil man dann halt immer erst die, äh, Operatoren, äh, immer erst die Funktion mit den Klammern auflösen muss, äh, bevor man sieht, was passiert und während man quasi, wenn man das als Operatoren hinschreibt, hat man so eine Art visuelles Pattern-Matching direkt schon, das einem sagt, was da, was da passiert und daher sind für so arithmetische Geschichten, um zu sehen, was da passiert ist, ist es halt, äh, viel sinnvoller, das mit Operatoren-Schreibweise hinzuschreiben als mit Funktionen, was man ja auch tun könnte.

Also, äh, für Dicts ist halt die Frage, ob das Sinn macht, aber, also immer dann, wenn, wenn einem das dabei beim Verständnis hilft, äh, wenn man das anders hinschreiben kann, dann kann es natürlich schon gut sein, dass das irgendwie sinnvoll ist und, ähm, ja, das ist auf jeden Fall, glaube ich, hier ein, äh, starkes Argument dafür und, äh, mal sehen. Ich, ich bin mir nicht sicher, ob wir das in Python 3.8 dann schon direkt sehen werden, aber es wäre auf jeden Fall, es ist irgendwie eine interessante Idee und, ähm, ja, ich bin mal gespannt, wie das sich so weiterentwickelt.

Neue News hatten wir, glaube ich, und das war der Django-Chat-Podcast.

Äh, releases machen und so. Ja, und, äh, das war schon, die ersten beiden Episoden sind erschienen, die erste war irgendwie relativ interessant. Ich fand, das war auch so, dass da irgendwie eine ganze Menge Überschneidung war zu dem, was wir in unserer Django-Folge irgendwie erzählt haben, so von dem, äh, so Rundtenor, äh.

Ja, ja, ja, ja, ja, ja, ja, ja, ja, ja, ja, ja, ja.

Ja, wir können eigentlich mal, Pandas, genau.

Ja, Pandas, was ist das denn überhaupt? Also, ähm, beim Eishockey, ich bin ja Eishockey-Fan, da haben die Schiedsrichter jetzt so ein Pandasymbol, äh, gehabt auf den Trikots, weil die eine Kooperation mit dem, äh, WWF haben und dann waren sie am Ende ein bisschen enttäuscht, dass der WWF da so eine Spendenaffäre hatte, aber, ähm, ja, das ist manchmal so, aber Pandas und Spendenaffäre hat wahrscheinlich jetzt bei uns jetzt so viel nicht miteinander zu tun.

Ne, aber das, äh, der Name bietet natürlich schon so ein bisschen, äh, äh, Verwechslungspotenzial. Wir hatten da auch genau darüber gesprochen, haben, ob wir nicht irgendwie mal zusammen irgendwie eine Podcast-Episode machen wollen, hatte.

Da sieht man auch irgendwie zuerst was anderes verstanden, glaube ich.

Ja, genau, also es gibt nicht nur, ähm, Python-Pandas, das Data-Frame-Framework, sondern auch, ähm, Python-Pandas-3D, die Game-Engine.

Ah!

Und, äh, weil ich ja irgendwie beide Themen abdecke, war das, was ich gerade zuletzt gemacht hatte, das erste, was im Kopf wieder aufgetaucht ist, und das war die Game-Engine, und dann haben wir, weiß nicht, fünf Minuten aneinander vorbeigeredet.

Wir können doch jetzt gerne nochmal fünf Minuten über die Game-Engine-Pandas-3D reden, wenn du magst.

Ist die in Python?

Also, äh, ich...

Ich glaube, Game-Entwicklung in Python ist vielleicht eine Folge, zu der ich nochmal wiederkommen sollte.

Oh, ja!

Ja, ja, einfach, weil das sehr, sehr umfangreich ist.

Und das geht?

Also, da gibt's im Wesentlichen irgendwie, äh, Pygame und Pandas als die beiden großen etablierten, dann gibt's noch so ein paar kleinere.

Und damit kann man wirklich auch Spiele machen, die auch gehen und die auch aussehen, oder sowas? Oder braucht man dafür noch Qt, oder sowas?

Ich sag's mal vorsichtig, ja, damit kann man Spiele machen, ähm, mit Pygame 2D-Spiele, mit Pandas 3D sogar 3D-Spiele, was man damit sehr gut machen kann, ist...

...ist zu lernen, wie so eine Game-Engine wirklich funktioniert.

Mhm.

Ich glaube aber nicht, dass man Triple-A-Titel darin machen möchte, weil es dann doch irgendwann umständlicher ist, als eine von den großen 3D-Game-Engines, die so am Markt sind, äh, die vielleicht auch ein bisschen mehr klickbar sind, zu verwenden.

Ich muss überlegen, welche das waren. Das war, ähm, Unreal...

Unreal, Unity 3D und...

...Unity 3D und CryEngine.

Ja, okay, dann CryEngine ist ja nicht frei. It 7 oder so 8.

Weiß ich gerade gar nicht.

Ich glaub, wir sind gerade völlig off-topic, ähm, wir wollten über Pandas sprechen.

Genau, also Pandas 3D ist die Game-Engine, darüber sprechen wir heute dann nicht, und, ähm, Pandas, äh, ist im Wesentlichen eins der Python-Tools, an denen man nicht vorbeikommt, wenn man Datenanalyse betreibt.

Okay, wir sind wieder mal bei der Datenanalyse.

Genau.

Datenbanken hatten wir übrigens in der letzten Folge, für alle, die sich das noch nicht angehört haben, eine ziemliche Mammut-Folge mit, wie lange, drei Stunden haben wir gebraucht?

Ja, ein bisschen mehr, aber genau um den Dreh.

Wenn ihr mal wieder die Wohnung richtig putzen wollt, dann...

Ja, an der Stelle würde ich ganz gerne noch kurz, äh, meinen Hintergrund in der Datenanalyse erwähnen, damit man so ein bisschen einordnen kann, aus welcher Richtung meine Kommentare kommen.

Ähm, als Biologe war damals, äh, Perl das große, die große Programmiersprache, um alles zu lösen, und, äh, erst zum Ende meiner Forschungszeit hat sich dann irgendwann Python durchgesetzt.

Das heißt, ich hab noch sehr viel in Perl gemacht, und was man in Perl gar nicht gut konnte, zumindest ich konnte das nicht, ist...

...das Daten, äh, nachher analysieren und visualisieren, aber die Aufbereitung war da sehr gut.

Das heißt, für die Analyse und, und die Visualisierung sind wir dann immer zu R rüber gewechselt.

R ist, äh, auch eine Programmiersprache, ähm, ist eine eher mathematische Annotation, ähm, zur Datenanalyse.

Und wenn ich so die Branche, sag ich mal, richtig überblicke, dann wird am meisten, ähm, R und Python benutzt, und vielleicht dann noch Mathe.

Ähm, als, als dritte Alternative, wenn Leute heute Daten, Datenanalyse machen.

Was meinst du denn mit Datenbereinigung?

Ähm, in der Biologie ist das so, dass die Daten immer unheimlich, äh, fuzzy sind, also man, man hat nie ganz konkrete Messwerte, sondern man hat immer super viele Abweichungen, mal, mal Fehlmessungen, mal Werte, die man gar nicht erheben konnte, und, äh...

Du musst dich dann entscheiden, ob du eine Rundung anwendest oder nicht.

Ähm, führt dann erstmal dazu, dass die Daten nicht mehr so strukturiert sind, wie man das eigentlich dachte in der Tabelle.

Ähm, das kommt auf, auf die Messinstrumente im Wesentlichen an.

Ähm, das heißt, die erste Aufbereitung ist erstmal, die Daten in ein maschinenlesbares Format zu bringen.

Und da ist es, äh, von unfassbarem Wert, wenn man programmieren kann.

Ähm...

Dann muss man jede einzelne Zeile oder Zelle durchgehen und die manuell korrigieren.

Mhm.

Genau, also ich, äh, ich hab auch, äh, tatsächlich schon...

Ich hab auch Kollegen damals gesehen, die, äh, von Programmierung gar keine Ahnung hatten, die dann angefangen haben, in Excel sich das händisch zusammenzustellen.

Und, äh, dann haben wir uns kurz zusammengesetzt, ein Makro geschrieben und dann ging das irgendwie doch schneller.

Mhm.

Ähm, und fehlerfreier an der Stelle auch.

So, und, ähm, dieser erste Schritt, überhaupt die Daten erstmal maschinenlesbar zu kriegen, der, der ist im Wesentlichen unabhängig von der Analyse, aber notwendig.

Nochmal für unsere ganz Anfänger, nochmal bitte, was denn überhaupt maschinenlesbar bedeutet.

Mhm.

Ähm, ich hab da mal irgendwann ein Beispiel vorbereitet, äh, für, ähm, für Mediziner, die von Excel zu R wechseln wollten.

Und, äh, das Beispiel war eine Tabelle, eine Excel-Tabelle aus meinem Laboralltag, wo dann in einem Tabellenblatt an mehreren verschiedenen Stellen so kleine Subtabellen zu sehen waren, wo die Messdaten drin standen.

Da gab's dann quasi einmal Experiment A, war so ein, äh, fünfmal...

Fünfmal vier Raster.

Experiment B war so ein fünfmal vier Raster, was irgendwie rechts daneben stand.

Und dann gab's noch ein Experiment C, was dann mittig darunter stand, auch fünfmal vier Raster.

Das ist für einen Menschen super lesbar, weil man kann sofort die Blöcke identifizieren und sich die Messdaten angucken.

Ähm, für eine Maschine ist das aber nicht mehr strukturiert lesbar.

Weil die Koordinaten nicht klar sind.

Weil die Koordinaten nicht klar sind, genau.

Und, ähm, was häufig passiert ist, wenn Menschen...

...Tabellen ausfüllen, um die visuell ansprechend zu machen, verletzen die ein wichtiges Kriterium, dass in jeder Zeile oder Spalte, je nachdem, woran man sich orientieren möchte, nur ein Datensatz wirklich drinsteht.

Oder stehen sollte, weil da unterschiedliche Informationen sind, die nicht voneinander getrennt sind.

Dann stehen zum Beispiel sowas wie eine Spalte, wo zwei verschiedene Datensachen auf einmal drinstehen.

Genau.

Einmal Temperatur in Celsius, einmal in Fahrenheit oder sowas.

Oder ist das legitim?

Ja, das könnte ja noch...

...zusammenpassen, aber, ähm, einmal die Temperaturen, ähm, in Celsius und Fahrenheit für das eine Experiment und dann, ähm, das Ganze nochmal für das andere Experiment irgendwo weiter hinten in der gleichen Zeile, aber nicht klar strukturiert abgrenzbar.

Mhm.

Ja, also das ist halt quasi bei Datenmarken, das ist halt die erste Normalform, dass halt man in der Spalte immer nur einen Wert stehen hat und nicht, äh, irgendwie mehrere zum Beispiel, was halt dann manche Leute...

Aber, äh, Fahrenheit und Celsius wäre okay, wenn man...

...die...

...wenn die Spalte...

...wenn das unterschiedliche Spalten wäre...

...wenn die Information enthalten wäre in der Zelle, ob es Celsius-Erfahrenheit wäre.

Äh...

Weil das wäre sonst problematisch, wenn man...

Ja, also wir kommen da sicherlich gleich nochmal zu, so gut das geht, in einem Podcast Tabellen zu beschreiben.

Ja, wir passieren, weil wir das so kritisieren.

Ähm, äh, grundsätzlich, wenn man so eine Tabelle hat, wo man Zeilenbeschriftungen hat und Spaltenbeschriftungen hat und die ganze Tabelle ist rechteckig, dann kriegt man die auch sinnvoll maschinenlesbar ausgewertet.

Mhm.

Also Probleme höre ich, fangen dann an, wenn man keine zweidimensionalen Tabellen mehr hat, keine, die man mal eben so auf seinen Whiteboard malen kann.

Welche, die man bauen müsste oder, äh, wo man irgendwelche Dimensionen verbraucht, die wir uns jetzt nicht so räumlich vorstellen können.

Genau.

Oder wo, wo tatsächlich Lücken drin sind und die Muster für Menschen zwar noch erkennbar bleiben, aber für eine Maschine die Koordinaten dann zum Beispiel nicht mehr zusammenpassen.

Okay.

Ja.

Ja.

Ja, okay, das haben wir so ungefähr verstanden, was so maschinenlesbar dann bedeutet für die einzelnen Daten.

Und wo kommt jetzt Pandas dann ins Spiel, wenn du jetzt diese...

Für die Darstellung von Vektoren NumPy und für einfache statistische Analysen SciPy und für Visualisierung Matplotlib.

Und dann war der Kreis eins weiter draußen so ein bisschen das, was darauf aufbaut.

Das war dann Pandas, das war, ähm, Studs Models war das, glaube ich.

Mhm, das so für Zeitreihen und so.

Genau, und, ähm, Seaborn.

Und das waren dann die Pendants, also, äh, Seaborn auch wieder zur Visualisierung und Studs Models.

Äh, im Prinzip zur statistischen Auswertung und Pandas eben zum, äh, zum Data Handling, ähm, aber jenseits von einfachen Vektoren.

Mhm, okay.

So, und da kommen wir im Prinzip auch schon wieder in den Bereich, wo man immer den Vergleich zwischen Excel normalerweise führt, ähm, wenn man das mit, mit Leuten bespricht, mit denen man zusammenarbeitet, ähm, weil Excel kennt irgendwie jeder.

Ja.

Also, Tabellenkalkulation ist...

Also, Tabellenkalkulation ist jedem sofort ein Begriff und alle wissen auch sofort, okay, es gibt Zeilen und Spalten.

Das ist so, dass das, äh, wäre ein Minimum, was man wissen muss, um mit Pandas was anfangen zu können.

Das hat man wahrscheinlich in der Schule schon mal aufgemacht oder so, oder aufmachen müssen.

In der Regel schon, ja.

Ja, genau, ähm, das heißt, bei Pandas sind wir jetzt in dem Bereich von, ähm, Data Handling.

Also, wie kann ich meine Daten laden, verarbeiten, zur Verfügung stellen für Analysen?

Wie macht Pandas das?

Gibt's da Speziellen?

Naja, also, äh, ich, ich würd sagen, also, das ist auch das, äh, ähm, denke ich, Hauptfeature von, von Pandas ist, dass man damit die Daten überhaupt erstmal irgendwie, äh, in, in so ein, ähm, ja, äh, reinbekommt irgendwie.

Also, äh, Westman Kinney hat das auch mal gesagt, dass die, äh, populärste und, und wichtigste Methode, die, die Pandas halt hat, ist halt Read CSV.

Mhm.

Äh, die sehr, sehr flexibel ist und man kann irgendwie so ungefähr jedes CSV, was irgendwo...

Genau, ist ein sehr hässliches Format und Leute machen unglaubliche, äh, und, und unheilige Dinge damit, aber, äh, man, man kann irgendwie mit dieser, mit dieser Funktion kann man das fast alles parsen, ne?

Die hat sehr viele, ähm, Argumente und sehr viele Dinge, an denen man da irgendwie was drehen kann und man kriegt fast alles damit geparsed und, ähm, das heißt, ja, egal wie komisch die Daten aussehen, die man so hat, man kriegt sie irgendwie mit Read CSV oft irgendwie in Pandas rein und hat sie dann halt in einem sauberen Format und kann das dann halt wieder in anderen Formaten rausschreiben, aber gut, äh, Pandas kann das nicht.

Kann nicht nur CSV, äh, lesen, sondern halt auch diverse andere Formate, äh, ja, von JSON über, keine Ahnung, XML oder was auch immer. Teilweise werden dann halt, äh, andere Bibliotheken unten drunter verwendet, um das halt einzulesen, aber, äh, das ist halt, äh, also Pandas ist eigentlich immer so der, der erste Schritt, äh, wenn man irgendwo Daten herbekommt, um die halt in, in ein Format zu bringen, mit dem man irgendwas machen kann, um es halt irgendwie einzulesen, äh, in Programmen, da nimmt man halt eigentlich immer Pandas, weil das halt...

Eine Zeitreihenanalyse oder sowas?

Eine Zeitreihenanalyse oder sowas?

Eine Zeitreihenanalyse oder sowas?

Ähm, und die Projekte, die am meisten Geld bekommen, sind sowas wie TensorFlow oder so, ne, weil man drüber schreiten kann, inwiefern das halt noch Open Source ist, aber, ähm, und, äh, auch die ganzen Cloud-Dienste oder so, die haben alle irgendwie, äh, Methoden, Daten da reinzubekommen, Daten wieder rauszubekommen.

zu bekommen und auch in denen steckt relativ viel Geld drin, aber diese Sachen sind alle

ziemlich schlecht irgendwie und Pandas füllte halt so eine Lücke.

Ist halt eigentlich ultra wichtig, weil irgendwie diese ganzen Datenimport-Export-Geschichten

sind halt etwas, was man immer braucht und irgendwie es gibt außer Pandas keine Projekte,

die das irgendwie ordentlich gemacht haben und du kannst natürlich irgendwie deine tolle

Deep Learning TensorFlow-Geschichte nehmen, aber wenn du die Daten halt nicht hast, um

damit irgendwas machen zu können, dann hilft dir das alles nichts und ja, das, eben, weiß

man, Kenny erzählt davon halt auch immer, dass ihm das total wundert und dass er das

total seltsam findet, dass halt so ein wichtiger Teil der Infrastruktur so wenig Liebe erfährt

quasi und dass seine Hauptmotivation war zu sagen, okay, da muss man mal was tun, da muss

man, das muss doch irgendwie, dieses Problem muss man doch lösen, das ist halt irgendwie

ein Problem, was alle haben und was irgendwie sehr ärgerlich ist und ja.

Und das ist halt, das macht Pandas auch sehr gut irgendwie und das ist immer so ein erster

Schritt, wenn man irgendwie Daten, auch wenn man jetzt hinterher Machine Learning machen

möchte oder so, hat man trotzdem immer Pandas mit dabei, weil man die Daten ja erstmal in

irgendwie ein Format bringen muss vorher und vielleicht aufräumen muss, sauber machen

muss, da gibt es auch immer so einen schönen Spruch, irgendwie Data Science ist halt so

oder auch Machine Learning ist halt, 80% ist halt Data Cleaning, ja, und 20% ist darüber

beschweren, dass irgendwie 80% Data Cleaning, ja, ich meine, die andere Sache ist, als Mensch

möchte man ja auch sich die Daten vielleicht zwischendurch mal angucken können und dafür

braucht man irgendwie eine Datenstruktur, in der man sehr schnell zu Rahmendaten kommt,

vielleicht braucht man mal einen Mittelwert oder will sich mal die Verteilung angucken,

gruppiert bei irgendwelchen...

Kategorien oder sowas.

Also sicherlich ist diese Import-Geschichte von Pandas eine der mächtigsten, die ich bisher

gesehen habe, was auch so fehlende Datenpunkte angeht und wenn die Struktur mal nicht ganz

stimmt und man kann einzelne Zeilen überspringen, wenn da mal was kaputt geht oder sowas.

Da habe ich jetzt übrigens direkt eine doofe Frage zu, weil es gibt ja irgendwie bei Pandas

so ein paar Werte, die, wenn die halt nicht da sind, die man irgendwie füllen kann, da

gibt es ja irgendwie jetzt aber so drei Typen.

So Null und None und None.

Warum, wieso braucht man da drei?

In Pandas, also ich wüsste jetzt eigentlich nur, dass es da Not a Number gibt und das

ist historisch sozusagen, hier ist kein Wert von NumPy, das ist auch irgendwie sozusagen

ganz unten drunter ist das tatsächlich ein...

In Float kann man das halt ausdrücken und ja, das hat halt auch so das leichte Problem,

dass man im Grunde immer dann, wenn man solche Werte hat, dann halt auch der Datentyp irgendwie

Float sein muss, was so ein bisschen doof ist.

Das war bis vor ganz kurzem war das noch so, dass man halt, wenn man jetzt eine Integer-Spalte

hatte und da fehlt halt jetzt ein Wert und man hat halt gesagt, okay, da kommt irgendwie

was dazu, was halt irgendwie fehlt oder so und man macht dann einen Re-Index und guckt

und dann hat es...

Dann hat sich plötzlich der Typ der Spalte in Float geändert, weil es halt keine fehlenden

Werte in Integer-Typ, die Type-Spalten gibt und das ist ein ziemlich blödes Problem.

Aber jetzt gibt es halt irgendwie seit einiger Zeit diese Array-Extensions, Array-Extensions-API

für Pandas und die halt mit Cyber-Pandas dazugekommen ist, ich weiß gar nicht, welche

Version das genau war.

Und jetzt hat auch die, Ende Januar ist die letzte größere Release von Pandas erschienen,

ich glaube 0.224 oder so.

0.24, ja.

0.24 und da ist jetzt halt auch eine native, natives Integer-Spaltenformat drin, das halt

auch nannen kann und das ist natürlich total cool irgendwie und man kann jetzt für, also

dadurch, dass man jetzt quasi nicht mehr Namen-Pile unten drunter liegen hat, kann man da auch

diverse andere...

coole Datentypen irgendwie verwenden, die vorher so nicht möglich waren, weil man ja

immer auf Namen-Pile angewiesen war.

Also Namen-Pile ist auch ganz cool, aber Namen-Pile hat halt das Problem, dass das grundlegende

Design dafür ist halt, ja jetzt doch schon wahrscheinlich fast 20 Jahre alt und passt

halt auch nicht mehr so richtig auf die Anforderungen von heute und dummerweise hat Pandas aber

viele der Implementationsdetails in Namen-Pile halt rausgelegt und das kann man jetzt auch

nicht mehr so einfach ändern, weil das halt...

also wenn man das wieder ändern würde, würde das Code brechen und dann also wäre keine

abwärtskompatiblen Änderungen mehr und das ist natürlich alles so ein bisschen blöde

Situation, aber irgendwie mit dieser Array-Extension-API hat man auf jeden Fall eine Möglichkeit, wenn

man den Typ ändert, dann ist das alles eigentlich in Ordnung und dann kann man da auch schöne

neue Sachen machen, ohne dass man auf Namen-Pile irgendwie angewiesen ist.

Zum Beispiel was halt...

also das sind so Beschränkungen, die sind echt blöd.

Also wenn man auf Namen-Pile unten drunter basierendes Pandas hat, dann hat man halt so

was nicht wie zum Beispiel Decimal-Types, also einfach man hat keinen fehlenden Missing-Value-Support

für sowas wie Integer, was auch schon schlimm ist, aber man hat halt auch... wenn man jetzt

mit Geld zu tun hat, was man ja vielleicht auch irgendwie... dann hat man halt bloß

Float, das will man auch nicht, also man würde das dann irgendwie wahrscheinlich eher Geld

in Integer, also in Cent-Integer oder sowas verwenden.

Viele werden wahrscheinlich irgendwie Float nehmen und dann denken, ach das wird schon

irgendwie hinhauen.

Und dann böse Überraschungen überleben, weil das für... das funktioniert halt überhaupt

gar nicht.

Und man kriegt diverse richtig böse Probleme, wenn man das macht.

Und in Datenbanken ist das Problem eigentlich auch schon lange gelöst, da gibt es den Decimal-Type,

genau für sowas, der dann halt auch ordentlich rundet und so.

Und in Python gibt es auch einen nativen Decimal-Type, der ist blöderweise nur total super langsam,

also den kann man eigentlich auch nicht nehmen.

Also sozusagen als Array-Extension-Type halt auch Decimal, sodass man das halt auch in Pandas

Data Frames halt Geld quasi mit Kommastellen verwenden kann, ohne dass man da mit schlimmen

Konsequenzen rechnen muss.

Und es gibt sowas wie Date-Time mit Time-Zonen dran und so, das ging vorher auch nicht.

Und das ist...

Achso, sowas wie Grad mit Celsius-Erfahrenheit vielleicht.

Das ist nochmal ein anderes... genau, das möchte man auch gerne haben.

Ich weiß nicht, ich glaube, das ist nicht direkt in Pandas drin.

Es gibt Bibliotheken dafür, dass man halt an Spalten auch noch irgendwie so eine Maßeinheit dran klebt.

Die Annotationen und auch Skalierungsfaktoren kommen auch mit unter aus dem zugrunde liegenden Datenformat,

aus dem man nachher importiert.

Also es gibt irgendwie wissenschaftliche Datenformate, die speichern sowas alles mit.

HDF 5 oder NET-CDF oder wie das inzwischen heißt.

Wie sieht das dann aus? Hat das eine Spalte, ein Doppel drin oder?

Da gibt es im Prinzip irgendwie so eine Tabelle von Meta-Daten.

Meta-Daten, wo drin steht, welche Spalten, welche Maßeinheit, welche Skalierungsfaktoren haben,

wann die zuletzt bearbeitet wurden.

Und darunter stehen dann serialisiert die Daten drin.

Und dadurch hat man einen sehr, sehr schnellen sequentiellen Zugriff auf seine Daten,

hat aber trotzdem die Möglichkeit, diese Skalierungen und Einheiten mitzuführen.

Und in Pandas weiß ich nicht, ob das inzwischen mit importiert wird.

Aber diese Erweiterung...

Ja, ich habe jetzt normalerweise auch nicht mehr parat, wie die Bibliothek...

Es gibt eine Bibliothek für so Maßeinheiten und sowas.

Ich weiß aber nicht genau, wie das gemacht ist.

Das müsste ich nochmal nachgucken.

Vielleicht können wir das einfach dann beim nächsten Mal nachreichen oder so.

Auf jeden Fall, da gibt es etwas und das kriegt man schon irgendwie alles auch mit dazu geschrieben.

Ja, also genau, das ist eigentlich so wie früher.

Der Default ist immer noch bei Pandas.

Wie Sachen gespeichert werden, das nennt sich irgendwie Block Manager oder Block Storage.

Und das sind immer 2D NumPy Arrays.

Und die sind halt immer sozusagen...

Also man würde eigentlich denken, dass ein Data Frame, dass jede Spalte irgendwie ein 1D,

also ein eindimensionales NumPy Array ist.

Aber das ist halt nicht so, sondern ein Data Frame besteht aus Blocks von 2D NumPy Arrays,

jeweils zu einem, also unterteilt nach Datentyp.

Also wenn ich jetzt sagen habe, ein Data Frame, der 3 Spalten hat, 2 davon Float, 1 Integer,

dann besteht das Ding aus 2 NumPy Arrays, 1 mit Integer und 1 mit Float, das halt 2 Spalten hat.

Da muss man jetzt natürlich aufpassen, von welcher Seite man drauf guckt.

Weil aus Pandas Sicht ist das erstmal eine Liste von Pandas Series.

Da haben wir auch noch nicht drüber gesprochen, was das ist.

Also die Abbildung als NumPy Arrays ist natürlich dann irgendwie die technische zugrunde liegende Abbildung.

Ja, ja, genau.

Eigentlich sollte das egal sein.

Sollte man sich eigentlich keine Gedanken darüber machen, sondern eigentlich ist eine Series halt quasi,

kann man es verstehen als Spalte oder eben Vektor, eindimensionale Datenstruktur mit vielleicht noch einem Index dran.

Aber so wird es halt nicht gespeichert.

Und das Blöde ist, dass diese Abstraktion halt auch so liegt.

Weil wenn man jetzt...

zum Beispiel eine Spalte hinzufügt zu einem DataFrame,

dann hat man das Problem, dass dadurch, dass jetzt, wenn man schon ein paar Float-Spalten da drin hat

und man fügt jetzt eine dazu, dann geht das ja nicht mehr wirklich.

Sondern dann müssen die kompletten Daten alle kopiert werden dafür.

Und wenn man jetzt in der Schleife irgendwie Spalten hinzufügt oder so,

dann kann es sein, dass einem der Speicher platzt und man weiß überhaupt nicht warum.

Das heißt, man muss im Grunde wissen, dass Pandas das so macht.

Dann gibt es ja immer so Tipps, wie gesagt, wenn man da irgendwie viele Spalten hinzufügt,

dann immer erst mal die einzelnen Spalten sammeln und dann hinterher alle zusammenfügen oder so.

Nicht irgendwie auf einem großen DataFrame eine Spalte hinzufügen, dann noch eine hinzufügen, das ist schlecht.

Und das sollte eigentlich, das sind so Schwächen bei Pandas, das sollte einen gar nicht interessieren, wenn man das benutzt.

Dummerweise muss man solche Sachen aber dann vielleicht doch wissen, weil man halt dieses Problem da an der Stelle noch hat.

Aber das kann sein, dass das jetzt alles demnächst besser wird.

Und mit dieser Version, mit der letzten Version ist es halt schon ein Stück besser geworden.

Und da sind halt die einzelnen Spalten, haben ihren eigenen Typ und ihre eigene Speichergeschichte und dann ist alles nicht mehr so ein Problem.

Aber ja, das ist vielleicht auch noch interessant.

Also Pandas ist gedacht für so Daten, also Small Data kann man quasi sagen, also Daten im Bereich von so ein paar Gigabyte, also einstellig Gigabyte.

Weil halt da fast alle Operationen dazu führen, dass das irgendwie kopiert wird, kann es sehr schnell sein, dass man halt irgendwie auch,

fünf oder vielleicht sogar bis zu zehnfacher der Datenmenge, die tatsächlich auf der Platte landet oder so, man dann als Hauptspeicher braucht.

Weil man kopiert ein paar, man fügt ein paar Spalten hinzu, transformiert ein bisschen was und dann schon hat man irgendwie einen fünffachen Hauptspeicherverbrauch.

Und daher ist es halt nicht so richtig effizient.

Kann auch sein, dass es jetzt dann halt besser wird.

Aber also für größere Sachen kann man Pandas nicht so super benutzen.

Aber für diese kleinen Datenmengen ist es halt sehr, sehr cool, weil es super effektiv ist.

Da auch viel Optimierung reingesteckt wurde, die Operationen halt auch so auf den Datenmengen halt schnell zu machen, sodass man halt oft dann nicht ein paar Sekunden warten muss, sondern eigentlich immer nur so ein paar hundert Millisekunden.

Und gerade wenn man das zusammen mit Jupyter Notebooks halt interaktiv in einem Browser verwendet, ist es halt sehr wichtig, dass man da nicht irgendwie, wenn man irgendwas ausführt, halt lange warten muss, sondern man drückt irgendwo drauf, es wird ausgeführt, man sieht ein Ergebnis und kann damit direkt weiterarbeiten.

Ja, vielleicht noch mal kurz in Jupyter Notebooks, also tolles Tool tatsächlich, wenn man sich so gerade so Daten aus der Wissenschaft angucken will, einfach einen DataFrame laden, da die ganzen Daten reinkloppen und dann mit Matplotlib und C-Born irgendwo direkt live immer Anlehrungen verfolgen können.

Ja, ich würde fast noch sagen, also der ganz, ganz klassische Workflow ist, man ruft einmal Describe auf, dann kriegt man so einmal die Rahmendaten, Streumass und Lagemaß auf dem DataFrame.

Genau, .describe, Klammer auf, Klammer zu, fertig, dann kriegt man erstmal einen groben Überblick über seine Daten. Dann kann man natürlich auch in die Daten direkt reingucken mit Head und Tail. Und das ist in meiner Erfahrung auch das, was man bei einem neuen Datensatz als allererstes mal macht, um sich anzugucken, womit arbeite ich denn überhaupt.

Und spannenderweise, wir waren eben bei Datenimport, da ist noch eine Sache, meine Lieblingsfunktion ist an der Stelle tatsächlich Import from Clipboard.

Also man kann tatsächlich, wenn man gerade irgendwie mal in Excel war oder in OpenOffice und was kopiert hat, das in Pandas DataFrames direkt wieder einladen. Das habe ich allerdings noch nie ausprobiert in Jupyter Notebooks. Ich weiß nicht, ob der das hinkriegt, aber ich wüsste jetzt auch erstmal nicht, was dagegen sprechen sollte.

Nö, das kann gut sein, dass das funktioniert, ja.

Also kann man sich halt auch ganz kleine Datenchunks, kleine Tabellen direkt aus der Zwischenablage in sein DataFrame reinladen.

Das heißt, wenn wir jetzt von diesem Gigabyte-Bereich liegen, ich glaube,

für wissenschaftliche Anwendung müsste das in den meisten Fällen auch relativ ausreichend sein.

Ja, ja, absolut. Also das ist sowieso so, die allermeisten Leute haben nicht mehr Daten. Also für die allermeisten Leute reicht das aus.

Wenn man mehr hat, dann weiß man das und dann kann man auch was anderes nehmen.

Ja, aber stimmt, wir hatten eben noch gar nicht genau, vielleicht sollten wir da so ein bisschen systematisch auch nochmal kurz reingehen.

Also Pandas, genau, das hat auch was damit zu tun, wo der Name herkommt.

Also Pandas steht eigentlich für Penalty.

Penaldata, oder das war halt auch mal das, was halt so in der Finanzwelt, wo Leute von Geräte haben, von Penaldata.

Und damit meinen sie dann halt oft Excel-Sheets irgendwie oder mehrere davon.

Und das kann Pandas auch, ist aber irgendwie nicht mehr so.

Also es gibt auch noch, es gibt halt einmal Series, es gibt DataFrames, das ist halt sozusagen eine zweidimensionale Tabelle irgendwie.

Series ist eindimensional und dann gibt es auch noch Panels, die sind halt dann mehrdimensional.

Und die werden aber eigentlich nicht mehr verwertet.

Oder wurden eigentlich nie so wirklich viel verwendet.

Und das überlegen die Leute auch gerade, ob sie das irgendwie wieder rausnehmen, weil es eigentlich ziemlich sinnlos ist und der Hauptnutzen bei den DataFrames ist.

Ja, genau, daher kommt der Name.

Es ist ein bisschen blöd, wenn man danach googeln will und dann hat man Tierbilder.

Aber wir haben immer wieder Tierbilder dabei.

Auch interessant ist das Vorbild.

Vorbild für Pandas ist ja R, denke ich mal.

Das ist mit Googlen auch nicht viel einfacher.

Aber genau, ich weiß nicht, du hast auch schon mal mit R gearbeitet, Simon.

Was sind denn da so die, wie kann man das eigentlich miteinander vergleichen?

Oder ist da vielleicht auch ganz interessant zu sehen, wo das herkommt?

Ja, also ich habe in meiner Forschungszeit sehr viel zwischen R und Excel hin und her gewechselt.

Und tatsächlich muss ich sagen, die R...

Ja, DataFrames, die den Pandas DataFrames sehr, sehr ähnlich sind, die hatten irgendwie so zwei, drei zentrale Vorteile gegenüber Excel, weswegen ich irgendwann komplett gewechselt bin.

Einer ist sicherlich, dass die DataFrames immer rechteckig sind.

Also man kann nicht eine Spalte mit weniger Daten füllen als die nächste Spalte.

Es muss zu jeder Zeile immer für jede Spalte auch einen Wert geben.

Also es gibt für jeden Index irgendwie keinen Error.

Genau.

Wenn ein Not a Number ist, ist das okay.

Aber es muss auf jeden Fall irgendeinen Eintrag geben.

Das führt dann dazu, dass man keine Überprüfung mehr machen muss, wie lang ist denn meine Spalte gerade, in der ich bin.

Dann gibt es bei DataFrames grundsätzlich auch Typen je Spalte.

Das ist in Excel nicht so.

Da hat jede Zelle im Prinzip einen Typ, wenn man will.

Und da kann man auch ganz viel...

...bösen Schabernack mit treiben.

Und in DataFrames, dadurch einfach, dass man eine Series pro Spalte hat, hat auch eine Spalte immer nur einen Typ.

Und das Dritte, was ich an DataFrames unheimlich zu schätzen wusste, war, in A heißen die "Factors", in Pandas heißen, glaube ich, einfach nur "Categories" oder haben gar keinen speziellen Namen, dass, wenn man kategorische Daten hat, die erstmal als Texte...

...auch als Texte erscheinen, sowas wie blau, rot, gelb als Farben in einer Spalte, dass die in dem zugrunde liegenden Datenformat erstmal sowas wie Integers sind und entsprechend auch relativ schnell zum Indizieren benutzt werden können.

Das heißt, dass die Diktion-Lesbare wieder als rot, gelb, grün, blau dargestellt werden.

Okay.

Wie macht Pandas das?

Als Dictionary dann?

Oder...?

Das war lange...

Also, in Pandas heißen die Dinger "Categorials" und das wurde dann quasi intern irgendwie auf Integers abgebildet.

Man hatte die einfach durchnummeriert und dann war das halt, was halt natürlich auch viel weniger Platz braucht als Text, aber jetzt auch, glaube ich, mit 0.24 ist es jetzt so.

Und dann hat man halt so einen eigenen Datentyp bekommen, sodass es halt jetzt auch so ein First-Class-Citizen im Grunde ist.

So, vorher war es halt auch immer so, naja, es sind komische Dinge passiert.

Ich hatte zum Beispiel mal irgendwann mit Categoricals auch so ein Problem.

Ich hab da irgendwie größere Data-Frames irgendwie zusammengebastelt und dann ist mir irgendwie so regelmäßig der Hauptspeicher explodiert und ich wusste nicht warum, hab ich dann auch einen Bug irgendwie bei Pandas gefeilt und der war dann ziemlich lange offen und das hatte halt auch damit zu tun,

dass es nicht irgendwie nativ irgendwie da drin war, sondern das war halt mit den anderen Integers Geschichten irgendwie verknuselt und ja, das ist schrecklich.

Ja, aber genau, das ist natürlich eine sehr nette Sache, wenn man das halt so machen kann.

Ja, das heißt, man sieht halt den Text in der Tabelle, aber in Wirklichkeit speichert man halt viel weniger Daten, halt nur eine Zahl.

Ja, praktisch.

Wie schaut man sich denn so Daten dann an?

Ich musste ja irgendwie eine Struktur bringen.

Ich hab ja jetzt irgendwie ganz viele Spalten irgendwie mit Zeilen in meinem großen rechteckigen Datenfeld drin oder sowas und ich möchte jetzt irgendwie die kombinieren.

Also man kann auch direkt auf dem, also das benutze ich tatsächlich ziemlich gerne, ist, man kann sagen, also Data-Frame, man kürzt das normalerweise immer ab mit df, also das Standardobjekt, das man dann halt sozusagen hat, heißt einfach df und da kann man einfach sagen df.plot und dem halt noch so ein bisschen Parameter mitgeben und dann,

äh, plotet das halt direkt.

Dann kannst du ja dann Daten anzeigen, die du dann reingegeben hast, also ich, ähm, das, die Visualisierungsebene dann damit quasi.

Genau, genau, in einem Notebook sieht man halt auch dann direkt irgendwie quasi grafisch was.

Äh, standardmäßig ist es dann halt ein Matplotlib, aber man kann halt das auch, äh, das Plotting-Backend von Panda, äh, sozusagen austauschen, also es ist halt so pluggable und man kann das austauschen und man kann halt auch Bokeh zum Beispiel nehmen oder, äh, weiß gar nicht, es ist auch noch viel andere, ähm.

Ich hab Plotly schon gesehen.

Plotly, genau.

Und, äh, Seaborn ist ja im Prinzip Matplotlib nochmal ein bisschen erweitert, äh, kann man da auch rein, reinpluggen.

Genau, so dass es halt, äh, man hat halt immer, ähm, ähm, kann es dann anders aussehen lassen, so dass zum Beispiel bei, bei Bokeh oder, oder Plotly ist es halt so, wenn man dann sagt df.plot irgendwas, dann kann man das, dann ist halt, äh, ist das, was man sieht, dann halt auch scrollbar zum Beispiel, man kann da drin zoomen oder so, was man bei einem Matplotlib-Bild jetzt nicht machen kann, weil da ist einfach, das ist quasi dann halt so ein statisch rausgerendertes PNG oder so und dann, äh, wenn man da, äh,

da reinzoomt, dann wird es nur pixelig, aber, äh, man sieht nicht mehr, während halt bei, äh, eben dieser, äh, bei, bei Plotly oder so hat man dann, kann man, wenn man reinzoomt, sieht man einfach an der Stelle mehr und, äh, das, man muss an dem Aufruf, an dem Plotaufruf eigentlich nichts ändern, sondern man tauscht einfach nur das Backend aus und, äh, ja, das ist schon sehr nett und das verwende ich tatsächlich oft, äh, irgendwie um Sachen zu visualisieren, ja.

Also, wenn man gar nicht weiß, wie man anfangen soll, ähm, wenn ich mich richtig erinnere, macht Plot standardmäßig einfach ein Perplot, alles gegen alles, dann sieht man schon mal, wie sind die Daten zueinander verteilt, dann, äh, kann man Effekte sehen, wie, ähm, auf zwei bestimmten Variablen ist die Verteilung eher so bimodal, man hat zwei Felder von Punkten oder sowas, also da, da kann man schon grundsätzlich mal sehen, wie sind meine Daten überhaupt verteilt, äh, ansonsten, äh, gibt's ja oft eine Frage,

äh, eine Fragestellung, äh, in der ideellen Welt, äh, gibt's im Vorfeld eine Fragestellung und dann, äh, kann man auf diese Fragestellung hinzuarbeiten, dann weiß man genau, welche Spalten brauche ich jetzt gleich, ähm, Spaltenzugriffe, äh, sind in Pandas, finde ich, super, super easy und convenient, äh, man, man gibt im Prinzip einfach nur von seinem DataFrame-Objekt, ähm, per Dot-Syntax den Spaltennamen an oder in, ähm, eckigen Klammern wie bei einem Listenzugriff, ähm,

jetzt muss ich grad genau überlegen, äh, doch, da geht der Spaltenname auch, ja, es gibt, es gibt zwei Interfaces, es gibt halt mit, mit, ähm, man kann halt entweder den Namen nehmen oder man kann halt auch den numerischen Index nehmen, äh, das ist Log und iLog, glaube ich, sind die unterschiedlichen, äh, Funktionen, die man da aufrufen kann, aber, äh, also, ich würde auch eigentlich immer eher, also, die, die mit den Indizes ist eine ältere Geschichte und, äh, ich würde eher die Namen immer nehmen, weil das ist ja ein klarer, was, was da eigentlich gemeint ist, ja.

Also erstmal hat man Zugriff auf seine, äh, tabellarischen Daten und da kann man sagen, ich möchte jetzt, äh, Spalten A, B und E plotten, ähm, auf einer X-Achse, die ist in Spalte D meinetwegen.

Aber nur die roten oder die roten und die gelben vergleichen.

Genau, ähm, das ist dann der zweite Schritt, äh, dass man anfängt vorher zu aggregieren, man kann dann überlegen, äh, will ich, ähm,

nur bestimmte Gruppierungen haben, es gibt, äh, Funktionen, die heißen GroupBy, ähm, es gibt auch Funktionen, ähm, um, äh, eine kumulative Summe über irgendeinen Datensatz, äh, direkt per Funktion aufzurufen.

Das ist was, was man auch aufplott, einfach plotten möchte.

Dass man sagt, okay, ich hab jetzt hier meine Daten und, äh, ich plotte dahinter in einer zweiten Serie auch noch die kumulative Summe, dann, äh, ist das quasi per einzelnen Funktionsaufruf in Pandas möglich.

Ähm, ist darüberhin spannend für die ganze Anwendung, ne, wenn man irgendwie so kategorisierbare Daten mit verschiedenen Merkmalen hat und man dann, äh, bestimmten Merkmalen, bestimmte Wahrscheinlichkeiten zuordnen will, also mehrere Merkmale hat, also keine Ahnung, Leute ab zwei Meter und, äh, trotzdem unter, weiß nicht, 70 Kilo und, ähm, welche Wahrscheinlichkeit haben die für bestimmte Dinge im Vergleich?

Genau, da, da kommen wir in, in anderen Bereichen so ein bisschen rein und das ist, ähm, äh, Indizierung auf Basis von, von bullschen Werten, also man kann jetzt zum Beispiel sagen,

ich, äh, möchte aus meinem Datensatz eigentlich nur alle Zeilen auswählen, äh, in denen Spalte A, was zum Beispiel die Höhe sein könnte, sagen wir Höhe, äh, eines Menschen kleiner als 1,80 Meter und größer als 1,60 Meter ist.

Und dann würde der mir, ähm, entsprechend einen Slice aus meinem Data-Frame rausgeben, der nur dieser Bedingungen entspricht.

Was wird denn der technische Erzeuger? Also macht der eine Kopie der Tabelle mit diesen Werten oder setzt der halt dann noch eine

neue Tabelle daneben mit so Bullian-Werten, ist wahr, ist falsch oder, und macht da doch so ein Index, den er nur liest, oder?

Ähm, gut, also meistens wird tatsächlich, wenn man jetzt irgendwie, äh, da irgendwas extrahiert, wird, wird kopiert, man kann aber auch sagen, dass es nicht kopiert werden soll, ähm, ähm, ja, äh, also das sind meistens diese, diese Bullien, also im Grunde erzeugt das halt eine Spalte, äh, wenn man jetzt zum Beispiel sowas hat, man sagt, DF, eckige Klammer,

auf, irgendwie, ähm, DF.2 ist größer irgendwas und dann, und, äh, DF.2 ist kleiner irgendwas, äh, dieser, dieser, dieser Logo, äh, Bullscher-Ausdruck wird sozusagen dann halt, äh, irgendwie in eine Spalte verwendet, halt, wo dann irgendwie in jeder Zeile True oder False drinsteht.

Und dann wird das halt, wenn man jetzt zeilenweise filtert, äh, werden halt alle Zeilen, die halt, äh, True sind, raus, äh, werden halt rausgesucht und alle anderen werden halt ignoriert, quasi.

Ähm, und, ähm, ja, ganz genau, wie das technisch unten drunter funktioniert, weiß ich jetzt aber auch nicht.

Ähm, äh, und, ja, das sind halt so, ich kann mir vorstellen, dass irgendwie so ein NumPy halt irgendwie als Feature drin, dass man Sachen, dass man so Masken verwenden kann, aber ich bin mir nicht sicher, ob es wirklich verwendet wird, keine Ahnung.

Egal, muss man halt nochmal genauer nachlesen.

Ähm, ja, und, ähm, dann kann man da irgendwie weitere, weitere Dinge mitmachen.

Das ist, äh, das ist halt recht, äh, recht schön, schönes.

Schöne Methode, um da halt irgendwie Sachen rauszuselecten.

Vielleicht kann man an der Stelle auch mal grad, äh, ne, ne Blogartikel-Reihe erwähnen, das fällt mir da grad ein, ähm, die ich immer wieder, wenn ich irgendwie Leuten, äh, von Pandas erzähle, auch mit erwähne, weil die, weil die so toll ist.

und

ist von Tom Augsburger

ja genau, das heißt

Modern Pandas

und das ist Teil 1

bis, ich weiß gar nicht wie viel es gibt

bis 8

momentan

kenne ich noch gar nicht, muss ich auch mal reinschauen

so lernt man

immer dazu

genau und der beschreibt halt

sehr ausführlich wie das mit diesem Indexing

aus Userperspektive, was man damit alles machen kann

funktioniert

und ja

also gerade wenn man jetzt nicht nur einen Index hat

das ist auch etwas, was halt Pandas kennt

was ich von Datenbanken so nicht kenne

also Datenbanken bedeuten Indizes

ein bisschen was anderes als halt jetzt bei Pandas

man kann halt bei Pandas auch mehrdimensional

Indizes haben und dann halt irgendwie

kreuz und quer verschachtelte Abfragen macht

und da

wenn man das sich so zuerst anguckt, dann

raucht einem da relativ schnell so der Kopf

aber wenn man tatsächlich diese Probleme

hat, dann kann das ultra praktisch sein

wenn man da irgendwie sich mit auskennt

und diese Modern Pandas Serie ist halt eine

wo man das sehr schön

sehen kann, wie das funktioniert

im ersten Artikel werden glaube ich

da irgendwie so halt

diverse Indize-Geschichten erklärt

und dann gibt es halt einen Artikel

nur zu Method-Chaining

und ja

dann eins zu Indizes

und da wird dann auch nochmal das alte

Interface

gezeigt und halt was man jetzt

mit dem

neuen Interface an Dingen machen kann und da gibt es halt

wirklich verrückte Abfragen

die man

also

super spannend, was der neueste heiße Scheiß ist

was ich jetzt da gekannt habe, ist auch die einzige Quelle

deswegen habe ich jetzt den Vergleich natürlich wieder nicht

ist diese Einführung in

Python mit Data Science oder Data Science

mit Python von Jake Wanderplast

da ist auch ein schönes Artikel

zu Pandas drin, das ist auch frei

irgendwo bei GitHub

und sogar als Notebooks

die er alle gebraucht hat, da hat er irgendwie unter MIT

die Lizenz da online gestellt

und da kann man auch genau die Sachen als Notebooks direkt alle ausprobieren

das ist ein tolles Beispiel für diese, glaube ich, die

einfachen, so die Basissachen

drin, dass man das grundsätzliche alte Prinzip mal

versteht, das man direkt da mit Pandas potten kann

ich glaube über den Untergang der Titanic oder sowas

Ah ja

Ja, sonst benutzen die Tutorials

oft gerne den Iris-Datensatz

da geht es irgendwie um Blütenlänge

und Breite und

das war mir immer ein bisschen sympathischer als Biologe

Also welche

Klassen jetzt wie oder wie viele Frauen, Männer und

wie viele Jungs und Kinder

untergegangen sind, wie viele nicht

Das ist auch super spannend mit diesen

Multi-Level-Indizes

da sollten wir gleich auch nochmal vielleicht

ein paar Minuten uns Zeit für nehmen

Für den

Moment sei vielleicht

auch nochmal erwähnt, wenn man jetzt ein Pandas

DataFrame haben möchte und man

importiert das nicht aus einer Datei

oder aus der Zwischenablage

wie komme ich denn überhaupt zu meinem

DataFrame-Objekt und du hast eben gefragt

kann man da vielleicht Dictronix benutzen? Ja, kann man

tatsächlich. Also wenn ich in

Python schon ein Dictronary habe

was Keys und

als Values Listen hat

dann kann ich einfach

mein DataFrame erzeugen mit

pandas.dataframe oder

pd.dataframe, wenn man Pandas als

pd importiert

und da reingeben, mein Dictronary

dann macht er automatisch

aus den Keys Spaltennamen

und aus den Values, aus den Listen macht

er dann meine Series

hat natürlich

zur Bedingung, dass die gleich lang sind

sonst gibt es da einen Fehler

ich weiß gar nicht, ob der da mit na auffüllt

oder ob der

ja, ich bin mir gar nicht sicher

außer an das ein Fehler wirft, ich weiß es aber auch nicht

es gibt auch irgendwie so eine andere Funktion, ich weiß

jetzt nicht, bei was es genau geht, wenn man halt so ein DataFrame

über so ein NumPy-Array hat oder sowas

dass der automatisch neue Spalten erzeugen

kann, die er dann irgendwie

fortsetzt, ich weiß nicht, ob das linear passiert

oder sowas, habe ich irgendwie kurz entdeckt

wenn man einfach eine neue Spalte erstellt

dann, wenn man schon drei oder vier hat, dass

du dann, wenn du die fünfte erstellst, einfach dann

neue Werte reinbaut

kann sein, weiß ich nicht

vielleicht habe ich auch wieder

irgendwelchen Quatsch erzählt, ich weiß nicht

gerade nicht genau, was du da

meinst

jetzt habe ich das Buch natürlich zu Hause liegen lassen

irgendwo nachgeschlagen

Buch ist aber auch ein gutes

Stichwort, man

kriegt ja immer den gut gemeinten Ratschlag

guck doch mal ins Handbuch

das Pandas Handbuch ist tatsächlich

länglich, es hat

2900 irgendwas Seiten

davon sind

rund 900 so die Basisfunktionen

1400 nur die

API-Referenz und dann

nochmal weiterführende

Informationen

Hast du das durchgelesen?

Nee

So bei aller Liebe, das ist dann

doch etwas viel, aber

man kann halt relativ schnell kapitelweise

wenn man was ganz

bestimmtes sucht, da reinspringen

Es ist auch alles, also verlinkte

wie heißt das, Table of Contents

Inhaltsverzeichnis, genau

verlinktes Inhaltsverzeichnis, man kommt schnell dahin

Ja

Ja, die Dokumentation

von Pandas ist auch sehr gut, aber auch manchmal

die ist schon etwas trocken

manchmal muss man sich schon so ein bisschen

ein bisschen quälen

Vielleicht liegt das an dem Tabellenthema

Könnte auch, vielleicht liegt es einfach am Thema

Sollte man vielleicht eher irgendwie Schreiner werden

oder so

Das ist eigentlich total langweilig

Ja, das überlege ich mir manchmal

Das wäre toll

Ja, aber

genau

Stimmt, was hatten wir erwähnt

Was gibt es für Datentypen

so in Serien, Data Frames, Panels

Was kann man damit machen

Ja, so, genau

Man kann auch sehr viele Dinge

die man sonst vielleicht mit einer Datenbank machen würde

damit tun und das hätte ja auch so den Vorteil

Also das kann ich auch nur, ich finde

die Art, also das User Interface

von Pandas ist halt

ziemlich angenehm und ist auch relativ kurz

also wenn man in einer Datenbank arbeitet

und da SQL Statements schreibt, das geht natürlich auch

aber das ist halt viel

viel umständlicher

und Pandas hat halt eine sehr schöne

sehr schöne

sehr schöne UI eigentlich

und man kann viel damit machen

was man halt auch in einer Datenbank normalerweise tun würde

und insofern kann ich das auch nur empfehlen, wenn man jetzt irgendwie

so ein Datenbankproblem hat, man kann auch irgendwie die komplette

Datenbank, meistens sind die ja nicht so groß, auch irgendwie

in Pandas sich reinholen oder als Data Frames

aus der Datenbank ziehen und dann da

irgendwelche Dinge machen und dann schon mal

wenn man dann weiß, wie es geht, dann kann man es hinterher auch

in SQL machen, aber vieles

von dem lässt sich auch locker

in Pandas mal ausprobieren, weil Pandas hat ja eben auch solche

Funktionen wie, man kann Joins

machen, man kann halt Data Frames Merge

also da heißt das dann, also vielleicht

verwendet man eher den Aufruf Merge oder so

aber im Grunde macht das dann halt auch

ein Join zwischen zwei Data Frames, dann kann man

angeben, auf welchen Spalten gejoint

werden soll und solche Dinge

und genau, eben all diese

Group-By-Geschichten

gibt es tatsächlich so eine Funktion, wie man eine Datenbank in

Data Frame bekommt und andersrum, wie man eine

Data Frame, wie man irgendeinen Datenbank-Typen speichert?

Naja, also für alle Datenbanken

gibt es da Adapter, mit denen man

die Daten auch auslesen kann, ja.

Genau, also diese Import-Export-Geschichten

also wir haben nur über Import

gesprochen, aber

Export gibt es halt auch für alle diese

Daten-Typen. Warum schreibt dann irgendjemand noch

SQL-Statements?

Ja doch, also manchmal

es kann schon sinnvoll

durchaus sinnvoll sein,

also wenn du in der Datenbank ja auch irgendwas manipulieren

willst an Werten, dann musst du es ja tun,

kannst ja gar nicht, kannst du auch in Pandas machen,

aber dann hast du das Problem, musst du es ja irgendwie wieder zurück in die Datenbank

schreiben und dann...

Dann markierst du eine neue Datenbank.

Ja, und gegebenenfalls

ist das, was du in deinem Speicher

bearbeiten kannst, auch

kleiner als das, was

in der gesamten Datenbank ist, das heißt,

beim Import würdest du schon nur einen Teil aus der

Datenbank nehmen, kannst damit aber

dann relativ komfortabel rumspielen.

Ja.

Tatsächlich, der Befehl

ist Join, auch in

DataFrames. Ich verwechsel das auch immer wieder,

deswegen habe ich gerade mal kurz nachgeguckt.

Und es gibt noch Concatenate,

da kann man aus einem DataFrame irgendwie

Spalten in ein

anderes reinziehen.

Ja, und dann genau

solche, eben es gibt

so Datenmanipulationsgeschichten,

eben Join, Merge,

dann gibt es noch

solche Sachen wie,

genau, das ist auch schwer

zu erklären, wenn man das jetzt nur hört,

fürchte ich,

sowas wie Pivot,

Unpivot, Melt,

Stack, Unstack, so sehr praktische

Geschichten, aber ich weiß jetzt ehrlich gesagt nicht genau,

wie ich das erklären kann. Ja, du kannst,

also wenn du, hm, okay, ich versuch's

mal einfach, wenn du jetzt,

du machst im Grunde aus einer,

aus

Dingen, die in einer Spalte

stehen, machst du mit Pivot

irgendwie zusätzliche Spalten.

Achso, ich bin gerade völlig auf

den Kopf gefallen, ich hab's natürlich mit der Transformation gerade

verwechselt. Ja, so Transpose,

ja, das ist natürlich, das ist

relativ einfach, aber Pivot, das macht schon

so ein bisschen kompliziertere Dinge. Das aggregiert

irgendwas zur besseren Auswertung.

Einen Widerfall,

doch? Ne, das, das,

ja, also manchmal hat man Daten halt in einem Format,

in dem man schlecht plotten kann.

Und manchmal braucht man

halt Dinge, die in einer Zeile, die

irgendwo in einer Zeile stehen, die möchte man als Spalte haben,

um dann halt die Spalte besser plotten zu können, und dafür

fällt man dann auf Pivot. Und dann, äh,

äh, genau, die umgekehrte Funktion

dazu ist Melt, äh, und,

ähm, die, äh,

aber eigentlich noch allgemeineren Funktionen,

die funktionieren dann eben auf so, äh,

Multilevel-Indizesen, halt Stack und Unstack.

Ja. Aber das kann auch sehr schnell,

äh, einen so ein bisschen überfordern.

Also ich kann sagen, so aus

dem Biologen-Alltag, dass ich Pivot

und Melt nie benutzt hab, ähm, einfach,

weil, weil die vielleicht

auch zu viel Magie im Hintergrund noch machen

können. Äh, Stack und Unstack

aber sehr häufig, weil, äh,

in der, in der Realität

sind, äh, wir hatten ja eingangs

über die Excel-Tabellen gesprochen,

die nicht immer ganz maschinenlesbar sind.

Es gibt noch den Zwischenwert,

wo die zwar maschinenlesbar sind,

aber mehrere Level von Indizes

haben, und, äh, wenn

die mehrere Level von Indizes haben,

man könnte sich das zum Beispiel vorstellen

wie, ähm,

ähm, weiß ich nicht,

ein, äh,

ich hatte eben noch

ein Beispiel im Kopf, äh, äh,

äh, sowas wie, äh,

Klausurnoten nach Semestern

in zwei verschiedenen

Gruppen, sagen wir mal,

Biologen versus Chemiker oder sowas,

ähm, wie die in der Chemieklausur

abschneiden im ersten Semester,

im zweiten Semester. Und

dann hat man diese Gruppierung einmal,

ähm, zu welcher Gruppe

gehören die Personen an, aber

dann hat man auch, äh, für

jede Zeile im Prinzip eine spezifische

Person.

Das heißt, mehrere Personen

teilen die gleiche Gruppe,

also Biologe oder Chemiker,

ähm, aber jede Person hat

eigene Noten in Semester 1,

in Semester 2. Wenn man das

jetzt, jetzt muss ich kurz überlegen, in welche

Richtung man das stacken würde,

dann würde man im Prinzip

sagen, ich, ähm,

schreibe jetzt

jede

Person einzeln als Zeile

auf und habe eine neue Spalte, wo

die Gruppe nochmal als sich wiederholender

Wert mit drin steht.

Sodass ich wegkomme von

ich habe, ähm, im Prinzip

zwei Zeilen, die jeweils vier Unterzeilen

beinhalten, zu ich

habe einfach acht Zeilen, äh,

wo in, in jeder dieser

Zeilen die Gruppe nochmal explizit drinsteht.

Ähm, das

macht es dann einfacher nachher Gruppierungen

zu machen. Außerdem könnte

man dann mit Unstack in die andere

Richtung wieder sagen, ich möchte das jetzt

gar nicht nach den Gruppierungen unstacken, sondern

nach Semestern zum Beispiel. Und dann

tauscht man plötzlich die, die Spalte

identitäten. Aber ja, also,

Tabellentransformationen

einfach nur in einem Audio-Podcast zu erklären,

ist sehr schwierig.

Genau, ich, ja, ich weiß gar nicht, ob

es, ob es zu dem Stack-an-Stack oder so, äh,

äh, Thema halt auch ein Modern

Pandas Artikel gibt.

Ich fürchte, nein. Ah, schade.

Ah ja, muss man einfach mal nach, äh, also,

na ja, ich verlinke da einfach mal einen Artikel zu,

wie das, wie das so aussieht. Wenn man das sieht,

ist es eigentlich, dann kann man's, kann man's deutlich

besser verstehen. Ja.

Genau, das sind so die Dinge, die man dann, dann

mit dann tut. Hm.

Ja.

Äh.

Ja, vielleicht noch mal dieser Pivot, äh, kurz, das

wart ihr gerade kurz dabei, das sind wir kurz abgeschweift.

Mhm. Also, was macht man damit

jetzt genau? Also, ich kenne das irgendwie jetzt auch irgendwie aus Excel, wenn man

eine Auswertung hat, man hat dann irgendwelche Datenblätter

oder sowas, und dann möchte man dann

irgendwelche Aggregate

irgendeinem Endnutzer auf einem

Auswertungs-Dashboard zur Verfügung

stellen. Und da wird dann irgendwas zusammen

gerechnet.

Hm.

Ja, Excel genau kann ja auch sowas

so, Pivot-Tabellen. Ja. Also, ich hab hier

gerade mal das, das, äh, Data Science

Cheat-Cheat-Panda ist offen. Ah.

Können wir auch nachher verlinken. Ja.

Ähm, und da steht im Wesentlichen drin,

dass, äh, Pivot-Table,

wie gesagt, ich hab's noch nie benutzt, aber dass es, ähm,

eine

Pivot-Tabelle macht, die

äh, die

anhand von einer Spalte

gruppiert, und dann

aber über andere Spalten eine Funktion

aufruft. Das kann zum Beispiel sowas sein,

wie Mittelwert oder eine Summe oder

ähm, nahezu

beliebige Funktionen.

Hm.

Möglicherweise

hab ich das auch nie

benutzt, weil ich die Excel-Funktion

nie benutzt hab. Ähm,

was ich allerdings öfter benutzt hab,

ist, äh, die Funktion Apply.

Und Apply erlaubt einem jetzt

innerhalb eines Data Frames an,

auf, auf Basis einer

Achse sozusagen, eine

Funktion auszuführen. Das kann auch wieder

nur Mittelwert oder Standardabweichung

sein. Das können aber

auch, äh, komplexere Funktionen

sein. Und, ähm,

also

für, für die, die vielleicht schon Hintergrund

in R haben, da gibt's, äh,

T-Apply und L-Apply für

Zeilen, Spalten und was weiß

ich nicht alles. In Pandas

Data Frames gibt's im Wesentlichen Apply und

man gibt die Achse an. Also soll das

auf Reihen, auf Spalten,

äh, äh, agieren. Hm.

Und dann gibt man eine Funktion an und die

wird dann entsprechend für

eine komplette Spalte oder eine komplette

Zeile ausgeführt.

Ja, das ist vielleicht eben, genau, das ist auch noch ein ganz wichtiger

Punkt, den wir noch gar nicht erwähnt haben, dass

man, man kann, was man nicht tun sollte,

äh, äh, über Data Frames iterieren

und dann in der Vorschleife da irgendwelche

Dinge mitmachen. Ja, das könnte man sich auch vorstellen,

dass man das so tut, weil

das, wenn man das, äh, wenn man

aus Python kommt, äh, dann macht man das ja mit

Listen normalerweise so. Aber, äh,

das geht halt nicht, oder das geht schon,

ist halt nur dann sehr, sehr langsam.

Äh, während halt, wenn man jetzt

Apply aufruft, dann, äh, ist das halt

ziemlich schnell.

Äh, weil unten drunter, äh,

weil eben, also, vor, vor Loops in Python

sowieso langsam sind und man dann eben

keine Vorloop machen muss, sondern das läuft halt

alles, äh, irgendwie in, in, in den entsprechenden,

also kommt, je nachdem, hm,

wie der Datentyp ist, aber möglicherweise

halt landet das in einer dieser optimierten

vortragenden Bibliotheken, die unten drunter unter

der Lampe, äh, liegen. Und es

ist halt auch so, dass es dann in gewisser Weise schon

parallelisiert wird. Und halt diese, diese

ich weiß jetzt gar nicht, wofür SIMD steht,

diese Instruktions-Test,

diese Single Instruction Multiple Data.

Ah, okay. Ja, äh, genau.

Super. Dankeschön.

Äh, da, wo, ja, man

spricht da auch von Vektorisierung. Also, man,

ähm, äh, kann

halt mit einem Taktzyklus

halt mehrere, äh,

Operationen oder ausführen,

weil man hat so super lange Register,

äh, weiß ich nicht, vielleicht

512, äh, Byte oder so.

Und da sind dann halt viele, äh,

äh, wenn man jetzt Integer hat,

4 Byte, äh, Werte drin. Und die werden

dann halt alle addiert gleichzeitig oder

multipliziert oder sowas.

Und man zerlegt halt ein komplettes, äh,

äh, Array sozusagen, auf dem man

irgendwelche Dinge macht, halt in diese Blöcke

und kann, braucht dann halt viel weniger Takte,

als wenn man da einen For-Loop drüber machen würde.

Ja, und das ist,

macht Sachen super schnell, ja. Also das,

man hat halt, äh, irgendwie so

Python-Interface mit einem Jupyter Notebook,

das sieht dann halt so aus, als hätte man so super,

wäre man super high-levelig, aber wenn man eine Operation macht,

kann es sein, dass dann tatsächlich etwas sehr, sehr

Optimiertes, äh, passiert und es sehr schnell

ist und man, wenn jemand da hingehen würde,

würde es ein C schreiben, ist er möglicherweise

deutlich langsamer, wenn er, wenn er

nicht genau weiß, was er tut.

Ähm, und das ist natürlich für viele

Leute auch total überraschend, äh, äh, und

das ist auch eine sehr, sehr, sehr, sehr schöne Geschichte.

Aber ja, man muss halt, äh,

man muss halt auch so ein bisschen eine komische

Syntax dafür, äh, halt in Kauf nehmen.

Man kann halt nicht mehr For-Loops machen, man muss halt

immer Apply schreiben und dann halt eine

Funktion übergeben. Oft übergibt man dann halt so anonyme

Funktionen, schreibt dann Apply und dann Lambda,

X und dann kriegt man halt, äh, irgendwie ein Wert übergeben

und macht dann damit irgendwas. Ja.

Ähm. - Comprehensions oder sowas kann man auch

vergessen, genau, das selbe Problem. - Genau, das

geht alles nicht mehr. Ja.

Man schreibt halt alles nur noch, äh,

ja, quasi, ja, man

schreibt eigentlich fast alles in Apply. Ich weiß gar nicht, ob es

da noch andere Funktionen gibt, die so ähnlich sind wie Apply.

Naja.

Ne, das war eigentlich immer

Apply, ja.

Ja, ja, und dann chained man

halt die Sachen hintereinander.

Man kann halt dann, diese

Methode liefert dann halt das Ergebnis von dem Apply

zurück, dann, äh, ruft man

darauf wieder was anderes auf und dann hat man halt eine ganze Reihe

von so hintereinander gechaineden Apply aufrufen

unter Umständen. Und, ähm, ja.

Ähm.

Das ist auch, auch witzig, äh, äh,

fällt mir grad noch zu dieser Vektorisierungsgeschichte

ein, ähm,

früher haben auch

Leute irgendwie, äh, erzählt,

naja, ach, das mit dem, mit der

Parallelisierung, das ist ja alles gar kein Problem, wenn wir jetzt

viele CPUs haben, so, äh, irgendwie,

die, die, äh, Steigerung der Taktfrequenz war ja dann

irgendwann auch schon vor längerer Zeit irgendwie vorbei,

mehr oder weniger, und man muss halt,

man kriegt halt mehr Prozessoren, also

Moore's Law ist halt noch nicht wirklich weg, weil sich

das eigentlich auch nur auf die Transistoren, nicht auf, äh,

die Geschwindigkeit als solche irgendwie bezieht.

Ähm, aber, äh,

dann hieß es halt so, naja,

das, das ist kein Problem, wenn man mehrere Prozessoren hat,

da gibt's halt bestimmt Compiler, die das automatisch parallelisieren

oder so. Ne.

Ist nicht passiert, wird's auch nie

passieren, dass Sachen automatisch

parallelisieren geht halt nicht. Und, äh,

das Schlimme ist, selbst so was

wie automatisch vektorisieren geht halt nicht.

Weil, äh,

dummerweise, wenn man jetzt, äh,

in, in C, na, wenn man sich jetzt

mal vorstellt, man schreibt eine Vorschleife, die jetzt

zwei Vektoren addiert,

äh, also sagen wir mal so, die macht einfach nur

C gleich A plus B.

Wobei jetzt C, A und B sind

halt, äh, Vektoren der gleichen Länge.

Äh, naja, C ist der, der

erzeugt wird. Äh,

und man macht halt einfach vor, look, die das tut,

dann denkt man sich jetzt, könnte doch eigentlich der

Prozessor, äh, der, der Compiler hingehen und, äh,

das, äh, irgendwie in diese

Single Instruction Multiple Data, äh,

äh, Prozessorbefehle umwandeln

und dann irgendwie, äh, das deutlich schneller machen,

stellt sich heraus, nein, kann er nicht, weil,

äh, in C ist es, äh, ändert es

halt die Semantik von deinem Programm.

Weil, es könnte ja auch sein, dass

dieses C irgendwie, äh,

wieder was mit deinem A

und deinem B zu tun hat und die

Reihenfolge, in der du Sachen addierst,

sich auf die nächste Addition irgendwie auswirken.

Sodass halt, wenn du das in der Vorlog machst, kommt halt was

raus, als wenn du das parallel machst.

Und dann muss der Compiler natürlich sagen,

so, nee, kann ich nicht automatisch optimieren, weil,

weiß er nicht, vielleicht ist das irgendwie, hat das,

ist das die Programmlogik, dass das so sein muss.

So, das heißt, bei sowas

Simples geht's schon nicht. Also man kann natürlich irgendwie

dann so, äh, äh,

Hinweise an den Compiler dazuschreiben, also

man sagt so, hier ist okay, darfst du schon optimieren,

mach da mal, äh, aber

so generell kann ein Compiler das nicht machen.

Und damit ist es natürlich schon irgendwie,

ja, und das ist

einer der Gründe, warum das auch in Fortran so

viel, äh, schöner funktioniert ist, weil da

gehen solche Sachen nicht. Da kannst du nicht, äh,

kann nicht das Ergebnis, ähm,

einer Addition in,

bei, wenn du, wenn du zwei solche Arrays

addierst, äh, äh, kann

nicht sich auswirken auf die nächste,

sozusagen. Das ist, das T kann nicht irgendwie wieder

zu A oder zu B gehören. Sodass,

da das ausgeschlossen ist, kannst du in,

in Fortran solche Operationen halt automatisch

vektorisieren. Also einer der Gründe, warum das halt

irgendwann auch alles irgendwie Fortran ist.

Äh, auf der anderen Seite, das müsste nicht unbedingt,

du kannst auch ein C machen oder ein C++, wenn du

das halt dem Compiler entsprechende Hinweise gibst. Aber

es ist alles irgendwie nicht so, nicht so ganz einfach.

Und, ähm, ja.

Wahrscheinlich will man sich da auch nicht mit rumschlagen.

Aber wenn man einfach so Paddler verwendet, dann passiert das ja alles automatisch

und man hat nichts damit zu tun. Das ist gut.

Ja.

Ja, ähm,

genau.

Vektorisierung hatten wir dann.

Genau, was wir vielleicht nochmal, äh,

ein bisschen detaillierter ansprechen können, ist irgendwie

das Plotting. Also es gibt, äh,

für jedes DataFrame erstmal

ein DotPlot. Und da kann man

noch ein paar Parameter angeben und seinen Plot

konfigurieren. Es gibt auch

noch eine Reihe von anderen Funktionen.

Ich hab die auch nie alle im Kopf.

Aber da gibt's irgendwie noch Scatter und Box.

Und da hat man dann verschiedene

Diagrammtypen auch standardmäßig

schon vorimplementiert.

Damit man sich nicht mehr darum kümmern muss,

die Plot-Funktion entsprechend durchzukonfigurieren.

Sondern man bekommt

direkt die Plots, die man haben möchte.

Ja.

Und, ähm,

eine Sache, die ich ganz schön finde, ist,

man kann als Spalten

da auch wieder die Spalten-Namen angeben.

Man muss jetzt nicht irgendwelche

Koordinaten in dem DataFrame angeben,

sondern man sagt: Plotte bitte

Höhe, Breite,

Länge gegen Zeitachse.

Und dann passiert

das genau so.

Das ist einfach auch dann

deutlich besser lesbarer

und wartbarer Code, den man

schreibt. Ja.

Ja.

Ja.

Welche

präferiert ihr von diesen Plotting-Bibliotheken?

Also jetzt so irgendwie Matplotlib mit Seaborn

oder dann doch Bookie, oder?

Ich verwende

meistens Seaborn tatsächlich, ähm,

in Notebooks.

Aber, ähm,

es kommt halt drauf an,

auf den Einsatzzweck. Also meistens

müssen die für mich nicht interaktiv sein.

Und dann verwende ich halt Seaborn.

Weil es einfach netter aussieht, als Matplotlib direkt zu verwenden.

Und das ist halt auch irgendwie einfacher.

Es gibt halt manche Plots, das geht auch

mit Matplotlib, aber, äh,

es ist halt schon so ein bisschen, also

ehrlich gesagt, ich mach das meistens so,

dass ich auf Seaborn, äh,

auf der Seaborn-Dokumentation halt dann so

angucke, was ich so grob brauche. Und dann

scrolle ich halt durch die Beispiele, bis ich irgendwas gefunden habe.

Dann kopiere ich den Aufruf und modifiziere

den so lange, bis es halt irgendwie funktioniert.

Ähm,

wenn man jetzt mit Matplotlib hingehen würde

und das so nachbauen würde, dann

ist das, äh, ist das halt

deutlich schwieriger. Und, äh,

es geht natürlich auch, Matplotlib ist, Seaborn baut

darauf auf, und Matplotlib ist sehr mächtig.

Aber es ist, äh, die API ist nicht

so ganz einfach. Und, ähm,

eigentlich musste ich da nie, da ich auch nie so

wirklich komplizierte Visualisierungen mache, musste ich da nie so tief

einsteigen, dass ich das irgendwie wirklich

gebraucht hätte, sondern für mich reicht Seaborn meistens aus.

Und dann gibt's aber natürlich auch noch Fälle,

wo man das halt, ähm,

äh, so ein bisschen interaktiv braucht, wo man

in, da drin zoomen können möchte, oder man möchte

es auf einer Webseite haben. Und

dann, ähm, ja,

ist eher sowas wie Bokeh oder Plotly,

äh, das, was man da verwenden möchte. Also,

äh, grad wenn man jetzt, also Plotly hab ich

glaub ich auch schon mal für so Dashboards

oder so, kann man das ganz gut verwenden.

Äh, man kann tatsächlich, äh,

relativ einfach eben, wenn man jetzt eine Datenbank

hat oder so, dann zockt man daraus wieder DataFrames.

Und, äh, die kann man dann

sehr einfach mit, mit Plotly, äh,

irgendwie auf einer Webseite visualisieren. Und dann

können sich die Leute, die

das angucken, halt auch dann, äh, irgendwie

den Bereich, der sie interessiert, halt irgendwie auswählen.

Und, ähm, daran zoomen und so.

Ja. Also ich bin auch totaler

Plotly-Fan, ähm,

äh, im Wesentlichen, was da rauskommt

als, als Graph ist ne

kleine HTML-Seite oder auch nur

ein Snippet, das man einbinden kann.

Und, äh, zugrunde liegt

im D3JS, das ist eine Visualisierungs-

Library in JavaScript.

Und, äh, das hat

super viele Funktionen, aber ich benutze

das hauptsächlich dafür, dass

man einen Mouse-Hover auf den Datensatz

hat. Man fährt halt

über den Graph drüber und man sieht den exakten Wert,

nochmal an der Maus. Äh, das ist so

die, die, die wichtigste

Funktion, die ich an Plotly immer wieder nutze.

Ähm, das kann man aber auch beliebig

weitereskalieren noch. Es gibt jetzt neu,

äh, von Plotly Dash, das

ist ein ganzes Dashboard mit

Plotly-Grafen, geschrieben in

Flask. Und, äh,

das kriegt man auch superschnell

hochgefahren. Und es gibt sogar inzwischen

ein GitHub-Projekt, das, äh, ne Django-Anbindung

für, für dieses Plotly-Dashboard

macht. Also, ähm,

da kann man dann im Wesentlichen ne

ganze Website mit Datenvisualisierung

als, als Django-Applikation

direkt ausliefern.

Was auch ziemlich nett ist,

hab ich aber noch nicht im Detail ausprobiert.

Gibt's sowas auch für R?

Ja, ja, ja, so, äh, man muss sogar sagen,

der Dash ist halt so im Nachbau von etwas,

was halt in R super populär

ist. Und das ist, in R heißt das Shiny.

Ja, genau. Und, ähm,

das, äh, ist

eigentlich immer noch so ein bisschen der, der Goldstandard für,

für diese, diese Geschichten, weil,

also, ich weiß nicht, wie weit, also,

ich hab jetzt auch schon lange nicht mehr angeguckt, aber,

wie weit Dash da jetzt ist, ob sie, also,

äh, ob sie das schon, ob sie da, da

dran sind, aber, ähm,

man hört immer noch, dass, dass viele Leute sagen,

so, ah, aber Shiny ist schon irgendwie toller

und ich mag das lieber als irgendwie,

da gibt's noch keine so richtige Alternative in der

breiten Welt, so, ja. Ich mein, äh,

da, da guckt auch jeder vom anderen ab, ehrlicherweise.

Also, ähm, äh,

R hat auch irgendwann angefangen

mit diesen Notebooks und, ähm,

hat jetzt die Möglichkeit, ganze Berichte

in Markdown zu mischen,

mit ausführbaren Codes zählen.

Also, im Prinzip das, was man mit Jupyter

Notebooks für Python hat, gibt's

auch in R. Ähm,

da, da, die, also, das

ist so eine Co-Evolution der beiden,

äh, der beiden

Analyse-Workflows, sag ich mal.

Ja, wobei man sagen muss, dass die ursprüngliche

Idee, äh, für diese Notebook-Geschichte,

ähm, die Art, wie wir das, das kommt aus

Mathematica, ähm,

und es gibt schon ganz lang,

äh, aber ist nie, hat sich nie

so wirklich durchgesetzt, bis dann,

äh, äh, das,

dann, äh, jemand als, äh,

äh, eben, bis, bis Leute das dann halt,

äh, irgendwie dieses Jupyter-Projekt, äh,

also das aus dem IPython, äh,

Interpreter halt, äh, irgendwie rausgewachsen ist, äh,

bis das da implementiert wurde.

Und ich hab jetzt auch letztens gehört, dass jemand, äh,

also den Mathematiker-Autor

gefragt hat

warum das jetzt, warum das eigentlich nicht

Open Source wäre, weil das hätte so

sich doch jetzt irgendwie durchgesetzt und voll toll

und so und das

die Idee war ja vorher schon da, aber

ist unbekannt geblieben und

äh, ja

Steven Waffram hatte glaube ich so

ja, also ich hätte das ja schon gerne als

Open Source irgendwie veröffentlicht, aber das ging damals nicht

weil es keine Distributionsmöglichkeiten

dafür gab, das wurde halt alles irgendwie auf

CDs und DVDs

irgendwie, tja

ja, es ist manchmal

es ist komisch, ne, so irgendwie Idee

es reicht nicht irgendwie, dass eine Idee super ist oder so

sondern es müssen mehrere Sachen zusammenkommen, damit

irgendwas wirklich dann abhebt

und manchmal

ja, kommt

dann, denken Leute, dass irgendwie eine Idee

erst kurz gibt oder so, das gibt sie schon ganz lange

aber die Umstände waren halt nicht

nicht richtig, so dass sie halt

vorher halt noch nicht abheben konnte

und das ist bei diesen

diesen Jupyter-Notebooks ist das halt schon, ich denke, das war halt genau

der richtige Moment und jetzt ist es halt groß geworden

und, ähm, ja

Shiny, let's be bad guys

Ich meine, gerade im Data-Science-Bereich, wo man

schnell viele Dinge ausprobieren

muss, ohne Skripte von Anfang

neu laufen zu lassen

äh, ist natürlich der

Killer-Anwendungszweck für diese Notebooks

Ja

Ja, haben wir noch was hier für

Pandas?

Ja, also Pandas ist ja nie

isoliert zu betrachten

Wir haben ja jetzt ganz viel schon auch über

NumPy gesprochen, über Seaborn und Mudplotlib

und, ähm, die eine

Bibliothek, die ich eingangs noch mit erwähnt hatte

war Studs Models

und die bringt

da im Prinzip noch eine Funktionalität

rein, die ich persönlich auch erstmal nur von

A kannte

und zwar ist das

ähm, Formeln

anzugeben

auf die man dann Fitting machen

kann oder die man auch plotten kann

und diese, diese Formeln

das ist vielleicht erstmal

ungewohnt, wenn man das noch nie gesehen hat

gibt man im Wesentlichen irgendwie an

als, äh, sagen wir mal eine

Geradengleichung y tilde x

also, äh, eine Variable

y, die abhängig ist von

äh, einer Variable x

und als lineare Funktion zu

verstehen ist und

ähm, in diesem

Studs Models gibt's, äh, die

ähm, die Funktionen

von OLS, um diese Formeln abzubilden

die kann man dann auch mit

Pandas Data Frames zusammen benutzen

um wieder Plotting zu machen

also, OLS meinte Optimal Linear

Squares Modeling, oder?

ähm, müsste ja

äh, Ordinary

Ordinary Linear

äh, least squares oder sowas

ich weiß nicht mehr, keine Ahnung

also im Wesentlichen irgendwie, ähm

äh, lineare Gleichungen

an, anzugeben, da gibt's auch noch ganz

viele andere Möglichkeiten, ähm,

das ist nur jetzt der, der einfachste Fall

immer, wo man eine lineare Gleichung

angibt

und, ähm, diese Variablen, die man

da angibt, ähm

die

können in meinem Pandas Data Frame

zu finden sein

und dann kann ich, äh,

das Plotting darüber machen

da kann ich einmal die Trendlinie direkt plotten

ich kann das Fitting direkt über die Pandas Data Frames

machen, also die, die greifen

da irgendwie, also alle diese Bibliotheken

greifen sehr stark ineinander

und da würde es auch gar nicht

reichen, die 2900 Seiten des

Pandas Handbuchs komplett zu lesen

weil man müsste halt auch

noch das NumPy Handbuch komplett lesen

und dann vielleicht das, äh, Matplotlib Handbuch

noch komplett lesen und

ähm

Also falls ihr die 2900 Seiten Handbuch gelesen habt

dann sagt mal Bescheid und schreibt uns eine E-Mail

Ja, äh, genau

ich, ich, äh

Satzmodels, äh, kenne ich auch so

was Zeitreihen, äh, Modellierungs

Geschichten angeht, aber habe ich noch

noch nie so wirklich viel mit, äh, ähm

gemacht, ähm

ich bin eher so bei

Scikit-Learn zu Hause und, ähm

also Maschinen-Learning-Bibliothek

äh, und auch da ist es so, also meistens

bevor man halt irgendwelche, äh, bevor man

Daten irgendwie in Modelle kippen kann

ähm, muss man die halt mit Pandas einmal

aufräumen und dann war es halt so, früher musste man dann

immer noch so, okay, ich hab das jetzt in einem

Data Frame, mhm, wie kriege ich die Daten jetzt

äh, ah, wie kriege ich die Daten

äh, äh, jetzt so

dass ich die an meine Modelle verfüttern

kann, und das war auch mal so ein bisschen

problematisch und das ist jetzt aber auch schon

weiß nicht, letzte oder vorletzte

Version, äh, von Scikit-Learn war

auch kein Problem mehr, weil man jetzt

automatisch auch, weil man jetzt auch nicht

früher brauchten die ganzen

äh, äh, also in Scikit-Learn

heißen die Dinger Estimators, äh,

Estimator API, die haben halt

äh, NumPy-Arrays genommen und jetzt

mittlerweile nehmen die halt auch Pandas, äh, Data Frames

und, äh, die Spalten einmal halten

und wenn man halt irgendwie hinterher gucken

möchte, okay, was ist denn jetzt,

wo gelandet und so, und, äh,

dann kann, kann man da auch mit den Spalten

haben, arbeiten und das ist alles sehr, sehr bequem geworden

und das greift halt auch da wiederum ineinander

und das ist halt eigentlich sehr schön

und was da, also, das ist, das ist

ein, ein großes Data Science Ökosystem

mittlerweile und das ist halt schon toll

äh, ah, dazu fällt mir ein, genau

äh, Sparse

äh, äh, Data ist natürlich auch so ein

Problem, da gibt's, äh, irgendwie

ein Sparse-Type von

Sci, SciPy, das hat man früher

immer verwendet, es gibt ein paar Modelle, die

halt in Scikit-Learn mit, mit Sparsen-Daten umgehen

können, also das sind halt, also Spars heißt

ähm, äh,

Daten, bei denen die

meisten Werte null sind

äh, also zum Beispiel

wenn man, wenn ich jetzt einen Text in, in

oder eine Menge von Texten in

äh, Lektoren

verwandle, dann ist jedes Wort

eine Dimension, sozusagen, und das heißt

ich hab eine Tabelle mit, wenn ich

äh, einen kompletten, wenn ich eine Menge

von Texten, äh, in, in, in

eine Matrix verwandeln, in so eine Feature-Matrix

verwandeln möchte, äh, und dann ist

jedes Dokument ist eine Teile, und, äh,

die Spalten sind halt die Worte, die

drin vorkommen, dann sind halt, die

kommen halt, äh,

die meisten Worte, die es so

gibt, in einem Text aber nicht vor, das heißt, die

allermeisten Werte sind halt null,

und das ist halt blöd, das ist halt dicht zu speichern,

diese ganzen Nullen immer mit zu speichern, weil eigentlich

interessieren die einen ja gar nicht, und

dafür gibt's dann so, so Spars, äh,

Formate, und dann gibt's dann, ja,

CSA, äh,

äh, äh, oder, oder

CSO-Formate in, in, in

Sci-Py, aber das ist

halt auch alles ein bisschen unschön,

und, ähm,

in, äh, jetzt eben der letzten

Release von Pandas war auch ein natives

Spars-Datenformat mit drin,

das hab ich mir aber noch nicht angeguckt, aber das sieht auch

interessant aus, ich weiß auch nicht, ob man das jetzt in, in

Sci-Cat Launcher verwenden kann, aber

das ist, äh, genau, das

wird halt auch noch mit abgedeckt,

und, ähm, ja,

das ist auch noch so ein nicht uninteressantes

Detail.

Gibt's noch andere, äh,

Bibliotheken aus den Web- und Sci-Learn

Starts Models, Sci-Py,

ja, äh,

die ganzen Visualisierungsgeschichten,

ähm,

oh, ja, doch eine, eine Geschichte,

äh, auch noch, äh, wichtig,

wenn man jetzt, äh, tatsächlich, äh,

äh, größere Datenmengen hat, oder halt auch,

äh, Operationen, die lange dauern, und man hatte

irgendwie so eine dicke Kiste mit irgendwie,

äh, weiß ich nicht,

64 Prozessoren, irgendwie

in einem halben Terabyte Hauptspeicher oder so,

äh, und, äh,

man ist so ein bisschen angeödet davon,

dass das irgendwie immer nur auf einem Prozessor läuft,

dann kann man da was tun.

Da gibt's ein auch sehr schönes Projekt, das nennt sich

DARS, ähm,

und damit kann man das halt so ein bisschen

auf mehrere Prozessoren skalieren, also was das,

äh, letztendlich tut, ist,

ein DataFrame halt in viele Kleider

zu zahacken, und dann halt, äh,

die Operationen halt

auf Prozessoren zu

verteilen, und dann halt das hinterher wieder zusammenzuführen,

aber es kann halt

komp-, also, ich hab mehr oder weniger

beliebige Compute

Drafts kann man da irgendwie angeben,

so, es ist halt, äh,

einfache Dinge sind halt einfach

damit zu parallelisieren, wenn man komplizierte Sachen

machen möchte, dann muss man dann auch so ein bisschen nachdenken

und dann halt eventuell, äh,

sich überlegen, wie man das halt ausgeführt kriegt, aber,

äh, im Grunde

funktioniert das so, man hat halt so eine Deferred

API, man sagt halt, was man tun möchte, und dann am Schluss

sagt man irgendwie jetzt Collect oder so,

und dann, äh, oder, äh,

ich glaub, weiß gar nicht, also,

man ruft halt irgendwie eine Funktion auf, die

sagt so, und jetzt rechnet das halt alles mal aus, und dann

wird das halt auf die unterschiedlichen Prozessoren verteilt,

wird alles ausgerechnet, und am Schluss hat man

das alles wieder in einem DataFrame, und, ähm,

die Geschwindigkeit

hat sich dann, wenn man Glück gehabt hat,

halt irgendwie linear, äh,

ähm, ist dann

linear skaliert, und man braucht nur noch ein Sechzigstel

der Zeit, oder so, ja.

Ähm, genau.

Das ist auf jeden Fall auch ein Ding,

was man sich auch angucken sollte, also,

was, was zu Skalierungsgeschichten angeht, ja, wenn die Datenmengen

dann noch viel größer sind, so, oder dass sie halt

nicht mehr in den Hauptspeicher auf einer Maschine passen, oder so,

äh, dann

muss man sich nochmal was anderes überlegen, dann, äh,

bleibt eigentlich nur, dass man das dann,

dass man irgendwie dann in Richtung

Spark geht, oder sowas.

Aber diesen, diesen Fall hat man fast nie, äh,

weil mittlerweile,

ja, die Maschinen so viele Hauptspeicher haben, dass das irgendwie

kaum vorkommt.

Wenn's nicht mehr in den Hauptspeicher passt, Geld dagegen

werfen und mehr Hauptspeicher besorgen.

Ja.

Ja, wenn wir schon beim halben Terabyte

angekommen sind, da ist ja schon noch ein bisschen Platz.

Ja.

Geht eine ganze Menge rein.

Ja, so, Skalierung hatten wir jetzt auch

so ein bisschen. Wir hatten noch, glaube ich, dieses, äh,

äh, Wes McKinney, hast du kurz erwähnt,

da hatten wir, glaube ich, einmal in unserer Weihnachtsfolge

dieses Ten Things I Hate About Pandas, irgendwie.

Ah, ja, ja, ja, genau.

Ähm, ich weiß nicht, ob da noch was rauskam.

Ja, der, ähm,

also, er arbeitet

halt hauptsächlich an dem Arrow-Projekt,

dass, da geht's darum, eine neue Grundlage zu schaffen,

äh, und zwar nicht nur

für Python, sondern, ähm, für

äh, alle anderen

Programmiersprachen auch, weil man hat halt das Problem, dass man

man möchte eigentlich

nicht, wenn man Daten hat, die groß sind,

und, äh, man möchte die nicht

mehrfach im Hauptspeicher halten, aber momentan kommt man nicht drum rum,

wenn man jetzt, äh,

beispielsweise in R

und in Python irgendwie auf Daten

irgendwie was machen möchte, dann muss man die

halt irgendwie erst, wenn man die jetzt in Python

hat, serialisieren, irgendwo hin auf die Platte schreiben,

dann in R wieder einlesen und

hat sie dann, im Endeffekt zahlen wir im Hauptspeicher, was natürlich

irgendwie doof ist, äh, und

das Projekt ist sozusagen, äh,

äh, äh,

stellt halt sozusagen Schnittstellen für alle Programmiersprachen

bereit, aber die Daten selber

werden nur, äh, im Hauptspeicher

an einer Stelle gehalten, da kann man mit allen Sprachen,

also, was weiß ich, von Java bis C,

äh, C++, Rust,

äh, was auch immer, irgendwelche Leute schreiben gerade eine Query Engine

für Arrow in, in Rust,

äh, Python A, äh, darauf zugreifen

und, äh, da irgendwelche

Manipulationen drauf machen,

äh, ohne dass es halt dann

jedes Mal eine Kopie macht. Und das ist

natürlich auch eine sehr, sehr interessante Geschichte,

weil das ist eben,

davon hatten wir jetzt ja auch schon ein paar Mal,

äh, irgendwie momentan so ein, wenn man mit so

Big Data-Geschichten, Hadoop-Clustern zu tun hat,

so ein Problem, dass man da nicht so gut an die

Daten rankommt, ähm,

und, ähm,

ja, das war auch eines der ersten

Geschichten, die Arrow gemacht hat, war, äh,

Parquet

Fileparser, äh,

zu implementieren, sodass man halt zumindest

die Files, äh, in denen die Daten liegen,

halt irgendwie lesen kann.

Ähm, ja, und, äh,

ähm,

das, äh, das ist, das ist,

glaube ich, also mittlerweile

funktioniert das irgendwie fast allen Sprachen,

dass man das halt sozusagen als,

äh, ähm,

äh, Ersatz für NumPy auch nehmen

kann, äh, äh,

und, dass das, also eine, eine

Geschichte ist so, dass, dass in, in,

in Pandas das nicht so wirklich schmerzfrei

NumPy aushauschen kann, weil das halt,

äh, viele Sachen in, in Pandas

beruhen halt darauf, dass NumPy so ist, wie es ist.

Das wird halt schwierig. Da gibt's auch, äh,

eine Serie von Artikeln zu,

nennt sich Pandas 2.0 irgendwie,

wo man dann halt überlegt, dass man die API

so nicht abwärtskompatibel ändert.

Das, das hat

Wesmerkini 2015 ein paar Artikel

geschrieben. Bisher ist da nicht so viel

passiert, aber man müsste, wenn man jetzt komplett auf Arrow umsteigen

wollte und so, dann müsste man da wahrscheinlich, äh,

irgendwie viel auch an dem Frontend

von Pandas ändern und das wird dann

nochmal, nochmal schwierig.

Ähm,

und, äh, ist es so, dass, äh,

was auch noch in, in nächster Zeit

bei Arrow ansteht, ist, es gibt

so einen großen, so ein großes

Kluft, äh, zwischen dem, was halt

im Datenbankenbereich passiert ist

und dem, was halt in, äh,

im Data Science-Bereich passiert ist und

da geht's auch darum, das so ein bisschen

anzugleichen. Also, was man zum Beispiel nicht hat, ist eine

Query-Engine für Arrow. Also, das wird, da

wird halt grad geschrieben. Also, nächsten,

ich glaub, das ist das Projekt so für die nächsten drei, zwei, drei Jahre

in Arrow ist halt so, wer

doch schickt, da auch so eine SQL-Engine

drauf zu haben, sodass man halt Arrow

auch als, ja,

Ersatz oder Alternative

zu Impala oder sowas halt auf Clustern

verwenden könnte.

Weil das ist im Grunde auch eine, äh, SQL-Engine

äh, in C geschrieben,

die halt, ähm,

äh, äh, die halt auf so einem

Hadoop-Cluster laufen kann. Ähm,

und dann

kann das aber viele der Sachen, die man halt in so

Datenbanken hat, auch noch nicht. Also, ganzen

Indiz-Index-Geschichten und so

und, ähm,

ja,

da, da, da, da, da läuft

das aber irgendwie so hin. Also, ich meine, wenn man jetzt

sich so eine ideale Zukunft mal ausmalen

würde, könnte,

würde ich sagen, wäre das eigentlich sowas, man hat, äh,

äh, äh, irgend so ein

In-Memory-Storage, äh,

also In-Memory-Storage-Arrow oder so.

Man hat, äh, irgendwie

als Frontend etwas Pandas-ähnliches.

Ähm, es gab da auch schon

einen, ähm, Ansatz von, äh,

eben auch wieder von West McKinney, das ist so ein zentraler

Figur, äh, das nennt sich Ibis, das

Projekt, äh, wo es darum geht,

eine, ein Superset

von SQL zu haben,

das möglichst Pandas-ähnlich ist,

ähm, mit dem man aber all das

machen kann, was man sonst auch mit SQL-Datenbanken macht.

Und, ähm,

ja, das halt auch so eine, so eine

Default-Execution-Geschichte macht,

dass man halt hinterher nur sagt, äh, irgendwie man, man

definiert die ganzen Transformationen, Abfragen,

die man da macht und dann am Schluss sagt man, so, und jetzt ausführen

und dann geht das quasi an so ein

Cluster raus. Und das ist,

Und mit SQL auch alles. SQL ist sowieso blöd, weil diverse Geschichten gehen halt mit SQL nicht so richtig gut. Also man kann auch Tests für SQL schreiben, aber das ist alles ziemlich hässlich. Und man kann auch nicht so wirklich Code sharen. Also es gibt nicht so etwas wie Funktionen, aber wenn man ähnliche Abfragen macht in unterschiedlichen Kontexten, dann kopiert man oft die Statements und so. Das ist alles nicht so schön.

Und das ist halt mit so einer Notation wie in Ibis halt deutlich besser, weil da kann man das einfach in Funktionen packen und die Funktionen woanders halt verwenden und so. Und das geht halt schöner.

Ja, und das dann halt auch nochmal ändern. Bei einem SQL-Statement könntest du das ja auch in eine Funktion packen, aber das Problem ist, dann hast du halt genau dieses Statement. Du kannst das Statement kaum ändern. Außer du nimmst halt ein ORM, aber ORM ist dann auch wieder eigene Probleme.

Und ja, also ich würde mir eine ideale Welt, würde ich mir so vorstellen, also für kleine Datenmengen funktioniert man das.

Das ist ja schon super. Bis auf diese kleinen Hässlichkeiten wie eben NAN und diese Block-Storage-Geschichten. Aber das kriegt man ja alles in den Griff mit der Array-Extension-API.

Aber für große Datenmengen, dass man halt so etwas Ähnliches hat wie Spark oder auch der DOOP, also man hat einen großen Cluster, wo dann in Memory halt die ganzen Daten in Apache Arrow quasi liegen und man dann auf Arrow aufsetzend irgendwelche Query-Execution-Engines hat, die man füttert.

Von einem Pandas-ähnlichen Frontend aus, wo man dann halt definiert, was man gerne hätte und das dann halt irgendwie auf den Cluster verteilt wird.

Also man hat irgendwie so eine Art Array-Datenbank, verteilte In-Memory-Array-Datenbank mit so einer vielleicht Intermediate-SQL-ähnlichen Query-Engine hat, aber so als Frontend sowas wie Pandas.

So dass man dann halt auch wirklich große Datenmengen einfach so Transformation machen kann wie in Pandas.

Das wird vielleicht noch ein paar Jahre dauern, aber das wäre so das, was ich mir wünschen würde, was passiert.

Und dass man vielleicht irgendwann dann tatsächlich Pandas 2.0 hat, wo man nochmal komplett neu irgendwie diese ganzen Geschichten, die in der Kombination mit einem API halt nicht so toll sind, gelöst werden.

Aber das kann auch sein, dass das nie passiert, weil so viele Leute jetzt Pandas verwenden.

Ja, ich weiß nicht, von meiner Seite, ich wüsste jetzt spontan nichts mehr.

Wenn ihr mich jetzt fragen würdet, fragt doch mal.

Was sind so die drei wichtigsten Sachen, die ich mit nach Hause nehmen muss, wenn ich mal mit Pandas anfangen möchte?

Was sind die wichtigsten drei Sachen, die du mit nach Hause nehmen musst, lieber Simon, wenn du mal mit Pandas anfangen möchtest?

Ich würde sagen, Describe, Plot und Apply sind so die drei ganz zentralen Dinge, die man sich angucken möchte, weil da kann man fast alles schon mitmachen.

Ja, okay.

Ja, ich würde sagen, Read CSV sollte man sich auch mal angucken.

Ja, okay, also Datenimport, ja.

Aber sonst, ja, nee, klar, doch.

Ja, schön, schön.

Ja.

Schöne Strukturierung mit unseren Daten über Pandas, ich finde es hervorragend.

Ja, dann würde ich sagen, sind wir mit dem Pandas-Thema tatsächlich für heute soweit durch.

Und vielleicht machen wir noch so ein bisschen Abschluss und erzählen noch ein bisschen was von euren Lieblings-Picks oder sowas.

Ja.

Ja.

Erstmal.

Sieben, möchtest du anfangen? Irgendwie hast du einen Lieblings-Pick, irgendein Modul, weißt du?

Muss ich kurz einen Moment drüber nachdenken.

Bitte, dann ist nicht offen zuerst.

Ja, ich überlege gerade, ob ich irgendwas Pandas-mäßiges habe, aber ich fürchte, nee, ich, was man sich mal angucken kann, ist eine Bibliothek namens Alkali.

Das ist so ein Django-ORM-Style-Ding, aber für flache Files.

Und das ist halt auch ganz, ganz nett, wenn man jetzt irgendwie zum Beispiel irgendwelche, wenn man halt Django kann zum Beispiel und den ORM da schon so ein bisschen damit schon so Sachen gemacht hat, dann kann man halt auch da auf CSVs oder so halt Dinge machen, die so ähnlich sind.

Also das ist quasi so die umgekehrte Richtung. Also wahrscheinlich wäre es praktischer, wenn man Pandas kennt, das halt mit Pandas zu machen, aber wenn man das nicht kann, dann kann man halt auch irgendwie, wenn man Daten als CSV ausgeschrieben hat oder so, damit irgendwie wie auf einer Datenbank.

Das fand ich ganz witzig, die Idee. Deswegen würde ich das mal, das mal picken, aber ja.

Ja, ich würde tatsächlich Pickel nehmen. Ich weiß nicht, hatten wir das schon mal oder so? Ich fand das total super, dass man da so Python-Objekte speichern kann.

Stimmt, nee, das hatten wir noch nicht. Ist auch Teil der Standard-Bibliothek und genau, daher muss man nichts zusätzlich installieren. Das ist super, das, ja.

Kann man eigentlich auch mit DataFrames machen, oder? Ich weiß jetzt nicht, wie schnell sowas geht und ob man das nicht lieber in einer Datenbank dann speichert, aber.

Doch, kann man mit DataFrames auch machen. Ist auch tatsächlich ziemlich schnell.

Wenn man keine Lust mehr hat und wieder anfangen muss, immer an der gleichen Stelle zu debuggen, dann lädt man einfach dann irgendwann den Pickel ein oder so.

Ja, ja.

Und spart sich dann immer die Zeit beim Ausführen.

Ja, also genau, das ist, nee, das ist tatsächlich, wenn man, also ich finde DataFrames zu picklen, es funktioniert ganz gut.

Also man muss, man muss vielleicht dazu sagen, man muss dem Ganzen vertrauen.

Also wenn man, wenn einem jemand so ein Pickel-File gibt, ist das so, hier, so ein, wie war das bei der Sesamstraße immer so, macht so ein French-Code auf, so.

Willst du ein Pickel-File von mir realisieren?

Genau, dann lieber nicht machen, weil das kann, führt halt beliebigen Code aus und ja, das ist vielleicht nicht so schön.

Aber wenn man das selber generiert hat, dann ist das vielleicht okay.

Und dann ist es auch sehr schnell.

Also.

Da kann man durchaus, also wenn die, wenn die I.O., ich habe das nicht an die Grenzen, oder war da, nee, ich glaube, ich habe das tatsächlich nicht, nicht an die Grenzen bringen können, sondern das war immer so schnell, wie halt das Plattensystem drunter war.

Also ich habe damit auch schon, da ging halt so Gigabyte pro Sekunde, geht halt durch.

Also bei CSV ist, CSV ist richtig langsam.

CSV ist halt so, wenn es schnell ist, ein paar 10 Megabyte pro Sekunde, was halt, wenn du ein paar Gigabyte große Files hast, dann dauert das.

Und Pickel ist halt so, selbst wenn die Files Gigabyte groß sind, kannst du dann das halt, wenn das I.O.-System, das du hast, schnell ist, dann dauert das halt, zwei Sekunden ist das da.

Und das ist natürlich schon schön.

Es gibt andere Formate für, gerade um Daten wie in DataFrame, man sehr oft hat, irgendwie zu speichern, HDF5 zum Beispiel, oder Feather gibt es da auch eine Library, wo das auch veraltet eigentlich.

Heute würde man eher dann eben Arrow verwenden und dann ein paar K-Files lesen und schreiben.

Das ist auch sehr schnell.

Ähm, HDF5 ist, geht so, ist ein bisschen, ist nicht ganz so schnell, aber, ja, lassen wir mal, gibt es sonst noch irgendwelche Formate, die interessant sind?

Es gibt dieses NetCDF4, das ist die Weiterentwicklung von HDF5 und, ähm, da hat man dann...

NetCDF4 ist die Weiterentwicklung von 5?

NetCDF4, ähm, das ist schon die vierte Iteration von NetCDF, aber irgendwann sind die wohl aus HDF entstanden.

Wie das genau zustande gekommen ist, weiß ich auch nicht.

Äh, die haben dann so, so Späße wie, ähm, man kann direkt FileBlobs angeben und dann über mehrere Files eine Variable öffnen.

Äh, das ist ganz spannend, wenn man sehr große, äh, Datensätze als Chunks auf, auf seiner Festplatte hat.

Ähm, aber technische Details dazu weiß ich jetzt auch nicht.

Tja, Tim, hast du noch ein Lieblingsmodul?

Ja, ich hab ja eben schon gesagt, ich mag Plotly unheimlich gerne, aber wenn man Plotly grafen,

erstellen möchte, dann muss man irgendwie so ein ganz tief verschachteltes Data-Dictionary bauen

und dann ein Layout-Dictionary bauen und super viel konfigurieren.

Und Matplotlib geht halt schnell.

Und, ähm, Plotly hat kürzlich noch ein Tool rausgebracht, Matplotlib-to-Plotly-Grafen,

wo man, das, das funktioniert noch nicht perfekt, aber so, so die Basis-Grafen wie Boxplots oder Scatterplots oder sowas

kriegt man damit in Matplotlib ganz schnell definiert.

Irgendwie mit zwei, drei Zeilen Code und dann mit einer Zeile konvertiert in Plotly-Grafen.

Und dann hat man direkt dieses interaktive, ähm, man hat Mouse-Hover und man kann zoomen und, und so.

Das, das fand ich ganz schön, ist aber noch, ähm,

In den Kinderschuhen.

Ist noch in den Kinderschuhen, ja.

Ja, aber schön, das spannend zu verfolgen, ja.

Cool.

Ja.

Habt ihr noch irgendwas, was ihr loswerden wollt, irgendwie das, euer Modul der Woche, oder sind wir damit durch und, äh?

Loswerden.

Nö, ich glaub damit.

Achso, vielleicht, ja, äh, wollen wir, äh, genau, nächste Woche ist vielleicht ganz interessant, wenn, äh, irgendjemand da ist, der, der zuhört, zufällig, aber ich glaub's, glaub's wahrscheinlich eher nicht, äh, so, Podcast-Konferenz in Köln.

Ja, die Subscribe.

Bei uns genau um die Ecke ist, da gehen wir auch mal hin.

Genau, und da wüsstet ihr uns finden.

Und, äh, genau, da könnte man, äh, uns, äh, treffen, wenn man, wenn man wollte, also.

Ja, das.

Wer möchte, kann einfach eine Mail an uns fragen, ja.

Das, das kommt in den Veranstaltungen bei Ihnen, genau, aber ihr könnt uns sehr gerne treffen, tatsächlich.

Wir wissen noch nicht genau, ob wir Freitag und Samstag und Sonntag da sind, aber, äh, auf jeden Fall am Samstag und am Sonntag wird ihr das wahrscheinlich, äh, da sehen.

Das, äh, besprechen wir noch genauer.

Ja, kommst du.

Äh, ist ja immer mal wieder Django zur Sprache gekommen.

Anfang April ist die DjangoCon in Kopenhagen.

Oh, ja.

Vom 10. bis zum 14. April ist es, glaub ich.

Sieht man dich da?

Äh, mich nur am 9. April.

Äh, da ist das Django Girls Camp.

Einen Tag Django, ähm, äh, lernen.

Ja, ja.

Äh, da fliege ich kurz hin als Mentor.

Ich habe leider für die Konferenz selber keine Zeit.

Ja, ja, okay, super.

Ja, äh, wolltest du noch was zu, zu dem Cast sagen, zum Django-Cast, Jochen, oder machen wir das von anders?

Äh, ähm, ja, also da, letztens gab es irgendwie so ein, so ein, äh, Mail von Apple, wo sie gesagt haben, also, wir werden euch jetzt nicht direkt auslisten, äh, irgendwie, aber ihr solltet dann mal vielleicht irgendwie ein paar Sachen an eurem Feed ändern, dann muss ich jetzt nochmal rein.

Zum Beispiel sowas wie Episoden, Nummern sollten nicht im Titel sein und so.

Das machen aber alle, äh, ich auch.

Können wir doch nochmal irgendwas dran tun und, ähm, genau, ich, äh, ja, wir machen da auch so einen kleinen Workshop, äh, irgendwie auf dem, auf der Subscribe und, äh, müssen wir auch noch ein bisschen was für tun.

Und da wäre es natürlich auch interessant, was dann noch so, also, was ich jetzt schon implementiert habe, ist, dass man jetzt nicht mehr das Django-Admin-Interface braucht, um, äh, irgendwie Audio-Files hochzuladen.

Ähm, aber, ja, mal gucken.

Was dann noch so da dazukommt und dann, was, was super dringend ist, äh, ist irgendwie, dass die Dokumentation mal so ein bisschen besser wird und so.

Mal gucken, ob ich die drei Zeilen zuschraffe.

Ja.

Also mindestens so, so den, den First Step oder so.

Ja.

So den, den großen Struggle.

Ja, wenn ihr irgendwie so Anfänger seid wie ich, dann kommt ihr da bestimmt noch irgendwo dran.

Ja.

Ja, ansonsten.

Ja, dann vielen Dank, dass ihr zugehört habt heute wieder.

Dass ihr eingeschaltet habt.

Wie auch immer, wann auch immer, wo auch immer.

Mhm.

Lasst uns das übrigens wissen.

Schreibt eure E-Mails, Kommentare an hallo-at-python-podcast.de und, ja, kippt uns.

Äh, weiter an alle Leute, die Python interessiert in eurer Nähe, erzählt eure Freunden, Kommilitonen.

Äh, ja, das kann man vielleicht auch, also was man auch machen kann, ist, äh, auf iTunes bewerten, wenn das irgendwie, äh, weil, also das hilft natürlich stark.

Ähm, aber, äh, genau, ähm, ansonsten, ja.

Ja, genau.

Sagt Bescheid.

Erstmal, äh, hört uns gerne, vor allen Dingen wieder und so.

Bleibt uns gewogen, wie man so schön sagt.

Und bis zum nächsten Mal.

Bis zum nächsten Mal.

Tschüss.

Vielen Dank für die Einladung.

Tschüss.

Tschüss.

Tschüss.