WEBVTT

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

00:00:05.120 --> 00:00:10.840
Heute geht es um Pandas. Ja, was machen wir eigentlich? Wir sind, wie fast immer, in Jochens Hintergarten.

00:00:10.840 --> 00:00:14.200
Ich bin der Dominik, dabei ist wie immer der Jochen und unser Gast, der Simon.

00:00:14.200 --> 00:00:22.500
Ja, hallo Simon. Vielleicht kannst du dich einfach mal kurz vorstellen, bevor wir über das Thema reden.

00:00:22.500 --> 00:00:33.760
Klar. Ja, ich bin Simon. Ich bin von Haus aus Biologe, immer mit Interesse für Informatik und Spieleentwicklung gesegnet gewesen

00:00:33.760 --> 00:00:41.660
und habe das dann irgendwie auch zu meinem Beruf gemacht. Also ich habe nach meinem Biostudium ein bisschen geforscht in der Bioinformatik.

00:00:41.660 --> 00:00:47.480
Da ging es dann viel um Datenanalyse von DNA-Sequenzen und so Dingen.

00:00:47.480 --> 00:00:52.220
Game of Life. Game of Life, ja, quasi. Nur in echt echt.

00:00:52.500 --> 00:01:00.520
Ja, genau. Und zusammen mit dem Wissen, was ich daraus getragen habe und meinem Interesse an Informatik und Spieleentwicklung

00:01:00.520 --> 00:01:09.080
mache ich heute als selbstständiger IT-Trainer Trainings für Game Engines und Trainings für Softwareentwicklung

00:01:09.080 --> 00:01:11.560
und parallel noch ein paar Softwareprojekte.

00:01:11.560 --> 00:01:14.840
Das Gaming haben wir uns ja schon ein bisschen unterhalten. Das machen wir auch nach der Folge ein bisschen intensiver.

00:01:14.840 --> 00:01:17.200
Aber heute soll es ja um Pandas gehen. Genau, heute...

00:01:17.200 --> 00:01:22.420
Deswegen, ja, super, dass du das auch ganz viel mit deinem zu tun hattest in deinem Fach.

00:01:22.500 --> 00:01:23.140
In deiner Wissenschaft.

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

00:01:29.500 --> 00:01:37.320
Wenn ihr Fragen, Anmerkungen habt, Lobkommentare, Hass, dann schreibt uns doch an hallo-podcast.de.

00:01:37.320 --> 00:01:40.780
Ihr findet natürlich die Links und alle zusätzlichen Informationen wie in den Shownotes.

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

00:01:48.100 --> 00:01:52.480
Also seid doch bitte so nett und schickt uns einfach per E-Mail eure Do's und Don'ts.

00:01:52.500 --> 00:01:57.780
Das wäre super. Dann schneiden wir das ein bisschen zusammen und fragen euch in einer der nächsten Folgen bestimmt irgendwann mal danach.

00:01:57.780 --> 00:02:04.780
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.

00:02:04.780 --> 00:02:09.220
Und das ist übrigens vielleicht ganz interessant.

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

00:02:15.500 --> 00:02:16.780
Was ich ein bisschen überraschend finde.

00:02:16.780 --> 00:02:18.600
Ich hätte jetzt auch erwartet, dass es eher ein bisschen runtergeht.

00:02:18.600 --> 00:02:21.360
Vielleicht müssen wir noch mehr so Buzzword-Bingo-Sachen machen.

00:02:22.500 --> 00:02:24.740
Nein, wir machen das natürlich für alle unsere Hörer.

00:02:24.740 --> 00:02:26.980
Vor allen Dingen für die, die sich dafür wirklich interessieren.

00:02:26.980 --> 00:02:31.260
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.

00:02:31.260 --> 00:02:35.520
Oder ihr wisst ja, morgens, abends, nachts, beim Aufstehen im Flugzeug könnt ihr immer hören.

00:02:35.520 --> 00:02:39.940
Ja, bevor wir in das Thema gehen, ist weiterhin noch ein paar News aus der Szene.

00:02:39.940 --> 00:02:41.300
Und zwar gab es so ein bisschen was Neues.

00:02:41.300 --> 00:02:42.580
Daubig.

00:02:42.580 --> 00:02:45.080
Python 3.8, zweite Alpha.

00:02:45.080 --> 00:02:45.900
Ja.

00:02:45.900 --> 00:02:50.060
Ja, da gab es so ein paar coole neue Sachen mit Shared Memory for Multiprocessing.

00:02:50.060 --> 00:02:50.680
Jochen, was ist das denn?

00:02:50.680 --> 00:02:52.480
Ja, das ist eine gute Frage.

00:02:52.500 --> 00:02:52.620
Das ist eine gute Frage.

00:02:52.620 --> 00:02:55.600
Wann habe ich denn das da reingeschrieben?

00:02:55.600 --> 00:02:57.240
Oh, ja, das ist auch schon ein bisschen her.

00:02:57.240 --> 00:02:58.800
Ah doch, ja, alles klar.

00:02:58.800 --> 00:03:06.000
Das war ja immer so ein Problem.

00:03:06.000 --> 00:03:14.820
Also man muss ja, wenn man jetzt über mehrere Prozessoren Berechnungen verteilen will in Python, das auf mehreren Prozessen machen.

00:03:14.820 --> 00:03:22.440
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.

00:03:23.320 --> 00:03:38.460
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.

00:03:38.460 --> 00:03:45.180
Und eben so viele üblicherweise, wie man Prozessoren hat und ruft jetzt eine Funktion auf jedem Prozessor sozusagen auf.

00:03:45.180 --> 00:03:48.220
Also man hat jetzt eine Liste von Dingen, die man irgendwie abarbeiten möchte.

00:03:48.220 --> 00:03:49.760
Man hat eine Funktion, die das dann halt tut.

00:03:49.760 --> 00:03:52.480
Dann sagt man, okay, starte mit diesem.

00:03:52.500 --> 00:03:54.780
Job irgendwie diese Funktion.

00:03:54.780 --> 00:04:03.920
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.

00:04:03.920 --> 00:04:08.080
Also wie man im Supermarkt ganz viele verschiedene Kassen aufmacht und macht ein paar Kassen auf einmal auf.

00:04:08.080 --> 00:04:08.700
Ja, ja, ja.

00:04:08.700 --> 00:04:17.600
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.

00:04:17.600 --> 00:04:18.640
Das ist jetzt ein anderer Prozess.

00:04:18.640 --> 00:04:21.500
Das heißt, man kann nicht einfach das in, also.

00:04:22.500 --> 00:04:24.580
In Code ist es schon so, dass man einfach einen Funktionsaufruf macht.

00:04:24.580 --> 00:04:30.840
Aber was dann im Hintergrund passieren muss, ist ja irgendwie, dass die Daten serialisiert werden.

00:04:30.840 --> 00:04:32.980
Dann müssen sie irgendwie durch die Gegend geschoben werden.

00:04:32.980 --> 00:04:35.080
Und dann auf der anderen Seite wird der deserialisiert werden.

00:04:35.080 --> 00:04:36.100
In so kleine Häppchen.

00:04:36.100 --> 00:04:41.780
Und dass alle, die ganze große Bestellung an verschiedenen Kassen abgearbeitet wird, um danach wieder in der richtigen Reihenfolge im Einkaufskorb zu landen.

00:04:41.780 --> 00:04:43.920
So ungefähr?

00:04:43.920 --> 00:04:46.480
Ja, man kann.

00:04:46.480 --> 00:04:47.340
15 Fehler wieder.

00:04:47.340 --> 00:04:51.380
Nein, ich glaube, ich weiß nicht, ob die Analogie da an der Stelle so gut passt.

00:04:52.340 --> 00:04:53.480
Ich weiß auch nicht genau.

00:04:53.480 --> 00:04:57.360
Ja, man muss es.

00:04:57.360 --> 00:05:08.840
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.

00:05:08.840 --> 00:05:10.760
Und mit jedem Einkaufswagen einzeln zu einer Kasse.

00:05:10.760 --> 00:05:12.020
Und.

00:05:12.020 --> 00:05:14.880
Muss die irgendwer umpacken.

00:05:14.880 --> 00:05:16.140
Dann muss man die umpacken.

00:05:16.140 --> 00:05:22.180
Und das ist halt alles halbwegs aufwendig und kann halt auch zu Problemen führen, wenn die Daten sehr groß werden.

00:05:22.180 --> 00:05:26.460
Zum Beispiel kann es sein, dass irgendwelche Dinge dazwischen halt aussteigen und das ist alles nicht so schön.

00:05:26.460 --> 00:05:30.700
Und es ist halt unter Umständen auch etwas, was Dinge langsam macht.

00:05:30.700 --> 00:05:33.800
Und jetzt geht es aber transparent mit Chat Memory sozusagen.

00:05:33.800 --> 00:05:35.380
Das heißt, man hat halt die Daten.

00:05:35.380 --> 00:05:36.900
Genau, das ist ja auch so ein Problem.

00:05:36.900 --> 00:05:41.420
Wenn man jetzt Daten serialisiert und deserialisieren muss, dann kopiert man sie damit natürlich auch.

00:05:41.420 --> 00:05:47.460
Das heißt, wenn man große Daten hat, die jetzt vielleicht insgesamt nur einmal in den Hauptspeicher passen, aber nicht zweimal.

00:05:47.460 --> 00:05:50.600
Wenn man sie kopiert, dann hat man sie halt zweimal drin und dann hat man zu wenig Hauptspeicher.

00:05:50.600 --> 00:05:51.220
Ist ja auch blöd.

00:05:52.020 --> 00:05:58.180
Und was halt schon immer viel, viel cooler war, ist, wenn man halt einfach Shared Memory reservieren kann

00:05:58.180 --> 00:06:02.380
und sagt dann den einzelnen Prozessen, gibt denen nur einen Pointer auf diese Shared Memory und sagt so,

00:06:02.380 --> 00:06:05.000
da sind deine Datenstrukturen drin.

00:06:05.000 --> 00:06:10.420
Also das heißt, jemand nimmt sich einfach so einen Unterkorb aus dem Einkaufswagen raus, der schon fertig ist

00:06:10.420 --> 00:06:13.080
und der Einkaufskorb, der fährt dann automatisch auf das richtige Förderband.

00:06:13.080 --> 00:06:19.800
Ja, nee, aber das ist, ja, mal überlegen, ob man diese Analogie da noch irgendwie...

00:06:19.800 --> 00:06:21.600
Ja, Shared Memory, ein eigener Teil der Einkaufswagen.

00:06:21.860 --> 00:06:26.040
Das wäre der eine Einkaufswagen, der an allen fünf Kassen steht.

00:06:26.040 --> 00:06:30.040
Jede Kasse greift nur auf einen Teil von dem Korb selber zu.

00:06:30.040 --> 00:06:31.800
Stimmt, wir haben eine Ruhre von Kassen.

00:06:31.800 --> 00:06:33.180
Die Kasse ist oben, unten, rechts und links.

00:06:33.180 --> 00:06:34.160
Man kann einfach eingreifen.

00:06:34.160 --> 00:06:34.960
Das ist schön, ja.

00:06:34.960 --> 00:06:37.260
Genau, so könnte man sich das vorstellen, ja.

00:06:37.260 --> 00:06:43.580
Und das heißt, man hat halt, wenn man jetzt Daten hat, die so gerade in den Hauptspeicher vielleicht passen,

00:06:43.580 --> 00:06:45.440
dann kann man die trotzdem auf mehreren Prozessen verarbeiten.

00:06:45.440 --> 00:06:49.120
Und das macht natürlich Multiprocessing auf Python deutlich attraktiver.

00:06:49.120 --> 00:06:51.840
Und das ist irgendwie eine ziemlich coole Geschichte, wenn die jetzt in drei abkommen,

00:06:51.860 --> 00:06:52.240
und...

00:06:52.240 --> 00:06:53.280
Dann wird Python ja schneller.

00:06:53.280 --> 00:06:55.740
Ja, also, oder es wird einfacher damit.

00:06:55.740 --> 00:06:58.220
Also, man kann ja auch, das konnte man auch sowieso schon immer machen.

00:06:58.220 --> 00:07:02.320
Man kann ja auch einfach Shared Memory reservieren, da Dinge reinpacken.

00:07:02.320 --> 00:07:09.180
Da gibt es übrigens auch ein schönes Modul in der Standardbibliothek, das heißt Struct.

00:07:09.180 --> 00:07:10.200
Struct.

00:07:10.200 --> 00:07:18.060
Genau, damit kann man zum Beispiel Daten halt so binär irgendwie in den Hauptspeicher schreiben.

00:07:18.060 --> 00:07:21.840
Und das zum Beispiel so tun,

00:07:21.860 --> 00:07:23.420
dass das halt C-Structs sind.

00:07:23.420 --> 00:07:24.660
Ah.

00:07:24.660 --> 00:07:29.720
Und dann kann man das halt, also das ist halt so etwas, so haben wir das früher halt gemacht,

00:07:29.720 --> 00:07:33.240
wenn wir Daten nicht so groß waren, dass man da nicht einfach irgendwas mit tun konnte.

00:07:33.240 --> 00:07:37.380
Das heißt, man hat halt irgendwie einen Shared Memory Bereich,

00:07:37.380 --> 00:07:42.720
und den schreibt man halt irgendwie per Struct irgendwie, sozusagen C-Struct Daten irgendwie rein,

00:07:42.720 --> 00:07:46.400
und hat dann Python-Prozesse, die wiederum einen Pointer auf diese Shared Memory kriegen,

00:07:46.400 --> 00:07:51.480
und die dann halt wieder ein C-Modul haben, das dann halt irgendwas mit den Daten macht und so.

00:07:51.480 --> 00:07:53.520
Und dann geht das auch schon, aber das ist halt viel Handarbeit.

00:07:53.520 --> 00:07:58.000
Und jetzt kriegt man das quasi so geschenkt, und das passiert dann dann automatisch, und das ist halt schon sehr nett.

00:07:58.000 --> 00:07:58.740
Cool.

00:07:58.740 --> 00:07:58.940
Ja.

00:07:58.940 --> 00:08:02.600
Ich hörte ja auch gerade diese Hintergrundmusik, das ist so ein bisschen wie in Battlestar Galactica, ne, diese

00:08:02.600 --> 00:08:05.800
Ah, super.

00:08:05.800 --> 00:08:06.920
Keine Opelide.

00:08:06.920 --> 00:08:09.560
Ja, also die nächsten News aus der Szene.

00:08:09.560 --> 00:08:15.400
Doppelte Keys, gab ein Post von Guido irgendwo, der hat irgendwas geshared.

00:08:15.400 --> 00:08:21.000
Es gibt ein neues Python-Enhancement-Proposal, das ist eine ganz interessante,

00:08:21.340 --> 00:08:28.060
äh, äh, äh, Geschichte vorschlägt, und zwar geht's darum, dass man halt, äh, für Dicts vielleicht auch die, äh,

00:08:28.060 --> 00:08:34.220
äh, also Plus und Minus als Operatoren, äh, haben möchte, sodass man halt sagen kann, irgendwie Dict A plus Dict B,

00:08:34.220 --> 00:08:41.720
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,

00:08:41.720 --> 00:08:45.640
wenn man das halt abzieht, und das ist natürlich auch eine ganz, also ist eigentlich relativ naheliegend,

00:08:45.640 --> 00:08:48.960
es wundert mich, dass da bisher noch niemand draufgekommen ist, dass man das irgendwie mal machen könnte, aber

00:08:48.960 --> 00:08:51.260
das ist auf jeden Fall eine ganz interessante Idee.

00:08:51.260 --> 00:08:54.880
Und, ähm, Kido hat da einen Artikel zugeschrieben.

00:08:54.880 --> 00:09:02.480
Ja, genau, irgendwie, der hat zweimal den Key irgendwie draus zugewiesen, und dann quasi einen Dictionary mit zwei identischen Keys erzeugt,

00:09:02.480 --> 00:09:04.200
wo dann nur einer von überlebt hat.

00:09:04.200 --> 00:09:07.200
Äh, ja.

00:09:07.200 --> 00:09:14.100
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,

00:09:14.100 --> 00:09:17.240
und dann war Eins übrig, weil das die letzte Zuweisung war.

00:09:17.240 --> 00:09:19.300
Weil ich das richtig verstanden habe.

00:09:19.300 --> 00:09:21.240
Genau, das war das Verhalten.

00:09:21.260 --> 00:09:25.840
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,

00:09:25.840 --> 00:09:34.060
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,

00:09:34.060 --> 00:09:35.400
dass dann halt immer das letzte genommen wird.

00:09:35.400 --> 00:09:39.220
Und, ähm, das war mir auch gar nicht klar, dass das so ist, aber, äh...

00:09:39.220 --> 00:09:42.840
Also kein, ähm, Duplicate Value oder Key Error oder sowas.

00:09:42.840 --> 00:09:44.080
Nee, es wird einfach das letzte genommen.

00:09:44.080 --> 00:09:50.820
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,

00:09:51.180 --> 00:09:53.260
weil irgendjemand die Frage gestellt hat, ob das Absicht wäre oder nicht.

00:09:53.260 --> 00:09:56.520
Dann hat er so, ich hab damals noch lange drüber nachgedacht und das ist Absicht.

00:09:56.520 --> 00:09:56.780
Ja.

00:09:56.780 --> 00:09:57.400
Und damit...

00:09:57.400 --> 00:10:03.600
Ich erinnere mich an irgendein Programm, wo ich das dachte, wo ich irgendwie komischen Fehler hatte und das, glaube ich, genau daran gelegen hat.

00:10:03.600 --> 00:10:09.440
Weil, ja, irgendwelche Duplikate dann zwar drin waren, ich das aber nicht gemerkt habe, erst irgendwann später, als mir um die Ohren flog.

00:10:09.440 --> 00:10:21.100
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...

00:10:21.100 --> 00:10:22.960
halt eine gute Idee ist oder nicht.

00:10:22.960 --> 00:10:25.440
Wie heißt das wieder? Code Active State?

00:10:25.440 --> 00:10:26.700
Ähm.

00:10:26.700 --> 00:10:28.460
Python Ideas.

00:10:28.460 --> 00:10:31.580
Ja, nee, in seinem Blog war das Ding drin.

00:10:31.580 --> 00:10:32.160
Ja.

00:10:32.160 --> 00:10:50.440
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,

00:10:51.020 --> 00:11:19.280
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.

00:11:20.940 --> 00:11:46.660
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.

00:11:50.860 --> 00:12:20.780
Neue News hatten wir, glaube ich, und das war der Django-Chat-Podcast.

00:12:20.780 --> 00:12:50.700
Ä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.

00:12:50.700 --> 00:13:20.660
Ja, ja, ja, ja, ja, ja, ja, ja, ja, ja, ja, ja, ja.

00:13:20.660 --> 00:13:23.040
Ja, wir können eigentlich mal, Pandas, genau.

00:13:23.040 --> 00:13:39.720
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.

00:13:39.720 --> 00:13:50.420
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.

00:13:50.580 --> 00:13:52.760
Da sieht man auch irgendwie zuerst was anderes verstanden, glaube ich.

00:13:52.760 --> 00:14:01.940
Ja, genau, also es gibt nicht nur, ähm, Python-Pandas, das Data-Frame-Framework, sondern auch, ähm, Python-Pandas-3D, die Game-Engine.

00:14:01.940 --> 00:14:02.280
Ah!

00:14:02.280 --> 00:14:13.760
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.

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

00:14:17.760 --> 00:14:19.180
Ist die in Python?

00:14:19.180 --> 00:14:20.500
Also, äh, ich...

00:14:20.500 --> 00:14:25.380
Ich glaube, Game-Entwicklung in Python ist vielleicht eine Folge, zu der ich nochmal wiederkommen sollte.

00:14:25.380 --> 00:14:25.720
Oh, ja!

00:14:25.720 --> 00:14:28.720
Ja, ja, einfach, weil das sehr, sehr umfangreich ist.

00:14:28.720 --> 00:14:29.220
Und das geht?

00:14:29.220 --> 00:14:36.020
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.

00:14:36.020 --> 00:14:41.400
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?

00:14:41.400 --> 00:14:50.400
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...

00:14:50.420 --> 00:14:52.860
...ist zu lernen, wie so eine Game-Engine wirklich funktioniert.

00:14:52.860 --> 00:14:53.300
Mhm.

00:14:53.300 --> 00:15:07.820
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.

00:15:07.820 --> 00:15:10.180
Ich muss überlegen, welche das waren. Das war, ähm, Unreal...

00:15:10.180 --> 00:15:12.300
Unreal, Unity 3D und...

00:15:12.300 --> 00:15:15.000
...Unity 3D und CryEngine.

00:15:15.000 --> 00:15:18.640
Ja, okay, dann CryEngine ist ja nicht frei. It 7 oder so 8.

00:15:18.640 --> 00:15:20.340
Weiß ich gerade gar nicht.

00:15:20.340 --> 00:15:23.600
Ich glaub, wir sind gerade völlig off-topic, ähm, wir wollten über Pandas sprechen.

00:15:23.600 --> 00:15:34.940
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.

00:15:34.940 --> 00:15:37.340
Okay, wir sind wieder mal bei der Datenanalyse.

00:15:37.340 --> 00:15:38.780
Genau.

00:15:38.780 --> 00:15:44.760
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?

00:15:44.760 --> 00:15:47.260
Ja, ein bisschen mehr, aber genau um den Dreh.

00:15:47.260 --> 00:15:50.260
Wenn ihr mal wieder die Wohnung richtig putzen wollt, dann...

00:15:50.260 --> 00:16:00.700
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.

00:16:00.700 --> 00:16:13.280
Ä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.

00:16:13.280 --> 00:16:20.180
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...

00:16:20.180 --> 00:16:25.480
...das Daten, äh, nachher analysieren und visualisieren, aber die Aufbereitung war da sehr gut.

00:16:25.480 --> 00:16:31.060
Das heißt, für die Analyse und, und die Visualisierung sind wir dann immer zu R rüber gewechselt.

00:16:31.060 --> 00:16:39.020
R ist, äh, auch eine Programmiersprache, ähm, ist eine eher mathematische Annotation, ähm, zur Datenanalyse.

00:16:39.020 --> 00:16:50.020
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.

00:16:50.100 --> 00:16:56.320
Ähm, als, als dritte Alternative, wenn Leute heute Daten, Datenanalyse machen.

00:16:56.320 --> 00:16:58.960
Was meinst du denn mit Datenbereinigung?

00:16:58.960 --> 00:17:16.720
Ä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...

00:17:16.720 --> 00:17:18.720
Du musst dich dann entscheiden, ob du eine Rundung anwendest oder nicht.

00:17:20.020 --> 00:17:26.080
Ähm, führt dann erstmal dazu, dass die Daten nicht mehr so strukturiert sind, wie man das eigentlich dachte in der Tabelle.

00:17:26.080 --> 00:17:30.800
Ähm, das kommt auf, auf die Messinstrumente im Wesentlichen an.

00:17:30.800 --> 00:17:37.240
Ähm, das heißt, die erste Aufbereitung ist erstmal, die Daten in ein maschinenlesbares Format zu bringen.

00:17:37.240 --> 00:17:41.900
Und da ist es, äh, von unfassbarem Wert, wenn man programmieren kann.

00:17:41.900 --> 00:17:43.260
Ähm...

00:17:43.260 --> 00:17:46.640
Dann muss man jede einzelne Zeile oder Zelle durchgehen und die manuell korrigieren.

00:17:46.640 --> 00:17:46.880
Mhm.

00:17:46.880 --> 00:17:49.940
Genau, also ich, äh, ich hab auch, äh, tatsächlich schon...

00:17:49.940 --> 00:17:56.820
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.

00:17:56.820 --> 00:18:01.000
Und, äh, dann haben wir uns kurz zusammengesetzt, ein Makro geschrieben und dann ging das irgendwie doch schneller.

00:18:01.000 --> 00:18:01.780
Mhm.

00:18:01.780 --> 00:18:04.720
Ähm, und fehlerfreier an der Stelle auch.

00:18:04.720 --> 00:18:15.120
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.

00:18:15.120 --> 00:18:19.020
Nochmal für unsere ganz Anfänger, nochmal bitte, was denn überhaupt maschinenlesbar bedeutet.

00:18:19.020 --> 00:18:19.440
Mhm.

00:18:19.940 --> 00:18:29.980
Ähm, ich hab da mal irgendwann ein Beispiel vorbereitet, äh, für, ähm, für Mediziner, die von Excel zu R wechseln wollten.

00:18:29.980 --> 00:18:45.260
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.

00:18:45.260 --> 00:18:49.260
Da gab's dann quasi einmal Experiment A, war so ein, äh, fünfmal...

00:18:49.940 --> 00:18:50.660
Fünfmal vier Raster.

00:18:50.660 --> 00:18:55.020
Experiment B war so ein fünfmal vier Raster, was irgendwie rechts daneben stand.

00:18:55.020 --> 00:18:59.920
Und dann gab's noch ein Experiment C, was dann mittig darunter stand, auch fünfmal vier Raster.

00:18:59.920 --> 00:19:05.940
Das ist für einen Menschen super lesbar, weil man kann sofort die Blöcke identifizieren und sich die Messdaten angucken.

00:19:05.940 --> 00:19:09.740
Ähm, für eine Maschine ist das aber nicht mehr strukturiert lesbar.

00:19:09.740 --> 00:19:10.780
Weil die Koordinaten nicht klar sind.

00:19:10.780 --> 00:19:12.360
Weil die Koordinaten nicht klar sind, genau.

00:19:12.360 --> 00:19:19.360
Und, ähm, was häufig passiert ist, wenn Menschen...

00:19:19.940 --> 00:19:34.460
...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.

00:19:34.460 --> 00:19:38.740
Oder stehen sollte, weil da unterschiedliche Informationen sind, die nicht voneinander getrennt sind.

00:19:38.740 --> 00:19:43.940
Dann stehen zum Beispiel sowas wie eine Spalte, wo zwei verschiedene Datensachen auf einmal drinstehen.

00:19:43.940 --> 00:19:44.480
Genau.

00:19:44.480 --> 00:19:47.300
Einmal Temperatur in Celsius, einmal in Fahrenheit oder sowas.

00:19:47.300 --> 00:19:49.000
Oder ist das legitim?

00:19:49.000 --> 00:19:49.900
Ja, das könnte ja noch...

00:19:49.900 --> 00:20:05.780
...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.

00:20:05.780 --> 00:20:06.560
Mhm.

00:20:06.560 --> 00:20:16.960
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...

00:20:16.960 --> 00:20:19.860
Aber, äh, Fahrenheit und Celsius wäre okay, wenn man...

00:20:19.860 --> 00:20:20.720
...die...

00:20:20.720 --> 00:20:21.740
...wenn die Spalte...

00:20:21.740 --> 00:20:22.980
...wenn das unterschiedliche Spalten wäre...

00:20:22.980 --> 00:20:25.860
...wenn die Information enthalten wäre in der Zelle, ob es Celsius-Erfahrenheit wäre.

00:20:25.860 --> 00:20:28.000
Äh...

00:20:28.000 --> 00:20:29.440
Weil das wäre sonst problematisch, wenn man...

00:20:29.440 --> 00:20:35.120
Ja, also wir kommen da sicherlich gleich nochmal zu, so gut das geht, in einem Podcast Tabellen zu beschreiben.

00:20:35.120 --> 00:20:36.940
Ja, wir passieren, weil wir das so kritisieren.

00:20:36.940 --> 00:20:47.920
Ä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.

00:20:47.920 --> 00:20:48.380
Mhm.

00:20:49.820 --> 00:20:55.660
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.

00:20:55.660 --> 00:21:00.860
Welche, die man bauen müsste oder, äh, wo man irgendwelche Dimensionen verbraucht, die wir uns jetzt nicht so räumlich vorstellen können.

00:21:00.860 --> 00:21:00.980
Genau.

00:21:00.980 --> 00:21:10.340
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.

00:21:10.340 --> 00:21:11.120
Okay.

00:21:11.120 --> 00:21:12.460
Ja.

00:21:12.460 --> 00:21:13.680
Ja.

00:21:13.680 --> 00:21:19.580
Ja, okay, das haben wir so ungefähr verstanden, was so maschinenlesbar dann bedeutet für die einzelnen Daten.

00:21:19.780 --> 00:21:49.740
Und wo kommt jetzt Pandas dann ins Spiel, wenn du jetzt diese...

00:21:49.740 --> 00:21:58.240
Für die Darstellung von Vektoren NumPy und für einfache statistische Analysen SciPy und für Visualisierung Matplotlib.

00:21:58.240 --> 00:22:03.400
Und dann war der Kreis eins weiter draußen so ein bisschen das, was darauf aufbaut.

00:22:03.400 --> 00:22:10.220
Das war dann Pandas, das war, ähm, Studs Models war das, glaube ich.

00:22:10.220 --> 00:22:12.800
Mhm, das so für Zeitreihen und so.

00:22:12.800 --> 00:22:14.420
Genau, und, ähm, Seaborn.

00:22:14.420 --> 00:22:19.700
Und das waren dann die Pendants, also, äh, Seaborn auch wieder zur Visualisierung und Studs Models.

00:22:19.700 --> 00:22:30.220
Äh, im Prinzip zur statistischen Auswertung und Pandas eben zum, äh, zum Data Handling, ähm, aber jenseits von einfachen Vektoren.

00:22:30.220 --> 00:22:32.340
Mhm, okay.

00:22:32.340 --> 00:22:47.500
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.

00:22:47.500 --> 00:22:47.540
Ja.

00:22:47.540 --> 00:22:49.660
Also, Tabellenkalkulation ist...

00:22:49.660 --> 00:22:53.860
Also, Tabellenkalkulation ist jedem sofort ein Begriff und alle wissen auch sofort, okay, es gibt Zeilen und Spalten.

00:22:53.860 --> 00:22:59.860
Das ist so, dass das, äh, wäre ein Minimum, was man wissen muss, um mit Pandas was anfangen zu können.

00:22:59.860 --> 00:23:02.700
Das hat man wahrscheinlich in der Schule schon mal aufgemacht oder so, oder aufmachen müssen.

00:23:02.700 --> 00:23:03.660
In der Regel schon, ja.

00:23:03.660 --> 00:23:12.120
Ja, genau, ähm, das heißt, bei Pandas sind wir jetzt in dem Bereich von, ähm, Data Handling.

00:23:12.120 --> 00:23:18.420
Also, wie kann ich meine Daten laden, verarbeiten, zur Verfügung stellen für Analysen?

00:23:19.620 --> 00:23:20.580
Wie macht Pandas das?

00:23:20.580 --> 00:23:23.480
Gibt's da Speziellen?

00:23:23.480 --> 00:23:36.800
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.

00:23:36.800 --> 00:23:43.160
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.

00:23:43.160 --> 00:23:43.960
Mhm.

00:23:43.960 --> 00:23:48.800
Äh, die sehr, sehr flexibel ist und man kann irgendwie so ungefähr jedes CSV, was irgendwo...

00:23:49.580 --> 00:24:00.420
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?

00:24:00.420 --> 00:24:19.540
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.

00:24:19.540 --> 00:24:49.500
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...

00:24:49.500 --> 00:25:19.460
Eine Zeitreihenanalyse oder sowas?

00:25:19.460 --> 00:25:49.420
Eine Zeitreihenanalyse oder sowas?

00:25:49.420 --> 00:26:19.380
Eine Zeitreihenanalyse oder sowas?

00:26:19.380 --> 00:26:34.600
Ä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.

00:26:34.620 --> 00:26:39.380
zu bekommen und auch in denen steckt relativ viel Geld drin, aber diese Sachen sind alle

00:26:39.380 --> 00:26:44.540
ziemlich schlecht irgendwie und Pandas füllte halt so eine Lücke.

00:26:44.540 --> 00:26:48.920
Ist halt eigentlich ultra wichtig, weil irgendwie diese ganzen Datenimport-Export-Geschichten

00:26:48.920 --> 00:26:54.960
sind halt etwas, was man immer braucht und irgendwie es gibt außer Pandas keine Projekte,

00:26:54.960 --> 00:26:58.800
die das irgendwie ordentlich gemacht haben und du kannst natürlich irgendwie deine tolle

00:26:58.800 --> 00:27:03.340
Deep Learning TensorFlow-Geschichte nehmen, aber wenn du die Daten halt nicht hast, um

00:27:03.340 --> 00:27:11.720
damit irgendwas machen zu können, dann hilft dir das alles nichts und ja, das, eben, weiß

00:27:11.720 --> 00:27:14.440
man, Kenny erzählt davon halt auch immer, dass ihm das total wundert und dass er das

00:27:14.440 --> 00:27:19.020
total seltsam findet, dass halt so ein wichtiger Teil der Infrastruktur so wenig Liebe erfährt

00:27:19.020 --> 00:27:26.280
quasi und dass seine Hauptmotivation war zu sagen, okay, da muss man mal was tun, da muss

00:27:26.280 --> 00:27:29.300
man, das muss doch irgendwie, dieses Problem muss man doch lösen, das ist halt irgendwie

00:27:29.300 --> 00:27:32.840
ein Problem, was alle haben und was irgendwie sehr ärgerlich ist und ja.

00:27:33.340 --> 00:27:39.060
Und das ist halt, das macht Pandas auch sehr gut irgendwie und das ist immer so ein erster

00:27:39.060 --> 00:27:41.660
Schritt, wenn man irgendwie Daten, auch wenn man jetzt hinterher Machine Learning machen

00:27:41.660 --> 00:27:45.520
möchte oder so, hat man trotzdem immer Pandas mit dabei, weil man die Daten ja erstmal in

00:27:45.520 --> 00:27:49.600
irgendwie ein Format bringen muss vorher und vielleicht aufräumen muss, sauber machen

00:27:49.600 --> 00:27:54.600
muss, da gibt es auch immer so einen schönen Spruch, irgendwie Data Science ist halt so

00:27:54.600 --> 00:28:02.340
oder auch Machine Learning ist halt, 80% ist halt Data Cleaning, ja, und 20% ist darüber

00:28:03.340 --> 00:28:12.940
beschweren, dass irgendwie 80% Data Cleaning, ja, ich meine, die andere Sache ist, als Mensch

00:28:12.940 --> 00:28:17.500
möchte man ja auch sich die Daten vielleicht zwischendurch mal angucken können und dafür

00:28:17.500 --> 00:28:24.340
braucht man irgendwie eine Datenstruktur, in der man sehr schnell zu Rahmendaten kommt,

00:28:24.340 --> 00:28:28.860
vielleicht braucht man mal einen Mittelwert oder will sich mal die Verteilung angucken,

00:28:28.860 --> 00:28:31.500
gruppiert bei irgendwelchen...

00:28:33.340 --> 00:28:35.280
Kategorien oder sowas.

00:28:35.280 --> 00:28:43.860
Also sicherlich ist diese Import-Geschichte von Pandas eine der mächtigsten, die ich bisher

00:28:43.860 --> 00:28:50.360
gesehen habe, was auch so fehlende Datenpunkte angeht und wenn die Struktur mal nicht ganz

00:28:50.360 --> 00:28:54.220
stimmt und man kann einzelne Zeilen überspringen, wenn da mal was kaputt geht oder sowas.

00:28:54.220 --> 00:28:57.760
Da habe ich jetzt übrigens direkt eine doofe Frage zu, weil es gibt ja irgendwie bei Pandas

00:28:57.760 --> 00:29:01.720
so ein paar Werte, die, wenn die halt nicht da sind, die man irgendwie füllen kann, da

00:29:01.720 --> 00:29:03.140
gibt es ja irgendwie jetzt aber so drei Typen.

00:29:03.340 --> 00:29:06.840
So Null und None und None.

00:29:06.840 --> 00:29:12.400
Warum, wieso braucht man da drei?

00:29:12.400 --> 00:29:21.640
In Pandas, also ich wüsste jetzt eigentlich nur, dass es da Not a Number gibt und das

00:29:21.640 --> 00:29:29.740
ist historisch sozusagen, hier ist kein Wert von NumPy, das ist auch irgendwie sozusagen

00:29:29.740 --> 00:29:32.740
ganz unten drunter ist das tatsächlich ein...

00:29:33.340 --> 00:29:38.980
In Float kann man das halt ausdrücken und ja, das hat halt auch so das leichte Problem,

00:29:38.980 --> 00:29:43.740
dass man im Grunde immer dann, wenn man solche Werte hat, dann halt auch der Datentyp irgendwie

00:29:43.740 --> 00:29:45.420
Float sein muss, was so ein bisschen doof ist.

00:29:45.420 --> 00:29:51.880
Das war bis vor ganz kurzem war das noch so, dass man halt, wenn man jetzt eine Integer-Spalte

00:29:51.880 --> 00:29:57.660
hatte und da fehlt halt jetzt ein Wert und man hat halt gesagt, okay, da kommt irgendwie

00:29:57.660 --> 00:30:02.820
was dazu, was halt irgendwie fehlt oder so und man macht dann einen Re-Index und guckt

00:30:02.820 --> 00:30:03.220
und dann hat es...

00:30:03.220 --> 00:30:08.000
Dann hat sich plötzlich der Typ der Spalte in Float geändert, weil es halt keine fehlenden

00:30:08.000 --> 00:30:15.000
Werte in Integer-Typ, die Type-Spalten gibt und das ist ein ziemlich blödes Problem.

00:30:15.000 --> 00:30:25.680
Aber jetzt gibt es halt irgendwie seit einiger Zeit diese Array-Extensions, Array-Extensions-API

00:30:25.680 --> 00:30:30.540
für Pandas und die halt mit Cyber-Pandas dazugekommen ist, ich weiß gar nicht, welche

00:30:30.540 --> 00:30:31.520
Version das genau war.

00:30:33.100 --> 00:30:40.860
Und jetzt hat auch die, Ende Januar ist die letzte größere Release von Pandas erschienen,

00:30:40.860 --> 00:30:43.080
ich glaube 0.224 oder so.

00:30:43.080 --> 00:30:44.200
0.24, ja.

00:30:44.200 --> 00:30:51.380
0.24 und da ist jetzt halt auch eine native, natives Integer-Spaltenformat drin, das halt

00:30:51.380 --> 00:30:57.560
auch nannen kann und das ist natürlich total cool irgendwie und man kann jetzt für, also

00:30:57.560 --> 00:31:02.240
dadurch, dass man jetzt quasi nicht mehr Namen-Pile unten drunter liegen hat, kann man da auch

00:31:02.240 --> 00:31:02.980
diverse andere...

00:31:02.980 --> 00:31:07.680
coole Datentypen irgendwie verwenden, die vorher so nicht möglich waren, weil man ja

00:31:07.680 --> 00:31:09.500
immer auf Namen-Pile angewiesen war.

00:31:09.500 --> 00:31:13.860
Also Namen-Pile ist auch ganz cool, aber Namen-Pile hat halt das Problem, dass das grundlegende

00:31:13.860 --> 00:31:20.440
Design dafür ist halt, ja jetzt doch schon wahrscheinlich fast 20 Jahre alt und passt

00:31:20.440 --> 00:31:25.480
halt auch nicht mehr so richtig auf die Anforderungen von heute und dummerweise hat Pandas aber

00:31:25.480 --> 00:31:31.180
viele der Implementationsdetails in Namen-Pile halt rausgelegt und das kann man jetzt auch

00:31:31.180 --> 00:31:32.860
nicht mehr so einfach ändern, weil das halt...

00:31:32.860 --> 00:31:36.780
also wenn man das wieder ändern würde, würde das Code brechen und dann also wäre keine

00:31:36.780 --> 00:31:40.420
abwärtskompatiblen Änderungen mehr und das ist natürlich alles so ein bisschen blöde

00:31:40.420 --> 00:31:45.740
Situation, aber irgendwie mit dieser Array-Extension-API hat man auf jeden Fall eine Möglichkeit, wenn

00:31:45.740 --> 00:31:50.000
man den Typ ändert, dann ist das alles eigentlich in Ordnung und dann kann man da auch schöne

00:31:50.000 --> 00:31:53.260
neue Sachen machen, ohne dass man auf Namen-Pile irgendwie angewiesen ist.

00:31:53.260 --> 00:31:54.760
Zum Beispiel was halt...

00:31:54.760 --> 00:31:56.860
also das sind so Beschränkungen, die sind echt blöd.

00:31:56.860 --> 00:32:02.740
Also wenn man auf Namen-Pile unten drunter basierendes Pandas hat, dann hat man halt so

00:32:02.740 --> 00:32:09.840
was nicht wie zum Beispiel Decimal-Types, also einfach man hat keinen fehlenden Missing-Value-Support

00:32:09.840 --> 00:32:13.500
für sowas wie Integer, was auch schon schlimm ist, aber man hat halt auch... wenn man jetzt

00:32:13.500 --> 00:32:17.800
mit Geld zu tun hat, was man ja vielleicht auch irgendwie... dann hat man halt bloß

00:32:17.800 --> 00:32:22.680
Float, das will man auch nicht, also man würde das dann irgendwie wahrscheinlich eher Geld

00:32:22.680 --> 00:32:25.500
in Integer, also in Cent-Integer oder sowas verwenden.

00:32:25.500 --> 00:32:31.780
Viele werden wahrscheinlich irgendwie Float nehmen und dann denken, ach das wird schon

00:32:31.780 --> 00:32:32.520
irgendwie hinhauen.

00:32:32.620 --> 00:32:36.680
Und dann böse Überraschungen überleben, weil das für... das funktioniert halt überhaupt

00:32:36.680 --> 00:32:37.680
gar nicht.

00:32:37.680 --> 00:32:41.660
Und man kriegt diverse richtig böse Probleme, wenn man das macht.

00:32:41.660 --> 00:32:47.440
Und in Datenbanken ist das Problem eigentlich auch schon lange gelöst, da gibt es den Decimal-Type,

00:32:47.440 --> 00:32:52.200
genau für sowas, der dann halt auch ordentlich rundet und so.

00:32:52.200 --> 00:32:57.860
Und in Python gibt es auch einen nativen Decimal-Type, der ist blöderweise nur total super langsam,

00:32:57.860 --> 00:33:02.500
also den kann man eigentlich auch nicht nehmen.

00:33:02.500 --> 00:33:08.100
Also sozusagen als Array-Extension-Type halt auch Decimal, sodass man das halt auch in Pandas

00:33:08.100 --> 00:33:14.440
Data Frames halt Geld quasi mit Kommastellen verwenden kann, ohne dass man da mit schlimmen

00:33:14.440 --> 00:33:16.320
Konsequenzen rechnen muss.

00:33:16.320 --> 00:33:21.880
Und es gibt sowas wie Date-Time mit Time-Zonen dran und so, das ging vorher auch nicht.

00:33:21.880 --> 00:33:23.380
Und das ist...

00:33:23.380 --> 00:33:26.140
Achso, sowas wie Grad mit Celsius-Erfahrenheit vielleicht.

00:33:26.140 --> 00:33:29.700
Das ist nochmal ein anderes... genau, das möchte man auch gerne haben.

00:33:29.700 --> 00:33:32.300
Ich weiß nicht, ich glaube, das ist nicht direkt in Pandas drin.

00:33:32.380 --> 00:33:37.380
Es gibt Bibliotheken dafür, dass man halt an Spalten auch noch irgendwie so eine Maßeinheit dran klebt.

00:33:37.380 --> 00:33:45.300
Die Annotationen und auch Skalierungsfaktoren kommen auch mit unter aus dem zugrunde liegenden Datenformat,

00:33:45.300 --> 00:33:46.660
aus dem man nachher importiert.

00:33:46.660 --> 00:33:50.500
Also es gibt irgendwie wissenschaftliche Datenformate, die speichern sowas alles mit.

00:33:50.500 --> 00:33:55.280
HDF 5 oder NET-CDF oder wie das inzwischen heißt.

00:33:55.280 --> 00:33:57.620
Wie sieht das dann aus? Hat das eine Spalte, ein Doppel drin oder?

00:33:57.620 --> 00:34:02.260
Da gibt es im Prinzip irgendwie so eine Tabelle von Meta-Daten.

00:34:02.260 --> 00:34:07.340
Meta-Daten, wo drin steht, welche Spalten, welche Maßeinheit, welche Skalierungsfaktoren haben,

00:34:07.340 --> 00:34:11.220
wann die zuletzt bearbeitet wurden.

00:34:11.220 --> 00:34:13.820
Und darunter stehen dann serialisiert die Daten drin.

00:34:13.820 --> 00:34:19.360
Und dadurch hat man einen sehr, sehr schnellen sequentiellen Zugriff auf seine Daten,

00:34:19.360 --> 00:34:26.740
hat aber trotzdem die Möglichkeit, diese Skalierungen und Einheiten mitzuführen.

00:34:26.740 --> 00:34:32.020
Und in Pandas weiß ich nicht, ob das inzwischen mit importiert wird.

00:34:32.140 --> 00:34:35.140
Aber diese Erweiterung...

00:34:35.140 --> 00:34:39.680
Ja, ich habe jetzt normalerweise auch nicht mehr parat, wie die Bibliothek...

00:34:39.680 --> 00:34:41.460
Es gibt eine Bibliothek für so Maßeinheiten und sowas.

00:34:41.460 --> 00:34:44.060
Ich weiß aber nicht genau, wie das gemacht ist.

00:34:44.060 --> 00:34:45.300
Das müsste ich nochmal nachgucken.

00:34:45.300 --> 00:34:49.500
Vielleicht können wir das einfach dann beim nächsten Mal nachreichen oder so.

00:34:49.500 --> 00:34:55.060
Auf jeden Fall, da gibt es etwas und das kriegt man schon irgendwie alles auch mit dazu geschrieben.

00:34:55.060 --> 00:34:58.580
Ja, also genau, das ist eigentlich so wie früher.

00:34:58.580 --> 00:35:01.180
Der Default ist immer noch bei Pandas.

00:35:02.020 --> 00:35:05.860
Wie Sachen gespeichert werden, das nennt sich irgendwie Block Manager oder Block Storage.

00:35:05.860 --> 00:35:09.760
Und das sind immer 2D NumPy Arrays.

00:35:09.760 --> 00:35:13.480
Und die sind halt immer sozusagen...

00:35:13.480 --> 00:35:19.340
Also man würde eigentlich denken, dass ein Data Frame, dass jede Spalte irgendwie ein 1D,

00:35:19.340 --> 00:35:22.280
also ein eindimensionales NumPy Array ist.

00:35:22.280 --> 00:35:31.620
Aber das ist halt nicht so, sondern ein Data Frame besteht aus Blocks von 2D NumPy Arrays,

00:35:31.900 --> 00:35:34.900
jeweils zu einem, also unterteilt nach Datentyp.

00:35:34.900 --> 00:35:42.680
Also wenn ich jetzt sagen habe, ein Data Frame, der 3 Spalten hat, 2 davon Float, 1 Integer,

00:35:42.680 --> 00:35:49.380
dann besteht das Ding aus 2 NumPy Arrays, 1 mit Integer und 1 mit Float, das halt 2 Spalten hat.

00:35:49.380 --> 00:35:53.280
Da muss man jetzt natürlich aufpassen, von welcher Seite man drauf guckt.

00:35:53.280 --> 00:35:57.900
Weil aus Pandas Sicht ist das erstmal eine Liste von Pandas Series.

00:35:57.900 --> 00:36:00.740
Da haben wir auch noch nicht drüber gesprochen, was das ist.

00:36:01.780 --> 00:36:08.240
Also die Abbildung als NumPy Arrays ist natürlich dann irgendwie die technische zugrunde liegende Abbildung.

00:36:08.240 --> 00:36:10.160
Ja, ja, genau.

00:36:10.160 --> 00:36:12.260
Eigentlich sollte das egal sein.

00:36:12.260 --> 00:36:16.920
Sollte man sich eigentlich keine Gedanken darüber machen, sondern eigentlich ist eine Series halt quasi,

00:36:16.920 --> 00:36:22.820
kann man es verstehen als Spalte oder eben Vektor, eindimensionale Datenstruktur mit vielleicht noch einem Index dran.

00:36:22.820 --> 00:36:26.620
Aber so wird es halt nicht gespeichert.

00:36:26.620 --> 00:36:29.840
Und das Blöde ist, dass diese Abstraktion halt auch so liegt.

00:36:29.840 --> 00:36:31.660
Weil wenn man jetzt...

00:36:31.660 --> 00:36:34.880
zum Beispiel eine Spalte hinzufügt zu einem DataFrame,

00:36:34.880 --> 00:36:41.620
dann hat man das Problem, dass dadurch, dass jetzt, wenn man schon ein paar Float-Spalten da drin hat

00:36:41.620 --> 00:36:46.920
und man fügt jetzt eine dazu, dann geht das ja nicht mehr wirklich.

00:36:46.920 --> 00:36:49.540
Sondern dann müssen die kompletten Daten alle kopiert werden dafür.

00:36:49.540 --> 00:36:54.180
Und wenn man jetzt in der Schleife irgendwie Spalten hinzufügt oder so,

00:36:54.180 --> 00:36:57.060
dann kann es sein, dass einem der Speicher platzt und man weiß überhaupt nicht warum.

00:36:57.060 --> 00:37:00.180
Das heißt, man muss im Grunde wissen, dass Pandas das so macht.

00:37:01.540 --> 00:37:05.240
Dann gibt es ja immer so Tipps, wie gesagt, wenn man da irgendwie viele Spalten hinzufügt,

00:37:05.240 --> 00:37:09.480
dann immer erst mal die einzelnen Spalten sammeln und dann hinterher alle zusammenfügen oder so.

00:37:09.480 --> 00:37:13.980
Nicht irgendwie auf einem großen DataFrame eine Spalte hinzufügen, dann noch eine hinzufügen, das ist schlecht.

00:37:13.980 --> 00:37:20.880
Und das sollte eigentlich, das sind so Schwächen bei Pandas, das sollte einen gar nicht interessieren, wenn man das benutzt.

00:37:20.880 --> 00:37:28.100
Dummerweise muss man solche Sachen aber dann vielleicht doch wissen, weil man halt dieses Problem da an der Stelle noch hat.

00:37:28.100 --> 00:37:30.480
Aber das kann sein, dass das jetzt alles demnächst besser wird.

00:37:31.420 --> 00:37:34.180
Und mit dieser Version, mit der letzten Version ist es halt schon ein Stück besser geworden.

00:37:34.180 --> 00:37:40.360
Und da sind halt die einzelnen Spalten, haben ihren eigenen Typ und ihre eigene Speichergeschichte und dann ist alles nicht mehr so ein Problem.

00:37:40.360 --> 00:37:43.780
Aber ja, das ist vielleicht auch noch interessant.

00:37:43.780 --> 00:37:53.220
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.

00:37:53.220 --> 00:38:00.600
Weil halt da fast alle Operationen dazu führen, dass das irgendwie kopiert wird, kann es sehr schnell sein, dass man halt irgendwie auch,

00:38:01.300 --> 00:38:07.660
fünf oder vielleicht sogar bis zu zehnfacher der Datenmenge, die tatsächlich auf der Platte landet oder so, man dann als Hauptspeicher braucht.

00:38:07.660 --> 00:38:14.660
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.

00:38:14.660 --> 00:38:18.160
Und daher ist es halt nicht so richtig effizient.

00:38:18.160 --> 00:38:19.840
Kann auch sein, dass es jetzt dann halt besser wird.

00:38:19.840 --> 00:38:24.720
Aber also für größere Sachen kann man Pandas nicht so super benutzen.

00:38:24.720 --> 00:38:30.840
Aber für diese kleinen Datenmengen ist es halt sehr, sehr cool, weil es super effektiv ist.

00:38:31.180 --> 00:38:42.180
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.

00:38:42.180 --> 00:38:59.360
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.

00:39:01.060 --> 00:39:17.020
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.

00:39:17.020 --> 00:39:28.440
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.

00:39:30.940 --> 00:39:49.480
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.

00:39:49.480 --> 00:40:00.000
Und spannenderweise, wir waren eben bei Datenimport, da ist noch eine Sache, meine Lieblingsfunktion ist an der Stelle tatsächlich Import from Clipboard.

00:40:00.820 --> 00:40:16.580
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.

00:40:16.580 --> 00:40:18.140
Nö, das kann gut sein, dass das funktioniert, ja.

00:40:18.140 --> 00:40:27.360
Also kann man sich halt auch ganz kleine Datenchunks, kleine Tabellen direkt aus der Zwischenablage in sein DataFrame reinladen.

00:40:27.360 --> 00:40:30.620
Das heißt, wenn wir jetzt von diesem Gigabyte-Bereich liegen, ich glaube,

00:40:30.700 --> 00:40:34.240
für wissenschaftliche Anwendung müsste das in den meisten Fällen auch relativ ausreichend sein.

00:40:34.240 --> 00:40:40.080
Ja, ja, absolut. Also das ist sowieso so, die allermeisten Leute haben nicht mehr Daten. Also für die allermeisten Leute reicht das aus.

00:40:40.080 --> 00:40:43.680
Wenn man mehr hat, dann weiß man das und dann kann man auch was anderes nehmen.

00:40:43.680 --> 00:40:53.260
Ja, aber stimmt, wir hatten eben noch gar nicht genau, vielleicht sollten wir da so ein bisschen systematisch auch nochmal kurz reingehen.

00:40:53.260 --> 00:40:58.600
Also Pandas, genau, das hat auch was damit zu tun, wo der Name herkommt.

00:40:58.600 --> 00:41:00.600
Also Pandas steht eigentlich für Penalty.

00:41:00.700 --> 00:41:05.680
Penaldata, oder das war halt auch mal das, was halt so in der Finanzwelt, wo Leute von Geräte haben, von Penaldata.

00:41:05.680 --> 00:41:10.500
Und damit meinen sie dann halt oft Excel-Sheets irgendwie oder mehrere davon.

00:41:10.500 --> 00:41:14.480
Und das kann Pandas auch, ist aber irgendwie nicht mehr so.

00:41:14.480 --> 00:41:23.100
Also es gibt auch noch, es gibt halt einmal Series, es gibt DataFrames, das ist halt sozusagen eine zweidimensionale Tabelle irgendwie.

00:41:23.100 --> 00:41:28.100
Series ist eindimensional und dann gibt es auch noch Panels, die sind halt dann mehrdimensional.

00:41:28.100 --> 00:41:30.580
Und die werden aber eigentlich nicht mehr verwertet.

00:41:30.580 --> 00:41:35.180
Oder wurden eigentlich nie so wirklich viel verwendet.

00:41:35.180 --> 00:41:43.040
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.

00:41:43.040 --> 00:41:50.020
Ja, genau, daher kommt der Name.

00:41:50.020 --> 00:41:54.640
Es ist ein bisschen blöd, wenn man danach googeln will und dann hat man Tierbilder.

00:41:54.640 --> 00:41:59.260
Aber wir haben immer wieder Tierbilder dabei.

00:41:59.260 --> 00:42:00.260
Auch interessant ist das Vorbild.

00:42:00.460 --> 00:42:03.360
Vorbild für Pandas ist ja R, denke ich mal.

00:42:03.360 --> 00:42:05.760
Das ist mit Googlen auch nicht viel einfacher.

00:42:05.760 --> 00:42:13.240
Aber genau, ich weiß nicht, du hast auch schon mal mit R gearbeitet, Simon.

00:42:13.240 --> 00:42:18.300
Was sind denn da so die, wie kann man das eigentlich miteinander vergleichen?

00:42:18.300 --> 00:42:21.440
Oder ist da vielleicht auch ganz interessant zu sehen, wo das herkommt?

00:42:21.440 --> 00:42:27.100
Ja, also ich habe in meiner Forschungszeit sehr viel zwischen R und Excel hin und her gewechselt.

00:42:27.100 --> 00:42:30.100
Und tatsächlich muss ich sagen, die R...

00:42:30.340 --> 00:42:42.120
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.

00:42:42.120 --> 00:42:46.900
Einer ist sicherlich, dass die DataFrames immer rechteckig sind.

00:42:46.900 --> 00:42:52.380
Also man kann nicht eine Spalte mit weniger Daten füllen als die nächste Spalte.

00:42:52.380 --> 00:42:56.620
Es muss zu jeder Zeile immer für jede Spalte auch einen Wert geben.

00:42:56.620 --> 00:42:58.640
Also es gibt für jeden Index irgendwie keinen Error.

00:42:58.640 --> 00:42:59.280
Genau.

00:43:00.220 --> 00:43:01.940
Wenn ein Not a Number ist, ist das okay.

00:43:01.940 --> 00:43:04.960
Aber es muss auf jeden Fall irgendeinen Eintrag geben.

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

00:43:12.100 --> 00:43:21.740
Dann gibt es bei DataFrames grundsätzlich auch Typen je Spalte.

00:43:21.740 --> 00:43:26.040
Das ist in Excel nicht so.

00:43:26.040 --> 00:43:28.480
Da hat jede Zelle im Prinzip einen Typ, wenn man will.

00:43:28.480 --> 00:43:30.100
Und da kann man auch ganz viel...

00:43:30.100 --> 00:43:31.760
...bösen Schabernack mit treiben.

00:43:31.760 --> 00:43:41.820
Und in DataFrames, dadurch einfach, dass man eine Series pro Spalte hat, hat auch eine Spalte immer nur einen Typ.

00:43:41.820 --> 00:43:59.980
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...

00:43:59.980 --> 00:44:26.500
...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.

00:44:29.860 --> 00:44:34.080
Das heißt, dass die Diktion-Lesbare wieder als rot, gelb, grün, blau dargestellt werden.

00:44:34.080 --> 00:44:35.080
Okay.

00:44:35.080 --> 00:44:36.080
Wie macht Pandas das?

00:44:36.080 --> 00:44:37.080
Als Dictionary dann?

00:44:37.080 --> 00:44:38.080
Oder...?

00:44:38.080 --> 00:44:39.080
Das war lange...

00:44:39.080 --> 00:44:49.680
Also, in Pandas heißen die Dinger "Categorials" und das wurde dann quasi intern irgendwie auf Integers abgebildet.

00:44:49.680 --> 00:44:59.740
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.

00:44:59.740 --> 00:45:06.240
Und dann hat man halt so einen eigenen Datentyp bekommen, sodass es halt jetzt auch so ein First-Class-Citizen im Grunde ist.

00:45:06.240 --> 00:45:09.040
So, vorher war es halt auch immer so, naja, es sind komische Dinge passiert.

00:45:09.040 --> 00:45:15.740
Ich hatte zum Beispiel mal irgendwann mit Categoricals auch so ein Problem.

00:45:15.740 --> 00:45:29.620
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,

00:45:29.620 --> 00:45:39.020
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.

00:45:39.020 --> 00:45:46.300
Ja, aber genau, das ist natürlich eine sehr nette Sache, wenn man das halt so machen kann.

00:45:46.300 --> 00:45:55.420
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.

00:45:55.420 --> 00:45:57.420
Ja, praktisch.

00:45:57.420 --> 00:45:59.500
Wie schaut man sich denn so Daten dann an?

00:45:59.500 --> 00:46:00.820
Ich musste ja irgendwie eine Struktur bringen.

00:46:00.820 --> 00:46:08.660
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.

00:46:08.660 --> 00:46:29.140
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,

00:46:29.380 --> 00:46:31.660
äh, plotet das halt direkt.

00:46:31.660 --> 00:46:37.060
Dann kannst du ja dann Daten anzeigen, die du dann reingegeben hast, also ich, ähm, das, die Visualisierungsebene dann damit quasi.

00:46:37.060 --> 00:46:40.520
Genau, genau, in einem Notebook sieht man halt auch dann direkt irgendwie quasi grafisch was.

00:46:40.520 --> 00:46:56.580
Ä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.

00:46:56.580 --> 00:46:58.000
Ich hab Plotly schon gesehen.

00:46:58.000 --> 00:46:58.540
Plotly, genau.

00:46:59.260 --> 00:47:06.100
Und, äh, Seaborn ist ja im Prinzip Matplotlib nochmal ein bisschen erweitert, äh, kann man da auch rein, reinpluggen.

00:47:06.100 --> 00:47:29.140
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,

00:47:29.140 --> 00:47:52.840
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.

00:47:59.020 --> 00:48:28.900
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,

00:48:28.900 --> 00:48:58.240
ä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,

00:48:58.780 --> 00:49:26.120
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.

00:49:28.660 --> 00:49:46.800
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.

00:49:46.800 --> 00:49:50.200
Aber nur die roten oder die roten und die gelben vergleichen.

00:49:50.200 --> 00:49:58.540
Genau, ähm, das ist dann der zweite Schritt, äh, dass man anfängt vorher zu aggregieren, man kann dann überlegen, äh, will ich, ähm,

00:49:58.540 --> 00:50:12.500
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.

00:50:12.500 --> 00:50:15.560
Das ist was, was man auch aufplott, einfach plotten möchte.

00:50:15.560 --> 00:50:27.940
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.

00:50:28.420 --> 00:50:47.060
Ä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?

00:50:47.060 --> 00:50:58.120
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,

00:50:58.300 --> 00:51:14.060
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.

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

00:51:23.140 --> 00:51:28.180
Was wird denn der technische Erzeuger? Also macht der eine Kopie der Tabelle mit diesen Werten oder setzt der halt dann noch eine

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

00:51:35.260 --> 00:51:58.060
Ä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,

00:51:58.060 --> 00:52:14.860
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.

00:52:14.860 --> 00:52:24.580
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.

00:52:25.440 --> 00:52:30.120
Ähm, und, ähm, ja, ganz genau, wie das technisch unten drunter funktioniert, weiß ich jetzt aber auch nicht.

00:52:30.120 --> 00:52:43.480
Ä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.

00:52:43.480 --> 00:52:45.480
Egal, muss man halt nochmal genauer nachlesen.

00:52:45.480 --> 00:52:52.040
Ähm, ja, und, ähm, dann kann man da irgendwie weitere, weitere Dinge mitmachen.

00:52:52.040 --> 00:52:55.160
Das ist, äh, das ist halt recht, äh, recht schön, schönes.

00:52:55.320 --> 00:52:57.480
Schöne Methode, um da halt irgendwie Sachen rauszuselecten.

00:52:57.480 --> 00:53:09.080
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.

00:53:09.240 --> 00:53:10.240
und

00:53:10.240 --> 00:53:13.180
ist von Tom Augsburger

00:53:13.180 --> 00:53:17.260
ja genau, das heißt

00:53:17.260 --> 00:53:18.480
Modern Pandas

00:53:18.480 --> 00:53:21.700
und das ist Teil 1

00:53:21.700 --> 00:53:23.400
bis, ich weiß gar nicht wie viel es gibt

00:53:23.400 --> 00:53:25.700
bis 8

00:53:25.700 --> 00:53:26.340
momentan

00:53:26.340 --> 00:53:30.020
kenne ich noch gar nicht, muss ich auch mal reinschauen

00:53:30.020 --> 00:53:32.000
so lernt man

00:53:32.000 --> 00:53:32.580
immer dazu

00:53:32.580 --> 00:53:35.880
genau und der beschreibt halt

00:53:35.880 --> 00:53:37.340
sehr ausführlich wie das mit diesem Indexing

00:53:37.340 --> 00:53:39.700
aus Userperspektive, was man damit alles machen kann

00:53:39.700 --> 00:53:41.000
funktioniert

00:53:41.000 --> 00:53:43.840
und ja

00:53:43.840 --> 00:53:45.740
also gerade wenn man jetzt nicht nur einen Index hat

00:53:45.740 --> 00:53:47.660
das ist auch etwas, was halt Pandas kennt

00:53:47.660 --> 00:53:49.540
was ich von Datenbanken so nicht kenne

00:53:49.540 --> 00:53:51.220
also Datenbanken bedeuten Indizes

00:53:51.220 --> 00:53:53.060
ein bisschen was anderes als halt jetzt bei Pandas

00:53:53.060 --> 00:53:55.600
man kann halt bei Pandas auch mehrdimensional

00:53:55.600 --> 00:53:57.160
Indizes haben und dann halt irgendwie

00:53:57.160 --> 00:53:59.380
kreuz und quer verschachtelte Abfragen macht

00:53:59.380 --> 00:54:00.480
und da

00:54:00.480 --> 00:54:03.160
wenn man das sich so zuerst anguckt, dann

00:54:03.160 --> 00:54:05.080
raucht einem da relativ schnell so der Kopf

00:54:05.080 --> 00:54:07.240
aber wenn man tatsächlich diese Probleme

00:54:07.240 --> 00:54:09.180
hat, dann kann das ultra praktisch sein

00:54:09.180 --> 00:54:10.520
wenn man da irgendwie sich mit auskennt

00:54:10.520 --> 00:54:13.000
und diese Modern Pandas Serie ist halt eine

00:54:13.000 --> 00:54:14.620
wo man das sehr schön

00:54:14.620 --> 00:54:16.280
sehen kann, wie das funktioniert

00:54:16.280 --> 00:54:19.020
im ersten Artikel werden glaube ich

00:54:19.020 --> 00:54:19.760
da irgendwie so halt

00:54:19.760 --> 00:54:22.880
diverse Indize-Geschichten erklärt

00:54:22.880 --> 00:54:24.820
und dann gibt es halt einen Artikel

00:54:24.820 --> 00:54:25.960
nur zu Method-Chaining

00:54:25.960 --> 00:54:28.040
und ja

00:54:28.040 --> 00:54:30.380
dann eins zu Indizes

00:54:30.380 --> 00:54:32.040
und da wird dann auch nochmal das alte

00:54:32.040 --> 00:54:33.500
Interface

00:54:33.500 --> 00:54:36.140
gezeigt und halt was man jetzt

00:54:36.140 --> 00:54:37.140
mit dem

00:54:37.140 --> 00:54:39.000
neuen Interface an Dingen machen kann und da gibt es halt

00:54:39.000 --> 00:54:41.280
wirklich verrückte Abfragen

00:54:41.280 --> 00:54:41.640
die man

00:54:41.640 --> 00:54:42.700
also

00:54:42.700 --> 00:54:46.420
super spannend, was der neueste heiße Scheiß ist

00:54:46.420 --> 00:54:48.900
was ich jetzt da gekannt habe, ist auch die einzige Quelle

00:54:48.900 --> 00:54:50.560
deswegen habe ich jetzt den Vergleich natürlich wieder nicht

00:54:50.560 --> 00:54:52.300
ist diese Einführung in

00:54:52.300 --> 00:54:54.920
Python mit Data Science oder Data Science

00:54:54.920 --> 00:54:56.540
mit Python von Jake Wanderplast

00:54:56.540 --> 00:54:58.320
da ist auch ein schönes Artikel

00:54:58.320 --> 00:55:00.640
zu Pandas drin, das ist auch frei

00:55:00.640 --> 00:55:01.660
irgendwo bei GitHub

00:55:01.660 --> 00:55:04.920
und sogar als Notebooks

00:55:04.920 --> 00:55:06.920
die er alle gebraucht hat, da hat er irgendwie unter MIT

00:55:06.920 --> 00:55:07.900
die Lizenz da online gestellt

00:55:07.900 --> 00:55:10.780
und da kann man auch genau die Sachen als Notebooks direkt alle ausprobieren

00:55:10.780 --> 00:55:12.580
das ist ein tolles Beispiel für diese, glaube ich, die

00:55:12.580 --> 00:55:15.000
einfachen, so die Basissachen

00:55:15.000 --> 00:55:16.820
drin, dass man das grundsätzliche alte Prinzip mal

00:55:16.820 --> 00:55:18.720
versteht, das man direkt da mit Pandas potten kann

00:55:18.720 --> 00:55:21.040
ich glaube über den Untergang der Titanic oder sowas

00:55:21.040 --> 00:55:21.380
Ah ja

00:55:21.380 --> 00:55:24.740
Ja, sonst benutzen die Tutorials

00:55:24.740 --> 00:55:26.600
oft gerne den Iris-Datensatz

00:55:26.600 --> 00:55:28.620
da geht es irgendwie um Blütenlänge

00:55:28.620 --> 00:55:29.740
und Breite und

00:55:29.740 --> 00:55:32.700
das war mir immer ein bisschen sympathischer als Biologe

00:55:32.700 --> 00:55:34.740
Also welche

00:55:34.740 --> 00:55:36.800
Klassen jetzt wie oder wie viele Frauen, Männer und

00:55:36.800 --> 00:55:37.860
wie viele Jungs und Kinder

00:55:37.860 --> 00:55:39.440
untergegangen sind, wie viele nicht

00:55:39.440 --> 00:55:42.700
Das ist auch super spannend mit diesen

00:55:42.700 --> 00:55:44.480
Multi-Level-Indizes

00:55:44.480 --> 00:55:46.520
da sollten wir gleich auch nochmal vielleicht

00:55:46.520 --> 00:55:48.780
ein paar Minuten uns Zeit für nehmen

00:55:48.780 --> 00:55:50.860
Für den

00:55:50.860 --> 00:55:52.880
Moment sei vielleicht

00:55:52.880 --> 00:55:54.580
auch nochmal erwähnt, wenn man jetzt ein Pandas

00:55:54.580 --> 00:55:56.620
DataFrame haben möchte und man

00:55:56.620 --> 00:55:58.880
importiert das nicht aus einer Datei

00:55:58.880 --> 00:56:00.520
oder aus der Zwischenablage

00:56:00.520 --> 00:56:02.780
wie komme ich denn überhaupt zu meinem

00:56:02.780 --> 00:56:04.780
DataFrame-Objekt und du hast eben gefragt

00:56:04.780 --> 00:56:06.640
kann man da vielleicht Dictronix benutzen? Ja, kann man

00:56:06.640 --> 00:56:08.640
tatsächlich. Also wenn ich in

00:56:08.640 --> 00:56:10.640
Python schon ein Dictronary habe

00:56:10.640 --> 00:56:12.640
was Keys und

00:56:12.640 --> 00:56:14.640
als Values Listen hat

00:56:14.640 --> 00:56:16.640
dann kann ich einfach

00:56:16.640 --> 00:56:18.640
mein DataFrame erzeugen mit

00:56:18.640 --> 00:56:20.640
pandas.dataframe oder

00:56:20.640 --> 00:56:22.640
pd.dataframe, wenn man Pandas als

00:56:22.640 --> 00:56:24.640
pd importiert

00:56:24.640 --> 00:56:26.640
und da reingeben, mein Dictronary

00:56:26.640 --> 00:56:28.640
dann macht er automatisch

00:56:28.640 --> 00:56:30.640
aus den Keys Spaltennamen

00:56:30.640 --> 00:56:32.640
und aus den Values, aus den Listen macht

00:56:32.640 --> 00:56:34.640
er dann meine Series

00:56:34.640 --> 00:56:36.720
hat natürlich

00:56:36.720 --> 00:56:38.700
zur Bedingung, dass die gleich lang sind

00:56:38.700 --> 00:56:40.600
sonst gibt es da einen Fehler

00:56:40.600 --> 00:56:42.800
ich weiß gar nicht, ob der da mit na auffüllt

00:56:42.800 --> 00:56:43.660
oder ob der

00:56:43.660 --> 00:56:46.640
ja, ich bin mir gar nicht sicher

00:56:46.640 --> 00:56:48.880
außer an das ein Fehler wirft, ich weiß es aber auch nicht

00:56:48.880 --> 00:56:50.600
es gibt auch irgendwie so eine andere Funktion, ich weiß

00:56:50.600 --> 00:56:52.800
jetzt nicht, bei was es genau geht, wenn man halt so ein DataFrame

00:56:52.800 --> 00:56:54.340
über so ein NumPy-Array hat oder sowas

00:56:54.340 --> 00:56:56.760
dass der automatisch neue Spalten erzeugen

00:56:56.760 --> 00:56:58.080
kann, die er dann irgendwie

00:56:58.080 --> 00:57:00.620
fortsetzt, ich weiß nicht, ob das linear passiert

00:57:00.620 --> 00:57:02.160
oder sowas, habe ich irgendwie kurz entdeckt

00:57:02.160 --> 00:57:04.480
wenn man einfach eine neue Spalte erstellt

00:57:04.480 --> 00:57:06.280
dann, wenn man schon drei oder vier hat, dass

00:57:06.280 --> 00:57:08.200
du dann, wenn du die fünfte erstellst, einfach dann

00:57:08.200 --> 00:57:09.480
neue Werte reinbaut

00:57:09.480 --> 00:57:12.520
kann sein, weiß ich nicht

00:57:12.520 --> 00:57:14.280
vielleicht habe ich auch wieder

00:57:14.280 --> 00:57:15.480
irgendwelchen Quatsch erzählt, ich weiß nicht

00:57:15.480 --> 00:57:17.600
gerade nicht genau, was du da

00:57:17.600 --> 00:57:18.480
meinst

00:57:18.480 --> 00:57:22.120
jetzt habe ich das Buch natürlich zu Hause liegen lassen

00:57:22.120 --> 00:57:23.900
irgendwo nachgeschlagen

00:57:23.900 --> 00:57:26.100
Buch ist aber auch ein gutes

00:57:26.100 --> 00:57:27.900
Stichwort, man

00:57:27.900 --> 00:57:29.960
kriegt ja immer den gut gemeinten Ratschlag

00:57:29.960 --> 00:57:31.360
guck doch mal ins Handbuch

00:57:31.360 --> 00:57:34.160
das Pandas Handbuch ist tatsächlich

00:57:34.320 --> 00:57:35.800
länglich, es hat

00:57:35.800 --> 00:57:37.780
2900 irgendwas Seiten

00:57:37.780 --> 00:57:39.840
davon sind

00:57:39.840 --> 00:57:42.040
rund 900 so die Basisfunktionen

00:57:42.040 --> 00:57:44.160
1400 nur die

00:57:44.160 --> 00:57:46.060
API-Referenz und dann

00:57:46.060 --> 00:57:48.060
nochmal weiterführende

00:57:48.060 --> 00:57:49.080
Informationen

00:57:49.080 --> 00:57:50.320
Hast du das durchgelesen?

00:57:50.320 --> 00:57:50.500
Nee

00:57:50.500 --> 00:57:54.320
So bei aller Liebe, das ist dann

00:57:54.320 --> 00:57:55.360
doch etwas viel, aber

00:57:55.360 --> 00:57:58.720
man kann halt relativ schnell kapitelweise

00:57:58.720 --> 00:58:00.120
wenn man was ganz

00:58:00.120 --> 00:58:01.480
bestimmtes sucht, da reinspringen

00:58:01.480 --> 00:58:04.160
Es ist auch alles, also verlinkte

00:58:04.160 --> 00:58:06.840
wie heißt das, Table of Contents

00:58:06.840 --> 00:58:08.000
Inhaltsverzeichnis, genau

00:58:08.000 --> 00:58:11.000
verlinktes Inhaltsverzeichnis, man kommt schnell dahin

00:58:11.000 --> 00:58:13.460
Ja

00:58:13.460 --> 00:58:15.060
Ja, die Dokumentation

00:58:15.060 --> 00:58:16.440
von Pandas ist auch sehr gut, aber auch manchmal

00:58:16.440 --> 00:58:18.920
die ist schon etwas trocken

00:58:18.920 --> 00:58:20.420
manchmal muss man sich schon so ein bisschen

00:58:20.420 --> 00:58:22.280
ein bisschen quälen

00:58:22.280 --> 00:58:23.960
Vielleicht liegt das an dem Tabellenthema

00:58:23.960 --> 00:58:26.380
Könnte auch, vielleicht liegt es einfach am Thema

00:58:26.380 --> 00:58:29.120
Sollte man vielleicht eher irgendwie Schreiner werden

00:58:29.120 --> 00:58:29.620
oder so

00:58:29.620 --> 00:58:30.900
Das ist eigentlich total langweilig

00:58:30.900 --> 00:58:34.000
Ja, das überlege ich mir manchmal

00:58:34.000 --> 00:58:35.560
Das wäre toll

00:58:35.560 --> 00:58:37.700
Ja, aber

00:58:37.700 --> 00:58:39.980
genau

00:58:39.980 --> 00:58:43.960
Stimmt, was hatten wir erwähnt

00:58:43.960 --> 00:58:45.760
Was gibt es für Datentypen

00:58:45.760 --> 00:58:48.040
so in Serien, Data Frames, Panels

00:58:48.040 --> 00:58:50.240
Was kann man damit machen

00:58:50.240 --> 00:58:51.180
Ja, so, genau

00:58:51.180 --> 00:58:54.300
Man kann auch sehr viele Dinge

00:58:54.300 --> 00:58:56.480
die man sonst vielleicht mit einer Datenbank machen würde

00:58:56.480 --> 00:58:58.340
damit tun und das hätte ja auch so den Vorteil

00:58:58.340 --> 00:58:59.640
Also das kann ich auch nur, ich finde

00:58:59.640 --> 00:59:02.140
die Art, also das User Interface

00:59:02.140 --> 00:59:03.840
von Pandas ist halt

00:59:03.840 --> 00:59:05.840
ziemlich angenehm und ist auch relativ kurz

00:59:05.840 --> 00:59:07.840
also wenn man in einer Datenbank arbeitet

00:59:07.840 --> 00:59:09.840
und da SQL Statements schreibt, das geht natürlich auch

00:59:09.840 --> 00:59:11.840
aber das ist halt viel

00:59:11.840 --> 00:59:13.840
viel umständlicher

00:59:13.840 --> 00:59:15.840
und Pandas hat halt eine sehr schöne

00:59:15.840 --> 00:59:17.840
sehr schöne

00:59:17.840 --> 00:59:19.840
sehr schöne UI eigentlich

00:59:19.840 --> 00:59:21.840
und man kann viel damit machen

00:59:21.840 --> 00:59:23.840
was man halt auch in einer Datenbank normalerweise tun würde

00:59:23.840 --> 00:59:25.840
und insofern kann ich das auch nur empfehlen, wenn man jetzt irgendwie

00:59:25.840 --> 00:59:27.840
so ein Datenbankproblem hat, man kann auch irgendwie die komplette

00:59:27.840 --> 00:59:29.840
Datenbank, meistens sind die ja nicht so groß, auch irgendwie

00:59:29.840 --> 00:59:31.840
in Pandas sich reinholen oder als Data Frames

00:59:31.840 --> 00:59:33.680
aus der Datenbank ziehen und dann da

00:59:33.680 --> 00:59:35.680
irgendwelche Dinge machen und dann schon mal

00:59:35.680 --> 00:59:37.680
wenn man dann weiß, wie es geht, dann kann man es hinterher auch

00:59:37.680 --> 00:59:39.680
in SQL machen, aber vieles

00:59:39.680 --> 00:59:41.680
von dem lässt sich auch locker

00:59:41.680 --> 00:59:43.680
in Pandas mal ausprobieren, weil Pandas hat ja eben auch solche

00:59:43.680 --> 00:59:45.680
Funktionen wie, man kann Joins

00:59:45.680 --> 00:59:47.680
machen, man kann halt Data Frames Merge

00:59:47.680 --> 00:59:49.680
also da heißt das dann, also vielleicht

00:59:49.680 --> 00:59:51.680
verwendet man eher den Aufruf Merge oder so

00:59:51.680 --> 00:59:53.680
aber im Grunde macht das dann halt auch

00:59:53.680 --> 00:59:55.680
ein Join zwischen zwei Data Frames, dann kann man

00:59:55.680 --> 00:59:57.680
angeben, auf welchen Spalten gejoint

00:59:57.680 --> 00:59:59.680
werden soll und solche Dinge

00:59:59.680 --> 01:00:01.680
und genau, eben all diese

01:00:01.680 --> 01:00:03.520
Group-By-Geschichten

01:00:03.520 --> 01:00:05.520
gibt es tatsächlich so eine Funktion, wie man eine Datenbank in

01:00:05.520 --> 01:00:07.520
Data Frame bekommt und andersrum, wie man eine

01:00:07.520 --> 01:00:09.520
Data Frame, wie man irgendeinen Datenbank-Typen speichert?

01:00:09.520 --> 01:00:11.520
Naja, also für alle Datenbanken

01:00:11.520 --> 01:00:13.520
gibt es da Adapter, mit denen man

01:00:13.520 --> 01:00:15.520
die Daten auch auslesen kann, ja.

01:00:15.520 --> 01:00:17.520
Genau, also diese Import-Export-Geschichten

01:00:17.520 --> 01:00:19.520
also wir haben nur über Import

01:00:19.520 --> 01:00:21.520
gesprochen, aber

01:00:21.520 --> 01:00:23.520
Export gibt es halt auch für alle diese

01:00:23.520 --> 01:00:25.520
Daten-Typen. Warum schreibt dann irgendjemand noch

01:00:25.520 --> 01:00:27.520
SQL-Statements?

01:00:27.520 --> 01:00:29.520
Ja doch, also manchmal

01:00:29.520 --> 01:00:31.520
es kann schon sinnvoll

01:00:31.520 --> 01:00:33.360
durchaus sinnvoll sein,

01:00:33.360 --> 01:00:35.360
also wenn du in der Datenbank ja auch irgendwas manipulieren

01:00:35.360 --> 01:00:37.360
willst an Werten, dann musst du es ja tun,

01:00:37.360 --> 01:00:39.360
kannst ja gar nicht, kannst du auch in Pandas machen,

01:00:39.360 --> 01:00:41.360
aber dann hast du das Problem, musst du es ja irgendwie wieder zurück in die Datenbank

01:00:41.360 --> 01:00:43.360
schreiben und dann...

01:00:43.360 --> 01:00:45.360
Dann markierst du eine neue Datenbank.

01:00:45.360 --> 01:00:47.360
Ja, und gegebenenfalls

01:00:47.360 --> 01:00:49.360
ist das, was du in deinem Speicher

01:00:49.360 --> 01:00:51.360
bearbeiten kannst, auch

01:00:51.360 --> 01:00:53.360
kleiner als das, was

01:00:53.360 --> 01:00:55.360
in der gesamten Datenbank ist, das heißt,

01:00:55.360 --> 01:00:57.360
beim Import würdest du schon nur einen Teil aus der

01:00:57.360 --> 01:00:59.360
Datenbank nehmen, kannst damit aber

01:00:59.360 --> 01:01:01.360
dann relativ komfortabel rumspielen.

01:01:01.360 --> 01:01:03.200
Ja.

01:01:03.200 --> 01:01:05.200
Tatsächlich, der Befehl

01:01:05.200 --> 01:01:07.200
ist Join, auch in

01:01:07.200 --> 01:01:09.200
DataFrames. Ich verwechsel das auch immer wieder,

01:01:09.200 --> 01:01:11.200
deswegen habe ich gerade mal kurz nachgeguckt.

01:01:11.200 --> 01:01:13.200
Und es gibt noch Concatenate,

01:01:13.200 --> 01:01:15.200
da kann man aus einem DataFrame irgendwie

01:01:15.200 --> 01:01:17.200
Spalten in ein

01:01:17.200 --> 01:01:19.200
anderes reinziehen.

01:01:19.200 --> 01:01:21.200
Ja, und dann genau

01:01:21.200 --> 01:01:23.200
solche, eben es gibt

01:01:23.200 --> 01:01:25.200
so Datenmanipulationsgeschichten,

01:01:25.200 --> 01:01:27.200
eben Join, Merge,

01:01:27.200 --> 01:01:29.200
dann gibt es noch

01:01:29.200 --> 01:01:31.200
solche Sachen wie,

01:01:31.200 --> 01:01:33.040
genau, das ist auch schwer

01:01:33.040 --> 01:01:35.040
zu erklären, wenn man das jetzt nur hört,

01:01:35.040 --> 01:01:37.040
fürchte ich,

01:01:37.040 --> 01:01:39.040
sowas wie Pivot,

01:01:39.040 --> 01:01:41.040
Unpivot, Melt,

01:01:41.040 --> 01:01:43.040
Stack, Unstack, so sehr praktische

01:01:43.040 --> 01:01:45.040
Geschichten, aber ich weiß jetzt ehrlich gesagt nicht genau,

01:01:45.040 --> 01:01:47.040
wie ich das erklären kann. Ja, du kannst,

01:01:47.040 --> 01:01:49.040
also wenn du, hm, okay, ich versuch's

01:01:49.040 --> 01:01:51.040
mal einfach, wenn du jetzt,

01:01:51.040 --> 01:01:53.040
du machst im Grunde aus einer,

01:01:53.040 --> 01:01:55.040
aus

01:01:55.040 --> 01:01:57.040
Dingen, die in einer Spalte

01:01:57.040 --> 01:01:59.040
stehen, machst du mit Pivot

01:01:59.040 --> 01:02:01.040
irgendwie zusätzliche Spalten.

01:02:01.040 --> 01:02:02.880
Achso, ich bin gerade völlig auf

01:02:02.880 --> 01:02:04.880
den Kopf gefallen, ich hab's natürlich mit der Transformation gerade

01:02:04.880 --> 01:02:06.880
verwechselt. Ja, so Transpose,

01:02:06.880 --> 01:02:08.880
ja, das ist natürlich, das ist

01:02:08.880 --> 01:02:10.880
relativ einfach, aber Pivot, das macht schon

01:02:10.880 --> 01:02:12.880
so ein bisschen kompliziertere Dinge. Das aggregiert

01:02:12.880 --> 01:02:14.880
irgendwas zur besseren Auswertung.

01:02:14.880 --> 01:02:16.880
Einen Widerfall,

01:02:16.880 --> 01:02:18.880
doch? Ne, das, das,

01:02:18.880 --> 01:02:20.880
ja, also manchmal hat man Daten halt in einem Format,

01:02:20.880 --> 01:02:22.880
in dem man schlecht plotten kann.

01:02:22.880 --> 01:02:24.880
Und manchmal braucht man

01:02:24.880 --> 01:02:26.880
halt Dinge, die in einer Zeile, die

01:02:26.880 --> 01:02:28.880
irgendwo in einer Zeile stehen, die möchte man als Spalte haben,

01:02:28.880 --> 01:02:30.880
um dann halt die Spalte besser plotten zu können, und dafür

01:02:30.880 --> 01:02:32.720
fällt man dann auf Pivot. Und dann, äh,

01:02:32.720 --> 01:02:34.720
äh, genau, die umgekehrte Funktion

01:02:34.720 --> 01:02:36.720
dazu ist Melt, äh, und,

01:02:36.720 --> 01:02:38.720
ähm, die, äh,

01:02:38.720 --> 01:02:40.720
aber eigentlich noch allgemeineren Funktionen,

01:02:40.720 --> 01:02:42.720
die funktionieren dann eben auf so, äh,

01:02:42.720 --> 01:02:44.720
Multilevel-Indizesen, halt Stack und Unstack.

01:02:44.720 --> 01:02:46.720
Ja. Aber das kann auch sehr schnell,

01:02:46.720 --> 01:02:48.720
äh, einen so ein bisschen überfordern.

01:02:48.720 --> 01:02:50.720
Also ich kann sagen, so aus

01:02:50.720 --> 01:02:52.720
dem Biologen-Alltag, dass ich Pivot

01:02:52.720 --> 01:02:54.720
und Melt nie benutzt hab, ähm, einfach,

01:02:54.720 --> 01:02:56.720
weil, weil die vielleicht

01:02:56.720 --> 01:02:58.720
auch zu viel Magie im Hintergrund noch machen

01:02:58.720 --> 01:03:00.720
können. Äh, Stack und Unstack

01:03:00.720 --> 01:03:02.560
aber sehr häufig, weil, äh,

01:03:02.560 --> 01:03:04.560
in der, in der Realität

01:03:04.560 --> 01:03:06.560
sind, äh, wir hatten ja eingangs

01:03:06.560 --> 01:03:08.560
über die Excel-Tabellen gesprochen,

01:03:08.560 --> 01:03:10.560
die nicht immer ganz maschinenlesbar sind.

01:03:10.560 --> 01:03:12.560
Es gibt noch den Zwischenwert,

01:03:12.560 --> 01:03:14.560
wo die zwar maschinenlesbar sind,

01:03:14.560 --> 01:03:16.560
aber mehrere Level von Indizes

01:03:16.560 --> 01:03:18.560
haben, und, äh, wenn

01:03:18.560 --> 01:03:20.560
die mehrere Level von Indizes haben,

01:03:20.560 --> 01:03:22.560
man könnte sich das zum Beispiel vorstellen

01:03:22.560 --> 01:03:24.560
wie, ähm,

01:03:24.560 --> 01:03:26.560
ähm, weiß ich nicht,

01:03:26.560 --> 01:03:28.560
ein, äh,

01:03:28.560 --> 01:03:30.560
ich hatte eben noch

01:03:30.560 --> 01:03:32.400
ein Beispiel im Kopf, äh, äh,

01:03:32.400 --> 01:03:34.400
äh, sowas wie, äh,

01:03:34.400 --> 01:03:36.400
Klausurnoten nach Semestern

01:03:36.400 --> 01:03:38.400
in zwei verschiedenen

01:03:38.400 --> 01:03:40.400
Gruppen, sagen wir mal,

01:03:40.400 --> 01:03:42.400
Biologen versus Chemiker oder sowas,

01:03:42.400 --> 01:03:44.400
ähm, wie die in der Chemieklausur

01:03:44.400 --> 01:03:46.400
abschneiden im ersten Semester,

01:03:46.400 --> 01:03:48.400
im zweiten Semester. Und

01:03:48.400 --> 01:03:50.400
dann hat man diese Gruppierung einmal,

01:03:50.400 --> 01:03:52.400
ähm, zu welcher Gruppe

01:03:52.400 --> 01:03:54.400
gehören die Personen an, aber

01:03:54.400 --> 01:03:56.400
dann hat man auch, äh, für

01:03:56.400 --> 01:03:58.400
jede Zeile im Prinzip eine spezifische

01:03:58.400 --> 01:04:00.400
Person.

01:04:00.400 --> 01:04:02.240
Das heißt, mehrere Personen

01:04:02.240 --> 01:04:04.240
teilen die gleiche Gruppe,

01:04:04.240 --> 01:04:06.240
also Biologe oder Chemiker,

01:04:06.240 --> 01:04:08.240
ähm, aber jede Person hat

01:04:08.240 --> 01:04:10.240
eigene Noten in Semester 1,

01:04:10.240 --> 01:04:12.240
in Semester 2. Wenn man das

01:04:12.240 --> 01:04:14.240
jetzt, jetzt muss ich kurz überlegen, in welche

01:04:14.240 --> 01:04:16.240
Richtung man das stacken würde,

01:04:16.240 --> 01:04:18.240
dann würde man im Prinzip

01:04:18.240 --> 01:04:20.240
sagen, ich, ähm,

01:04:20.240 --> 01:04:22.240
schreibe jetzt

01:04:22.240 --> 01:04:24.240
jede

01:04:24.240 --> 01:04:26.240
Person einzeln als Zeile

01:04:26.240 --> 01:04:28.240
auf und habe eine neue Spalte, wo

01:04:28.240 --> 01:04:30.240
die Gruppe nochmal als sich wiederholender

01:04:30.240 --> 01:04:32.080
Wert mit drin steht.

01:04:32.080 --> 01:04:34.080
Sodass ich wegkomme von

01:04:34.080 --> 01:04:36.080
ich habe, ähm, im Prinzip

01:04:36.080 --> 01:04:38.080
zwei Zeilen, die jeweils vier Unterzeilen

01:04:38.080 --> 01:04:40.080
beinhalten, zu ich

01:04:40.080 --> 01:04:42.080
habe einfach acht Zeilen, äh,

01:04:42.080 --> 01:04:44.080
wo in, in jeder dieser

01:04:44.080 --> 01:04:46.080
Zeilen die Gruppe nochmal explizit drinsteht.

01:04:46.080 --> 01:04:48.080
Ähm, das

01:04:48.080 --> 01:04:50.080
macht es dann einfacher nachher Gruppierungen

01:04:50.080 --> 01:04:52.080
zu machen. Außerdem könnte

01:04:52.080 --> 01:04:54.080
man dann mit Unstack in die andere

01:04:54.080 --> 01:04:56.080
Richtung wieder sagen, ich möchte das jetzt

01:04:56.080 --> 01:04:58.080
gar nicht nach den Gruppierungen unstacken, sondern

01:04:58.080 --> 01:05:00.080
nach Semestern zum Beispiel. Und dann

01:05:00.080 --> 01:05:01.920
tauscht man plötzlich die, die Spalte

01:05:01.920 --> 01:05:03.920
identitäten. Aber ja, also,

01:05:03.920 --> 01:05:05.920
Tabellentransformationen

01:05:05.920 --> 01:05:07.920
einfach nur in einem Audio-Podcast zu erklären,

01:05:07.920 --> 01:05:09.920
ist sehr schwierig.

01:05:09.920 --> 01:05:11.920
Genau, ich, ja, ich weiß gar nicht, ob

01:05:11.920 --> 01:05:13.920
es, ob es zu dem Stack-an-Stack oder so, äh,

01:05:13.920 --> 01:05:15.920
äh, Thema halt auch ein Modern

01:05:15.920 --> 01:05:17.920
Pandas Artikel gibt.

01:05:17.920 --> 01:05:19.920
Ich fürchte, nein. Ah, schade.

01:05:19.920 --> 01:05:21.920
Ah ja, muss man einfach mal nach, äh, also,

01:05:21.920 --> 01:05:23.920
na ja, ich verlinke da einfach mal einen Artikel zu,

01:05:23.920 --> 01:05:25.920
wie das, wie das so aussieht. Wenn man das sieht,

01:05:25.920 --> 01:05:27.920
ist es eigentlich, dann kann man's, kann man's deutlich

01:05:27.920 --> 01:05:29.920
besser verstehen. Ja.

01:05:29.920 --> 01:05:31.760
Genau, das sind so die Dinge, die man dann, dann

01:05:31.760 --> 01:05:33.760
mit dann tut. Hm.

01:05:33.760 --> 01:05:35.760
Ja.

01:05:35.760 --> 01:05:37.760
Äh.

01:05:37.760 --> 01:05:39.760
Ja, vielleicht noch mal dieser Pivot, äh, kurz, das

01:05:39.760 --> 01:05:41.760
wart ihr gerade kurz dabei, das sind wir kurz abgeschweift.

01:05:41.760 --> 01:05:43.760
Mhm. Also, was macht man damit

01:05:43.760 --> 01:05:45.760
jetzt genau? Also, ich kenne das irgendwie jetzt auch irgendwie aus Excel, wenn man

01:05:45.760 --> 01:05:47.760
eine Auswertung hat, man hat dann irgendwelche Datenblätter

01:05:47.760 --> 01:05:49.760
oder sowas, und dann möchte man dann

01:05:49.760 --> 01:05:51.760
irgendwelche Aggregate

01:05:51.760 --> 01:05:53.760
irgendeinem Endnutzer auf einem

01:05:53.760 --> 01:05:55.760
Auswertungs-Dashboard zur Verfügung

01:05:55.760 --> 01:05:57.760
stellen. Und da wird dann irgendwas zusammen

01:05:57.760 --> 01:05:59.760
gerechnet.

01:05:59.760 --> 01:06:01.600
Hm.

01:06:01.600 --> 01:06:03.600
Ja, Excel genau kann ja auch sowas

01:06:03.600 --> 01:06:05.600
so, Pivot-Tabellen. Ja. Also, ich hab hier

01:06:05.600 --> 01:06:07.600
gerade mal das, das, äh, Data Science

01:06:07.600 --> 01:06:09.600
Cheat-Cheat-Panda ist offen. Ah.

01:06:09.600 --> 01:06:11.600
Können wir auch nachher verlinken. Ja.

01:06:11.600 --> 01:06:13.600
Ähm, und da steht im Wesentlichen drin,

01:06:13.600 --> 01:06:15.600
dass, äh, Pivot-Table,

01:06:15.600 --> 01:06:17.600
wie gesagt, ich hab's noch nie benutzt, aber dass es, ähm,

01:06:17.600 --> 01:06:19.600
eine

01:06:19.600 --> 01:06:21.600
Pivot-Tabelle macht, die

01:06:21.600 --> 01:06:23.600
äh, die

01:06:23.600 --> 01:06:25.600
anhand von einer Spalte

01:06:25.600 --> 01:06:27.600
gruppiert, und dann

01:06:27.600 --> 01:06:29.600
aber über andere Spalten eine Funktion

01:06:29.600 --> 01:06:31.440
aufruft. Das kann zum Beispiel sowas sein,

01:06:31.440 --> 01:06:33.440
wie Mittelwert oder eine Summe oder

01:06:33.440 --> 01:06:35.440
ähm, nahezu

01:06:35.440 --> 01:06:37.440
beliebige Funktionen.

01:06:37.440 --> 01:06:39.440
Hm.

01:06:39.440 --> 01:06:41.440
Möglicherweise

01:06:41.440 --> 01:06:43.440
hab ich das auch nie

01:06:43.440 --> 01:06:45.440
benutzt, weil ich die Excel-Funktion

01:06:45.440 --> 01:06:47.440
nie benutzt hab. Ähm,

01:06:47.440 --> 01:06:49.440
was ich allerdings öfter benutzt hab,

01:06:49.440 --> 01:06:51.440
ist, äh, die Funktion Apply.

01:06:51.440 --> 01:06:53.440
Und Apply erlaubt einem jetzt

01:06:53.440 --> 01:06:55.440
innerhalb eines Data Frames an,

01:06:55.440 --> 01:06:57.440
auf, auf Basis einer

01:06:57.440 --> 01:06:59.440
Achse sozusagen, eine

01:06:59.440 --> 01:07:01.280
Funktion auszuführen. Das kann auch wieder

01:07:01.280 --> 01:07:03.280
nur Mittelwert oder Standardabweichung

01:07:03.280 --> 01:07:05.280
sein. Das können aber

01:07:05.280 --> 01:07:07.280
auch, äh, komplexere Funktionen

01:07:07.280 --> 01:07:09.280
sein. Und, ähm,

01:07:09.280 --> 01:07:11.280
also

01:07:11.280 --> 01:07:13.280
für, für die, die vielleicht schon Hintergrund

01:07:13.280 --> 01:07:15.280
in R haben, da gibt's, äh,

01:07:15.280 --> 01:07:17.280
T-Apply und L-Apply für

01:07:17.280 --> 01:07:19.280
Zeilen, Spalten und was weiß

01:07:19.280 --> 01:07:21.280
ich nicht alles. In Pandas

01:07:21.280 --> 01:07:23.280
Data Frames gibt's im Wesentlichen Apply und

01:07:23.280 --> 01:07:25.280
man gibt die Achse an. Also soll das

01:07:25.280 --> 01:07:27.280
auf Reihen, auf Spalten,

01:07:27.280 --> 01:07:29.280
äh, äh, agieren. Hm.

01:07:29.280 --> 01:07:31.120
Und dann gibt man eine Funktion an und die

01:07:31.120 --> 01:07:33.120
wird dann entsprechend für

01:07:33.120 --> 01:07:35.120
eine komplette Spalte oder eine komplette

01:07:35.120 --> 01:07:37.120
Zeile ausgeführt.

01:07:37.120 --> 01:07:39.120
Ja, das ist vielleicht eben, genau, das ist auch noch ein ganz wichtiger

01:07:39.120 --> 01:07:41.120
Punkt, den wir noch gar nicht erwähnt haben, dass

01:07:41.120 --> 01:07:43.120
man, man kann, was man nicht tun sollte,

01:07:43.120 --> 01:07:45.120
äh, äh, über Data Frames iterieren

01:07:45.120 --> 01:07:47.120
und dann in der Vorschleife da irgendwelche

01:07:47.120 --> 01:07:49.120
Dinge mitmachen. Ja, das könnte man sich auch vorstellen,

01:07:49.120 --> 01:07:51.120
dass man das so tut, weil

01:07:51.120 --> 01:07:53.120
das, wenn man das, äh, wenn man

01:07:53.120 --> 01:07:55.120
aus Python kommt, äh, dann macht man das ja mit

01:07:55.120 --> 01:07:57.120
Listen normalerweise so. Aber, äh,

01:07:57.120 --> 01:07:59.120
das geht halt nicht, oder das geht schon,

01:07:59.120 --> 01:08:00.960
ist halt nur dann sehr, sehr langsam.

01:08:00.960 --> 01:08:02.960
Äh, während halt, wenn man jetzt

01:08:02.960 --> 01:08:04.960
Apply aufruft, dann, äh, ist das halt

01:08:04.960 --> 01:08:06.960
ziemlich schnell.

01:08:06.960 --> 01:08:08.960
Äh, weil unten drunter, äh,

01:08:08.960 --> 01:08:10.960
weil eben, also, vor, vor Loops in Python

01:08:10.960 --> 01:08:12.960
sowieso langsam sind und man dann eben

01:08:12.960 --> 01:08:14.960
keine Vorloop machen muss, sondern das läuft halt

01:08:14.960 --> 01:08:16.960
alles, äh, irgendwie in, in, in den entsprechenden,

01:08:16.960 --> 01:08:18.960
also kommt, je nachdem, hm,

01:08:18.960 --> 01:08:20.960
wie der Datentyp ist, aber möglicherweise

01:08:20.960 --> 01:08:22.960
halt landet das in einer dieser optimierten

01:08:22.960 --> 01:08:24.960
vortragenden Bibliotheken, die unten drunter unter

01:08:24.960 --> 01:08:26.960
der Lampe, äh, liegen. Und es

01:08:26.960 --> 01:08:28.960
ist halt auch so, dass es dann in gewisser Weise schon

01:08:28.960 --> 01:08:30.800
parallelisiert wird. Und halt diese, diese

01:08:30.800 --> 01:08:32.800
ich weiß jetzt gar nicht, wofür SIMD steht,

01:08:32.800 --> 01:08:34.800
diese Instruktions-Test,

01:08:34.800 --> 01:08:36.800
diese Single Instruction Multiple Data.

01:08:36.800 --> 01:08:38.800
Ah, okay. Ja, äh, genau.

01:08:38.800 --> 01:08:40.800
Super. Dankeschön.

01:08:40.800 --> 01:08:42.800
Äh, da, wo, ja, man

01:08:42.800 --> 01:08:44.800
spricht da auch von Vektorisierung. Also, man,

01:08:44.800 --> 01:08:46.800
ähm, äh, kann

01:08:46.800 --> 01:08:48.800
halt mit einem Taktzyklus

01:08:48.800 --> 01:08:50.800
halt mehrere, äh,

01:08:50.800 --> 01:08:52.800
Operationen oder ausführen,

01:08:52.800 --> 01:08:54.800
weil man hat so super lange Register,

01:08:54.800 --> 01:08:56.800
äh, weiß ich nicht, vielleicht

01:08:56.800 --> 01:08:58.800
512, äh, Byte oder so.

01:08:58.800 --> 01:09:00.640
Und da sind dann halt viele, äh,

01:09:00.640 --> 01:09:02.640
äh, wenn man jetzt Integer hat,

01:09:02.640 --> 01:09:04.640
4 Byte, äh, Werte drin. Und die werden

01:09:04.640 --> 01:09:06.640
dann halt alle addiert gleichzeitig oder

01:09:06.640 --> 01:09:08.640
multipliziert oder sowas.

01:09:08.640 --> 01:09:10.640
Und man zerlegt halt ein komplettes, äh,

01:09:10.640 --> 01:09:12.640
äh, Array sozusagen, auf dem man

01:09:12.640 --> 01:09:14.640
irgendwelche Dinge macht, halt in diese Blöcke

01:09:14.640 --> 01:09:16.640
und kann, braucht dann halt viel weniger Takte,

01:09:16.640 --> 01:09:18.640
als wenn man da einen For-Loop drüber machen würde.

01:09:18.640 --> 01:09:20.640
Ja, und das ist,

01:09:20.640 --> 01:09:22.640
macht Sachen super schnell, ja. Also das,

01:09:22.640 --> 01:09:24.640
man hat halt, äh, irgendwie so

01:09:24.640 --> 01:09:26.640
Python-Interface mit einem Jupyter Notebook,

01:09:26.640 --> 01:09:28.640
das sieht dann halt so aus, als hätte man so super,

01:09:28.640 --> 01:09:30.480
wäre man super high-levelig, aber wenn man eine Operation macht,

01:09:30.480 --> 01:09:32.480
kann es sein, dass dann tatsächlich etwas sehr, sehr

01:09:32.480 --> 01:09:34.480
Optimiertes, äh, passiert und es sehr schnell

01:09:34.480 --> 01:09:36.480
ist und man, wenn jemand da hingehen würde,

01:09:36.480 --> 01:09:38.480
würde es ein C schreiben, ist er möglicherweise

01:09:38.480 --> 01:09:40.480
deutlich langsamer, wenn er, wenn er

01:09:40.480 --> 01:09:42.480
nicht genau weiß, was er tut.

01:09:42.480 --> 01:09:44.480
Ähm, und das ist natürlich für viele

01:09:44.480 --> 01:09:46.480
Leute auch total überraschend, äh, äh, und

01:09:46.480 --> 01:09:48.480
das ist auch eine sehr, sehr, sehr, sehr schöne Geschichte.

01:09:48.480 --> 01:09:50.480
Aber ja, man muss halt, äh,

01:09:50.480 --> 01:09:52.480
man muss halt auch so ein bisschen eine komische

01:09:52.480 --> 01:09:54.480
Syntax dafür, äh, halt in Kauf nehmen.

01:09:54.480 --> 01:09:56.480
Man kann halt nicht mehr For-Loops machen, man muss halt

01:09:56.480 --> 01:09:58.480
immer Apply schreiben und dann halt eine

01:09:58.480 --> 01:10:00.320
Funktion übergeben. Oft übergibt man dann halt so anonyme

01:10:00.320 --> 01:10:02.320
Funktionen, schreibt dann Apply und dann Lambda,

01:10:02.320 --> 01:10:04.320
X und dann kriegt man halt, äh, irgendwie ein Wert übergeben

01:10:04.320 --> 01:10:06.320
und macht dann damit irgendwas. Ja.

01:10:06.320 --> 01:10:08.320
Ähm. - Comprehensions oder sowas kann man auch

01:10:08.320 --> 01:10:10.320
vergessen, genau, das selbe Problem. - Genau, das

01:10:10.320 --> 01:10:12.320
geht alles nicht mehr. Ja.

01:10:12.320 --> 01:10:14.320
Man schreibt halt alles nur noch, äh,

01:10:14.320 --> 01:10:16.320
ja, quasi, ja, man

01:10:16.320 --> 01:10:18.320
schreibt eigentlich fast alles in Apply. Ich weiß gar nicht, ob es

01:10:18.320 --> 01:10:20.320
da noch andere Funktionen gibt, die so ähnlich sind wie Apply.

01:10:20.320 --> 01:10:22.320
Naja.

01:10:22.320 --> 01:10:24.320
Ne, das war eigentlich immer

01:10:24.320 --> 01:10:26.320
Apply, ja.

01:10:26.320 --> 01:10:28.320
Ja, ja, und dann chained man

01:10:28.320 --> 01:10:30.160
halt die Sachen hintereinander.

01:10:30.160 --> 01:10:32.160
Man kann halt dann, diese

01:10:32.160 --> 01:10:34.160
Methode liefert dann halt das Ergebnis von dem Apply

01:10:34.160 --> 01:10:36.160
zurück, dann, äh, ruft man

01:10:36.160 --> 01:10:38.160
darauf wieder was anderes auf und dann hat man halt eine ganze Reihe

01:10:38.160 --> 01:10:40.160
von so hintereinander gechaineden Apply aufrufen

01:10:40.160 --> 01:10:42.160
unter Umständen. Und, ähm, ja.

01:10:42.160 --> 01:10:44.160
Ähm.

01:10:44.160 --> 01:10:46.160
Das ist auch, auch witzig, äh, äh,

01:10:46.160 --> 01:10:48.160
fällt mir grad noch zu dieser Vektorisierungsgeschichte

01:10:48.160 --> 01:10:50.160
ein, ähm,

01:10:50.160 --> 01:10:52.160
früher haben auch

01:10:52.160 --> 01:10:54.160
Leute irgendwie, äh, erzählt,

01:10:54.160 --> 01:10:56.160
naja, ach, das mit dem, mit der

01:10:56.160 --> 01:10:58.160
Parallelisierung, das ist ja alles gar kein Problem, wenn wir jetzt

01:10:58.160 --> 01:11:00.000
viele CPUs haben, so, äh, irgendwie,

01:11:00.000 --> 01:11:02.000
die, die, äh, Steigerung der Taktfrequenz war ja dann

01:11:02.000 --> 01:11:04.000
irgendwann auch schon vor längerer Zeit irgendwie vorbei,

01:11:04.000 --> 01:11:06.000
mehr oder weniger, und man muss halt,

01:11:06.000 --> 01:11:08.000
man kriegt halt mehr Prozessoren, also

01:11:08.000 --> 01:11:10.000
Moore's Law ist halt noch nicht wirklich weg, weil sich

01:11:10.000 --> 01:11:12.000
das eigentlich auch nur auf die Transistoren, nicht auf, äh,

01:11:12.000 --> 01:11:14.000
die Geschwindigkeit als solche irgendwie bezieht.

01:11:14.000 --> 01:11:16.000
Ähm, aber, äh,

01:11:16.000 --> 01:11:18.000
dann hieß es halt so, naja,

01:11:18.000 --> 01:11:20.000
das, das ist kein Problem, wenn man mehrere Prozessoren hat,

01:11:20.000 --> 01:11:22.000
da gibt's halt bestimmt Compiler, die das automatisch parallelisieren

01:11:22.000 --> 01:11:24.000
oder so. Ne.

01:11:24.000 --> 01:11:26.000
Ist nicht passiert, wird's auch nie

01:11:26.000 --> 01:11:28.000
passieren, dass Sachen automatisch

01:11:28.000 --> 01:11:29.840
parallelisieren geht halt nicht. Und, äh,

01:11:29.840 --> 01:11:31.840
das Schlimme ist, selbst so was

01:11:31.840 --> 01:11:33.840
wie automatisch vektorisieren geht halt nicht.

01:11:33.840 --> 01:11:35.840
Weil, äh,

01:11:35.840 --> 01:11:37.840
dummerweise, wenn man jetzt, äh,

01:11:37.840 --> 01:11:39.840
in, in C, na, wenn man sich jetzt

01:11:39.840 --> 01:11:41.840
mal vorstellt, man schreibt eine Vorschleife, die jetzt

01:11:41.840 --> 01:11:43.840
zwei Vektoren addiert,

01:11:43.840 --> 01:11:45.840
äh, also sagen wir mal so, die macht einfach nur

01:11:45.840 --> 01:11:47.840
C gleich A plus B.

01:11:47.840 --> 01:11:49.840
Wobei jetzt C, A und B sind

01:11:49.840 --> 01:11:51.840
halt, äh, Vektoren der gleichen Länge.

01:11:51.840 --> 01:11:53.840
Äh, naja, C ist der, der

01:11:53.840 --> 01:11:55.840
erzeugt wird. Äh,

01:11:55.840 --> 01:11:57.840
und man macht halt einfach vor, look, die das tut,

01:11:57.840 --> 01:11:59.680
dann denkt man sich jetzt, könnte doch eigentlich der

01:11:59.680 --> 01:12:01.680
Prozessor, äh, der, der Compiler hingehen und, äh,

01:12:01.680 --> 01:12:03.680
das, äh, irgendwie in diese

01:12:03.680 --> 01:12:05.680
Single Instruction Multiple Data, äh,

01:12:05.680 --> 01:12:07.680
äh, Prozessorbefehle umwandeln

01:12:07.680 --> 01:12:09.680
und dann irgendwie, äh, das deutlich schneller machen,

01:12:09.680 --> 01:12:11.680
stellt sich heraus, nein, kann er nicht, weil,

01:12:11.680 --> 01:12:13.680
äh, in C ist es, äh, ändert es

01:12:13.680 --> 01:12:15.680
halt die Semantik von deinem Programm.

01:12:15.680 --> 01:12:17.680
Weil, es könnte ja auch sein, dass

01:12:17.680 --> 01:12:19.680
dieses C irgendwie, äh,

01:12:19.680 --> 01:12:21.680
wieder was mit deinem A

01:12:21.680 --> 01:12:23.680
und deinem B zu tun hat und die

01:12:23.680 --> 01:12:25.680
Reihenfolge, in der du Sachen addierst,

01:12:25.680 --> 01:12:27.680
sich auf die nächste Addition irgendwie auswirken.

01:12:27.680 --> 01:12:29.520
Sodass halt, wenn du das in der Vorlog machst, kommt halt was

01:12:29.520 --> 01:12:31.520
raus, als wenn du das parallel machst.

01:12:31.520 --> 01:12:33.520
Und dann muss der Compiler natürlich sagen,

01:12:33.520 --> 01:12:35.520
so, nee, kann ich nicht automatisch optimieren, weil,

01:12:35.520 --> 01:12:37.520
weiß er nicht, vielleicht ist das irgendwie, hat das,

01:12:37.520 --> 01:12:39.520
ist das die Programmlogik, dass das so sein muss.

01:12:39.520 --> 01:12:41.520
So, das heißt, bei sowas

01:12:41.520 --> 01:12:43.520
Simples geht's schon nicht. Also man kann natürlich irgendwie

01:12:43.520 --> 01:12:45.520
dann so, äh, äh,

01:12:45.520 --> 01:12:47.520
Hinweise an den Compiler dazuschreiben, also

01:12:47.520 --> 01:12:49.520
man sagt so, hier ist okay, darfst du schon optimieren,

01:12:49.520 --> 01:12:51.520
mach da mal, äh, aber

01:12:51.520 --> 01:12:53.520
so generell kann ein Compiler das nicht machen.

01:12:53.520 --> 01:12:55.520
Und damit ist es natürlich schon irgendwie,

01:12:55.520 --> 01:12:57.520
ja, und das ist

01:12:57.520 --> 01:12:59.360
einer der Gründe, warum das auch in Fortran so

01:12:59.360 --> 01:13:01.360
viel, äh, schöner funktioniert ist, weil da

01:13:01.360 --> 01:13:03.360
gehen solche Sachen nicht. Da kannst du nicht, äh,

01:13:03.360 --> 01:13:05.360
kann nicht das Ergebnis, ähm,

01:13:05.360 --> 01:13:07.360
einer Addition in,

01:13:07.360 --> 01:13:09.360
bei, wenn du, wenn du zwei solche Arrays

01:13:09.360 --> 01:13:11.360
addierst, äh, äh, kann

01:13:11.360 --> 01:13:13.360
nicht sich auswirken auf die nächste,

01:13:13.360 --> 01:13:15.360
sozusagen. Das ist, das T kann nicht irgendwie wieder

01:13:15.360 --> 01:13:17.360
zu A oder zu B gehören. Sodass,

01:13:17.360 --> 01:13:19.360
da das ausgeschlossen ist, kannst du in,

01:13:19.360 --> 01:13:21.360
in Fortran solche Operationen halt automatisch

01:13:21.360 --> 01:13:23.360
vektorisieren. Also einer der Gründe, warum das halt

01:13:23.360 --> 01:13:25.360
irgendwann auch alles irgendwie Fortran ist.

01:13:25.360 --> 01:13:27.360
Äh, auf der anderen Seite, das müsste nicht unbedingt,

01:13:27.360 --> 01:13:29.200
du kannst auch ein C machen oder ein C++, wenn du

01:13:29.200 --> 01:13:31.200
das halt dem Compiler entsprechende Hinweise gibst. Aber

01:13:31.200 --> 01:13:33.200
es ist alles irgendwie nicht so, nicht so ganz einfach.

01:13:33.200 --> 01:13:35.200
Und, ähm, ja.

01:13:35.200 --> 01:13:39.200
Wahrscheinlich will man sich da auch nicht mit rumschlagen.

01:13:39.200 --> 01:13:41.200
Aber wenn man einfach so Paddler verwendet, dann passiert das ja alles automatisch

01:13:41.200 --> 01:13:43.200
und man hat nichts damit zu tun. Das ist gut.

01:13:43.200 --> 01:13:45.200
Ja.

01:13:45.200 --> 01:13:49.200
Ja, ähm,

01:13:49.200 --> 01:13:51.200
genau.

01:13:51.200 --> 01:13:53.200
Vektorisierung hatten wir dann.

01:13:53.200 --> 01:13:55.200
Genau, was wir vielleicht nochmal, äh,

01:13:55.200 --> 01:13:57.200
ein bisschen detaillierter ansprechen können, ist irgendwie

01:13:57.200 --> 01:13:59.040
das Plotting. Also es gibt, äh,

01:13:59.040 --> 01:14:01.040
für jedes DataFrame erstmal

01:14:01.040 --> 01:14:03.040
ein DotPlot. Und da kann man

01:14:03.040 --> 01:14:05.040
noch ein paar Parameter angeben und seinen Plot

01:14:05.040 --> 01:14:07.040
konfigurieren. Es gibt auch

01:14:07.040 --> 01:14:09.040
noch eine Reihe von anderen Funktionen.

01:14:09.040 --> 01:14:11.040
Ich hab die auch nie alle im Kopf.

01:14:11.040 --> 01:14:13.040
Aber da gibt's irgendwie noch Scatter und Box.

01:14:13.040 --> 01:14:15.040
Und da hat man dann verschiedene

01:14:15.040 --> 01:14:17.040
Diagrammtypen auch standardmäßig

01:14:17.040 --> 01:14:19.040
schon vorimplementiert.

01:14:19.040 --> 01:14:21.040
Damit man sich nicht mehr darum kümmern muss,

01:14:21.040 --> 01:14:23.040
die Plot-Funktion entsprechend durchzukonfigurieren.

01:14:23.040 --> 01:14:25.040
Sondern man bekommt

01:14:25.040 --> 01:14:27.040
direkt die Plots, die man haben möchte.

01:14:27.040 --> 01:14:28.880
Ja.

01:14:28.880 --> 01:14:30.880
Und, ähm,

01:14:30.880 --> 01:14:32.880
eine Sache, die ich ganz schön finde, ist,

01:14:32.880 --> 01:14:34.880
man kann als Spalten

01:14:34.880 --> 01:14:36.880
da auch wieder die Spalten-Namen angeben.

01:14:36.880 --> 01:14:38.880
Man muss jetzt nicht irgendwelche

01:14:38.880 --> 01:14:40.880
Koordinaten in dem DataFrame angeben,

01:14:40.880 --> 01:14:42.880
sondern man sagt: Plotte bitte

01:14:42.880 --> 01:14:44.880
Höhe, Breite,

01:14:44.880 --> 01:14:46.880
Länge gegen Zeitachse.

01:14:46.880 --> 01:14:48.880
Und dann passiert

01:14:48.880 --> 01:14:50.880
das genau so.

01:14:50.880 --> 01:14:52.880
Das ist einfach auch dann

01:14:52.880 --> 01:14:54.880
deutlich besser lesbarer

01:14:54.880 --> 01:14:56.880
und wartbarer Code, den man

01:14:56.880 --> 01:14:58.720
schreibt. Ja.

01:14:58.720 --> 01:15:00.720
Ja.

01:15:00.720 --> 01:15:02.720
Ja.

01:15:02.720 --> 01:15:04.720
Welche

01:15:04.720 --> 01:15:06.720
präferiert ihr von diesen Plotting-Bibliotheken?

01:15:06.720 --> 01:15:08.720
Also jetzt so irgendwie Matplotlib mit Seaborn

01:15:08.720 --> 01:15:10.720
oder dann doch Bookie, oder?

01:15:10.720 --> 01:15:12.720
Ich verwende

01:15:12.720 --> 01:15:14.720
meistens Seaborn tatsächlich, ähm,

01:15:14.720 --> 01:15:16.720
in Notebooks.

01:15:16.720 --> 01:15:18.720
Aber, ähm,

01:15:18.720 --> 01:15:20.720
es kommt halt drauf an,

01:15:20.720 --> 01:15:22.720
auf den Einsatzzweck. Also meistens

01:15:22.720 --> 01:15:24.720
müssen die für mich nicht interaktiv sein.

01:15:24.720 --> 01:15:26.720
Und dann verwende ich halt Seaborn.

01:15:26.720 --> 01:15:28.560
Weil es einfach netter aussieht, als Matplotlib direkt zu verwenden.

01:15:28.560 --> 01:15:30.560
Und das ist halt auch irgendwie einfacher.

01:15:30.560 --> 01:15:32.560
Es gibt halt manche Plots, das geht auch

01:15:32.560 --> 01:15:34.560
mit Matplotlib, aber, äh,

01:15:34.560 --> 01:15:36.560
es ist halt schon so ein bisschen, also

01:15:36.560 --> 01:15:38.560
ehrlich gesagt, ich mach das meistens so,

01:15:38.560 --> 01:15:40.560
dass ich auf Seaborn, äh,

01:15:40.560 --> 01:15:42.560
auf der Seaborn-Dokumentation halt dann so

01:15:42.560 --> 01:15:44.560
angucke, was ich so grob brauche. Und dann

01:15:44.560 --> 01:15:46.560
scrolle ich halt durch die Beispiele, bis ich irgendwas gefunden habe.

01:15:46.560 --> 01:15:48.560
Dann kopiere ich den Aufruf und modifiziere

01:15:48.560 --> 01:15:50.560
den so lange, bis es halt irgendwie funktioniert.

01:15:50.560 --> 01:15:52.560
Ähm,

01:15:52.560 --> 01:15:54.560
wenn man jetzt mit Matplotlib hingehen würde

01:15:54.560 --> 01:15:56.560
und das so nachbauen würde, dann

01:15:56.560 --> 01:15:58.400
ist das, äh, ist das halt

01:15:58.400 --> 01:16:00.400
deutlich schwieriger. Und, äh,

01:16:00.400 --> 01:16:02.400
es geht natürlich auch, Matplotlib ist, Seaborn baut

01:16:02.400 --> 01:16:04.400
darauf auf, und Matplotlib ist sehr mächtig.

01:16:04.400 --> 01:16:06.400
Aber es ist, äh, die API ist nicht

01:16:06.400 --> 01:16:08.400
so ganz einfach. Und, ähm,

01:16:08.400 --> 01:16:10.400
eigentlich musste ich da nie, da ich auch nie so

01:16:10.400 --> 01:16:12.400
wirklich komplizierte Visualisierungen mache, musste ich da nie so tief

01:16:12.400 --> 01:16:14.400
einsteigen, dass ich das irgendwie wirklich

01:16:14.400 --> 01:16:16.400
gebraucht hätte, sondern für mich reicht Seaborn meistens aus.

01:16:16.400 --> 01:16:18.400
Und dann gibt's aber natürlich auch noch Fälle,

01:16:18.400 --> 01:16:20.400
wo man das halt, ähm,

01:16:20.400 --> 01:16:22.400
äh, so ein bisschen interaktiv braucht, wo man

01:16:22.400 --> 01:16:24.400
in, da drin zoomen können möchte, oder man möchte

01:16:24.400 --> 01:16:26.400
es auf einer Webseite haben. Und

01:16:26.400 --> 01:16:28.240
dann, ähm, ja,

01:16:28.240 --> 01:16:30.240
ist eher sowas wie Bokeh oder Plotly,

01:16:30.240 --> 01:16:32.240
äh, das, was man da verwenden möchte. Also,

01:16:32.240 --> 01:16:34.240
äh, grad wenn man jetzt, also Plotly hab ich

01:16:34.240 --> 01:16:36.240
glaub ich auch schon mal für so Dashboards

01:16:36.240 --> 01:16:38.240
oder so, kann man das ganz gut verwenden.

01:16:38.240 --> 01:16:40.240
Äh, man kann tatsächlich, äh,

01:16:40.240 --> 01:16:42.240
relativ einfach eben, wenn man jetzt eine Datenbank

01:16:42.240 --> 01:16:44.240
hat oder so, dann zockt man daraus wieder DataFrames.

01:16:44.240 --> 01:16:46.240
Und, äh, die kann man dann

01:16:46.240 --> 01:16:48.240
sehr einfach mit, mit Plotly, äh,

01:16:48.240 --> 01:16:50.240
irgendwie auf einer Webseite visualisieren. Und dann

01:16:50.240 --> 01:16:52.240
können sich die Leute, die

01:16:52.240 --> 01:16:54.240
das angucken, halt auch dann, äh, irgendwie

01:16:54.240 --> 01:16:56.240
den Bereich, der sie interessiert, halt irgendwie auswählen.

01:16:56.240 --> 01:16:58.080
Und, ähm, daran zoomen und so.

01:16:58.080 --> 01:17:00.080
Ja. Also ich bin auch totaler

01:17:00.080 --> 01:17:02.080
Plotly-Fan, ähm,

01:17:02.080 --> 01:17:04.080
äh, im Wesentlichen, was da rauskommt

01:17:04.080 --> 01:17:06.080
als, als Graph ist ne

01:17:06.080 --> 01:17:08.080
kleine HTML-Seite oder auch nur

01:17:08.080 --> 01:17:10.080
ein Snippet, das man einbinden kann.

01:17:10.080 --> 01:17:12.080
Und, äh, zugrunde liegt

01:17:12.080 --> 01:17:14.080
im D3JS, das ist eine Visualisierungs-

01:17:14.080 --> 01:17:16.080
Library in JavaScript.

01:17:16.080 --> 01:17:18.080
Und, äh, das hat

01:17:18.080 --> 01:17:20.080
super viele Funktionen, aber ich benutze

01:17:20.080 --> 01:17:22.080
das hauptsächlich dafür, dass

01:17:22.080 --> 01:17:24.080
man einen Mouse-Hover auf den Datensatz

01:17:24.080 --> 01:17:26.080
hat. Man fährt halt

01:17:26.080 --> 01:17:27.920
über den Graph drüber und man sieht den exakten Wert,

01:17:27.920 --> 01:17:29.920
nochmal an der Maus. Äh, das ist so

01:17:29.920 --> 01:17:31.920
die, die, die wichtigste

01:17:31.920 --> 01:17:33.920
Funktion, die ich an Plotly immer wieder nutze.

01:17:33.920 --> 01:17:35.920
Ähm, das kann man aber auch beliebig

01:17:35.920 --> 01:17:37.920
weitereskalieren noch. Es gibt jetzt neu,

01:17:37.920 --> 01:17:39.920
äh, von Plotly Dash, das

01:17:39.920 --> 01:17:41.920
ist ein ganzes Dashboard mit

01:17:41.920 --> 01:17:43.920
Plotly-Grafen, geschrieben in

01:17:43.920 --> 01:17:45.920
Flask. Und, äh,

01:17:45.920 --> 01:17:47.920
das kriegt man auch superschnell

01:17:47.920 --> 01:17:49.920
hochgefahren. Und es gibt sogar inzwischen

01:17:49.920 --> 01:17:51.920
ein GitHub-Projekt, das, äh, ne Django-Anbindung

01:17:51.920 --> 01:17:53.920
für, für dieses Plotly-Dashboard

01:17:53.920 --> 01:17:55.920
macht. Also, ähm,

01:17:55.920 --> 01:17:57.760
da kann man dann im Wesentlichen ne

01:17:57.760 --> 01:17:59.760
ganze Website mit Datenvisualisierung

01:17:59.760 --> 01:18:01.760
als, als Django-Applikation

01:18:01.760 --> 01:18:03.760
direkt ausliefern.

01:18:03.760 --> 01:18:05.760
Was auch ziemlich nett ist,

01:18:05.760 --> 01:18:07.760
hab ich aber noch nicht im Detail ausprobiert.

01:18:07.760 --> 01:18:09.760
Gibt's sowas auch für R?

01:18:09.760 --> 01:18:11.760
Ja, ja, ja, so, äh, man muss sogar sagen,

01:18:11.760 --> 01:18:13.760
der Dash ist halt so im Nachbau von etwas,

01:18:13.760 --> 01:18:15.760
was halt in R super populär

01:18:15.760 --> 01:18:17.760
ist. Und das ist, in R heißt das Shiny.

01:18:17.760 --> 01:18:19.760
Ja, genau. Und, ähm,

01:18:19.760 --> 01:18:21.760
das, äh, ist

01:18:21.760 --> 01:18:23.760
eigentlich immer noch so ein bisschen der, der Goldstandard für,

01:18:23.760 --> 01:18:25.760
für diese, diese Geschichten, weil,

01:18:25.760 --> 01:18:27.600
also, ich weiß nicht, wie weit, also,

01:18:27.600 --> 01:18:29.600
ich hab jetzt auch schon lange nicht mehr angeguckt, aber,

01:18:29.600 --> 01:18:31.600
wie weit Dash da jetzt ist, ob sie, also,

01:18:31.600 --> 01:18:33.600
äh, ob sie das schon, ob sie da, da

01:18:33.600 --> 01:18:35.600
dran sind, aber, ähm,

01:18:35.600 --> 01:18:37.600
man hört immer noch, dass, dass viele Leute sagen,

01:18:37.600 --> 01:18:39.600
so, ah, aber Shiny ist schon irgendwie toller

01:18:39.600 --> 01:18:41.600
und ich mag das lieber als irgendwie,

01:18:41.600 --> 01:18:43.600
da gibt's noch keine so richtige Alternative in der

01:18:43.600 --> 01:18:45.600
breiten Welt, so, ja. Ich mein, äh,

01:18:45.600 --> 01:18:47.600
da, da guckt auch jeder vom anderen ab, ehrlicherweise.

01:18:47.600 --> 01:18:49.600
Also, ähm, äh,

01:18:49.600 --> 01:18:51.600
R hat auch irgendwann angefangen

01:18:51.600 --> 01:18:53.600
mit diesen Notebooks und, ähm,

01:18:53.600 --> 01:18:55.600
hat jetzt die Möglichkeit, ganze Berichte

01:18:55.600 --> 01:18:57.440
in Markdown zu mischen,

01:18:57.440 --> 01:18:59.440
mit ausführbaren Codes zählen.

01:18:59.440 --> 01:19:01.440
Also, im Prinzip das, was man mit Jupyter

01:19:01.440 --> 01:19:03.440
Notebooks für Python hat, gibt's

01:19:03.440 --> 01:19:05.440
auch in R. Ähm,

01:19:05.440 --> 01:19:07.440
da, da, die, also, das

01:19:07.440 --> 01:19:09.440
ist so eine Co-Evolution der beiden,

01:19:09.440 --> 01:19:11.440
äh, der beiden

01:19:11.440 --> 01:19:13.440
Analyse-Workflows, sag ich mal.

01:19:13.440 --> 01:19:15.440
Ja, wobei man sagen muss, dass die ursprüngliche

01:19:15.440 --> 01:19:17.440
Idee, äh, für diese Notebook-Geschichte,

01:19:17.440 --> 01:19:19.440
ähm, die Art, wie wir das, das kommt aus

01:19:19.440 --> 01:19:21.440
Mathematica, ähm,

01:19:21.440 --> 01:19:23.440
und es gibt schon ganz lang,

01:19:23.440 --> 01:19:25.440
äh, aber ist nie, hat sich nie

01:19:25.440 --> 01:19:27.280
so wirklich durchgesetzt, bis dann,

01:19:27.280 --> 01:19:29.280
äh, äh, das,

01:19:29.280 --> 01:19:31.280
dann, äh, jemand als, äh,

01:19:31.280 --> 01:19:33.280
äh, eben, bis, bis Leute das dann halt,

01:19:33.280 --> 01:19:35.280
äh, irgendwie dieses Jupyter-Projekt, äh,

01:19:35.280 --> 01:19:37.280
also das aus dem IPython, äh,

01:19:37.280 --> 01:19:39.280
Interpreter halt, äh, irgendwie rausgewachsen ist, äh,

01:19:39.280 --> 01:19:41.280
bis das da implementiert wurde.

01:19:41.280 --> 01:19:43.280
Und ich hab jetzt auch letztens gehört, dass jemand, äh,

01:19:43.860 --> 01:19:46.060
also den Mathematiker-Autor

01:19:46.060 --> 01:19:47.260
gefragt hat

01:19:47.260 --> 01:19:50.020
warum das jetzt, warum das eigentlich nicht

01:19:50.020 --> 01:19:51.860
Open Source wäre, weil das hätte so

01:19:51.860 --> 01:19:53.740
sich doch jetzt irgendwie durchgesetzt und voll toll

01:19:53.740 --> 01:19:55.280
und so und das

01:19:55.280 --> 01:19:57.540
die Idee war ja vorher schon da, aber

01:19:57.540 --> 01:19:59.540
ist unbekannt geblieben und

01:19:59.540 --> 01:20:01.760
äh, ja

01:20:01.760 --> 01:20:03.360
Steven Waffram hatte glaube ich so

01:20:03.360 --> 01:20:05.960
ja, also ich hätte das ja schon gerne als

01:20:05.960 --> 01:20:07.980
Open Source irgendwie veröffentlicht, aber das ging damals nicht

01:20:07.980 --> 01:20:09.860
weil es keine Distributionsmöglichkeiten

01:20:09.860 --> 01:20:11.480
dafür gab, das wurde halt alles irgendwie auf

01:20:11.480 --> 01:20:13.940
CDs und DVDs

01:20:13.940 --> 01:20:14.660
irgendwie, tja

01:20:14.660 --> 01:20:17.680
ja, es ist manchmal

01:20:17.680 --> 01:20:19.560
es ist komisch, ne, so irgendwie Idee

01:20:19.560 --> 01:20:21.660
es reicht nicht irgendwie, dass eine Idee super ist oder so

01:20:21.660 --> 01:20:23.620
sondern es müssen mehrere Sachen zusammenkommen, damit

01:20:23.620 --> 01:20:25.240
irgendwas wirklich dann abhebt

01:20:25.240 --> 01:20:26.300
und manchmal

01:20:26.300 --> 01:20:29.800
ja, kommt

01:20:29.800 --> 01:20:31.820
dann, denken Leute, dass irgendwie eine Idee

01:20:31.820 --> 01:20:33.900
erst kurz gibt oder so, das gibt sie schon ganz lange

01:20:33.900 --> 01:20:35.320
aber die Umstände waren halt nicht

01:20:35.320 --> 01:20:37.700
nicht richtig, so dass sie halt

01:20:37.700 --> 01:20:39.340
vorher halt noch nicht abheben konnte

01:20:39.340 --> 01:20:41.020
und das ist bei diesen

01:20:41.020 --> 01:20:43.380
diesen Jupyter-Notebooks ist das halt schon, ich denke, das war halt genau

01:20:43.380 --> 01:20:45.400
der richtige Moment und jetzt ist es halt groß geworden

01:20:45.400 --> 01:20:46.960
und, ähm, ja

01:20:46.960 --> 01:20:49.040
Shiny, let's be bad guys

01:20:49.040 --> 01:20:51.520
Ich meine, gerade im Data-Science-Bereich, wo man

01:20:51.520 --> 01:20:53.980
schnell viele Dinge ausprobieren

01:20:53.980 --> 01:20:55.840
muss, ohne Skripte von Anfang

01:20:55.840 --> 01:20:56.860
neu laufen zu lassen

01:20:56.860 --> 01:20:58.760
äh, ist natürlich der

01:20:58.760 --> 01:21:01.500
Killer-Anwendungszweck für diese Notebooks

01:21:01.500 --> 01:21:05.800
Ja

01:21:05.800 --> 01:21:09.160
Ja, haben wir noch was hier für

01:21:09.160 --> 01:21:10.300
Pandas?

01:21:11.020 --> 01:21:12.820
Ja, also Pandas ist ja nie

01:21:12.820 --> 01:21:14.600
isoliert zu betrachten

01:21:14.600 --> 01:21:16.640
Wir haben ja jetzt ganz viel schon auch über

01:21:16.640 --> 01:21:18.820
NumPy gesprochen, über Seaborn und Mudplotlib

01:21:18.820 --> 01:21:20.880
und, ähm, die eine

01:21:20.880 --> 01:21:22.900
Bibliothek, die ich eingangs noch mit erwähnt hatte

01:21:22.900 --> 01:21:24.400
war Studs Models

01:21:24.400 --> 01:21:26.720
und die bringt

01:21:26.720 --> 01:21:28.800
da im Prinzip noch eine Funktionalität

01:21:28.800 --> 01:21:30.840
rein, die ich persönlich auch erstmal nur von

01:21:30.840 --> 01:21:31.760
A kannte

01:21:31.760 --> 01:21:34.360
und zwar ist das

01:21:34.360 --> 01:21:36.900
ähm, Formeln

01:21:36.900 --> 01:21:37.680
anzugeben

01:21:37.680 --> 01:21:40.760
auf die man dann Fitting machen

01:21:40.760 --> 01:21:42.800
kann oder die man auch plotten kann

01:21:42.800 --> 01:21:44.820
und diese, diese Formeln

01:21:44.820 --> 01:21:46.500
das ist vielleicht erstmal

01:21:46.500 --> 01:21:48.280
ungewohnt, wenn man das noch nie gesehen hat

01:21:48.280 --> 01:21:50.580
gibt man im Wesentlichen irgendwie an

01:21:50.580 --> 01:21:52.260
als, äh, sagen wir mal eine

01:21:52.260 --> 01:21:54.420
Geradengleichung y tilde x

01:21:54.420 --> 01:21:56.820
also, äh, eine Variable

01:21:56.820 --> 01:21:58.720
y, die abhängig ist von

01:21:58.720 --> 01:22:00.560
äh, einer Variable x

01:22:00.560 --> 01:22:02.500
und als lineare Funktion zu

01:22:02.500 --> 01:22:04.340
verstehen ist und

01:22:04.340 --> 01:22:06.400
ähm, in diesem

01:22:06.400 --> 01:22:08.740
Studs Models gibt's, äh, die

01:22:08.740 --> 01:22:10.500
ähm, die Funktionen

01:22:10.760 --> 01:22:12.740
von OLS, um diese Formeln abzubilden

01:22:12.740 --> 01:22:14.680
die kann man dann auch mit

01:22:14.680 --> 01:22:17.140
Pandas Data Frames zusammen benutzen

01:22:17.140 --> 01:22:18.580
um wieder Plotting zu machen

01:22:18.580 --> 01:22:20.780
also, OLS meinte Optimal Linear

01:22:20.780 --> 01:22:21.780
Squares Modeling, oder?

01:22:21.780 --> 01:22:24.880
ähm, müsste ja

01:22:24.880 --> 01:22:26.100
äh, Ordinary

01:22:26.100 --> 01:22:27.720
Ordinary Linear

01:22:27.720 --> 01:22:30.200
äh, least squares oder sowas

01:22:30.200 --> 01:22:31.700
ich weiß nicht mehr, keine Ahnung

01:22:31.700 --> 01:22:34.500
also im Wesentlichen irgendwie, ähm

01:22:34.500 --> 01:22:36.540
äh, lineare Gleichungen

01:22:36.540 --> 01:22:38.520
an, anzugeben, da gibt's auch noch ganz

01:22:38.520 --> 01:22:40.380
viele andere Möglichkeiten, ähm,

01:22:40.500 --> 01:22:42.620
das ist nur jetzt der, der einfachste Fall

01:22:42.620 --> 01:22:44.760
immer, wo man eine lineare Gleichung

01:22:44.760 --> 01:22:45.140
angibt

01:22:45.140 --> 01:22:48.700
und, ähm, diese Variablen, die man

01:22:48.700 --> 01:22:50.060
da angibt, ähm

01:22:50.060 --> 01:22:51.920
die

01:22:51.920 --> 01:22:54.860
können in meinem Pandas Data Frame

01:22:54.860 --> 01:22:56.160
zu finden sein

01:22:56.160 --> 01:22:58.600
und dann kann ich, äh,

01:22:58.600 --> 01:23:00.160
das Plotting darüber machen

01:23:00.160 --> 01:23:02.660
da kann ich einmal die Trendlinie direkt plotten

01:23:02.660 --> 01:23:04.840
ich kann das Fitting direkt über die Pandas Data Frames

01:23:04.840 --> 01:23:06.660
machen, also die, die greifen

01:23:06.660 --> 01:23:08.660
da irgendwie, also alle diese Bibliotheken

01:23:08.660 --> 01:23:10.060
greifen sehr stark ineinander

01:23:10.500 --> 01:23:12.860
und da würde es auch gar nicht

01:23:12.860 --> 01:23:14.780
reichen, die 2900 Seiten des

01:23:14.780 --> 01:23:16.440
Pandas Handbuchs komplett zu lesen

01:23:16.440 --> 01:23:18.720
weil man müsste halt auch

01:23:18.720 --> 01:23:20.920
noch das NumPy Handbuch komplett lesen

01:23:20.920 --> 01:23:23.000
und dann vielleicht das, äh, Matplotlib Handbuch

01:23:23.000 --> 01:23:24.160
noch komplett lesen und

01:23:24.160 --> 01:23:26.360
ähm

01:23:26.360 --> 01:23:28.820
Also falls ihr die 2900 Seiten Handbuch gelesen habt

01:23:28.820 --> 01:23:30.980
dann sagt mal Bescheid und schreibt uns eine E-Mail

01:23:30.980 --> 01:23:33.440
Ja, äh, genau

01:23:33.440 --> 01:23:34.420
ich, ich, äh

01:23:34.420 --> 01:23:36.560
Satzmodels, äh, kenne ich auch so

01:23:36.560 --> 01:23:38.400
was Zeitreihen, äh, Modellierungs

01:23:38.400 --> 01:23:40.240
Geschichten angeht, aber habe ich noch

01:23:40.240 --> 01:23:42.700
noch nie so wirklich viel mit, äh, ähm

01:23:42.700 --> 01:23:43.640
gemacht, ähm

01:23:43.640 --> 01:23:45.980
ich bin eher so bei

01:23:45.980 --> 01:23:48.300
Scikit-Learn zu Hause und, ähm

01:23:48.300 --> 01:23:50.160
also Maschinen-Learning-Bibliothek

01:23:50.160 --> 01:23:52.260
äh, und auch da ist es so, also meistens

01:23:52.260 --> 01:23:54.280
bevor man halt irgendwelche, äh, bevor man

01:23:54.280 --> 01:23:55.540
Daten irgendwie in Modelle kippen kann

01:23:55.540 --> 01:23:58.080
ähm, muss man die halt mit Pandas einmal

01:23:58.080 --> 01:24:00.100
aufräumen und dann war es halt so, früher musste man dann

01:24:00.100 --> 01:24:02.140
immer noch so, okay, ich hab das jetzt in einem

01:24:02.140 --> 01:24:04.060
Data Frame, mhm, wie kriege ich die Daten jetzt

01:24:04.060 --> 01:24:06.280
äh, ah, wie kriege ich die Daten

01:24:06.280 --> 01:24:08.300
äh, äh, jetzt so

01:24:08.300 --> 01:24:10.120
dass ich die an meine Modelle verfüttern

01:24:10.120 --> 01:24:11.900
kann, und das war auch mal so ein bisschen

01:24:11.900 --> 01:24:14.000
problematisch und das ist jetzt aber auch schon

01:24:14.000 --> 01:24:15.960
weiß nicht, letzte oder vorletzte

01:24:15.960 --> 01:24:17.920
Version, äh, von Scikit-Learn war

01:24:17.920 --> 01:24:19.880
auch kein Problem mehr, weil man jetzt

01:24:19.880 --> 01:24:21.900
automatisch auch, weil man jetzt auch nicht

01:24:21.900 --> 01:24:23.260
früher brauchten die ganzen

01:24:23.260 --> 01:24:25.880
äh, äh, also in Scikit-Learn

01:24:25.880 --> 01:24:27.420
heißen die Dinger Estimators, äh,

01:24:27.420 --> 01:24:29.800
Estimator API, die haben halt

01:24:29.800 --> 01:24:31.900
äh, NumPy-Arrays genommen und jetzt

01:24:31.900 --> 01:24:34.040
mittlerweile nehmen die halt auch Pandas, äh, Data Frames

01:24:34.040 --> 01:24:36.020
und, äh, die Spalten einmal halten

01:24:36.020 --> 01:24:37.800
und wenn man halt irgendwie hinterher gucken

01:24:37.800 --> 01:24:39.920
möchte, okay, was ist denn jetzt,

01:24:40.000 --> 01:24:41.640
wo gelandet und so, und, äh,

01:24:41.640 --> 01:24:43.900
dann kann, kann man da auch mit den Spalten

01:24:43.900 --> 01:24:45.800
haben, arbeiten und das ist alles sehr, sehr bequem geworden

01:24:45.800 --> 01:24:47.500
und das greift halt auch da wiederum ineinander

01:24:47.500 --> 01:24:49.120
und das ist halt eigentlich sehr schön

01:24:49.120 --> 01:24:51.740
und was da, also, das ist, das ist

01:24:51.740 --> 01:24:54.040
ein, ein großes Data Science Ökosystem

01:24:54.040 --> 01:24:55.700
mittlerweile und das ist halt schon toll

01:24:55.700 --> 01:24:57.860
äh, ah, dazu fällt mir ein, genau

01:24:57.860 --> 01:24:59.340
äh, Sparse

01:24:59.340 --> 01:25:01.600
äh, äh, Data ist natürlich auch so ein

01:25:01.600 --> 01:25:03.440
Problem, da gibt's, äh, irgendwie

01:25:03.440 --> 01:25:05.900
ein Sparse-Type von

01:25:05.900 --> 01:25:07.800
Sci, SciPy, das hat man früher

01:25:07.800 --> 01:25:09.780
immer verwendet, es gibt ein paar Modelle, die

01:25:09.880 --> 01:25:11.820
halt in Scikit-Learn mit, mit Sparsen-Daten umgehen

01:25:11.820 --> 01:25:13.960
können, also das sind halt, also Spars heißt

01:25:13.960 --> 01:25:16.440
ähm, äh,

01:25:16.440 --> 01:25:17.760
Daten, bei denen die

01:25:17.760 --> 01:25:19.600
meisten Werte null sind

01:25:19.600 --> 01:25:21.900
äh, also zum Beispiel

01:25:21.900 --> 01:25:23.800
wenn man, wenn ich jetzt einen Text in, in

01:25:23.800 --> 01:25:25.920
oder eine Menge von Texten in

01:25:25.920 --> 01:25:27.700
äh, Lektoren

01:25:27.700 --> 01:25:29.620
verwandle, dann ist jedes Wort

01:25:29.620 --> 01:25:31.780
eine Dimension, sozusagen, und das heißt

01:25:31.780 --> 01:25:33.160
ich hab eine Tabelle mit, wenn ich

01:25:33.160 --> 01:25:35.680
äh, einen kompletten, wenn ich eine Menge

01:25:35.680 --> 01:25:37.860
von Texten, äh, in, in, in

01:25:37.860 --> 01:25:39.760
eine Matrix verwandeln, in so eine Feature-Matrix

01:25:39.760 --> 01:25:41.560
verwandeln möchte, äh, und dann ist

01:25:41.560 --> 01:25:43.860
jedes Dokument ist eine Teile, und, äh,

01:25:43.860 --> 01:25:45.640
die Spalten sind halt die Worte, die

01:25:45.640 --> 01:25:47.520
drin vorkommen, dann sind halt, die

01:25:47.520 --> 01:25:49.940
kommen halt, äh,

01:25:49.940 --> 01:25:51.760
die meisten Worte, die es so

01:25:51.760 --> 01:25:53.560
gibt, in einem Text aber nicht vor, das heißt, die

01:25:53.560 --> 01:25:54.720
allermeisten Werte sind halt null,

01:25:54.720 --> 01:25:57.600
und das ist halt blöd, das ist halt dicht zu speichern,

01:25:57.600 --> 01:25:59.340
diese ganzen Nullen immer mit zu speichern, weil eigentlich

01:25:59.340 --> 01:26:01.620
interessieren die einen ja gar nicht, und

01:26:01.620 --> 01:26:03.520
dafür gibt's dann so, so Spars, äh,

01:26:03.520 --> 01:26:05.420
Formate, und dann gibt's dann, ja,

01:26:05.420 --> 01:26:07.640
CSA, äh,

01:26:07.640 --> 01:26:09.640
äh, äh, oder, oder

01:26:09.640 --> 01:26:11.780
CSO-Formate in, in, in

01:26:11.780 --> 01:26:13.720
Sci-Py, aber das ist

01:26:13.720 --> 01:26:15.880
halt auch alles ein bisschen unschön,

01:26:15.880 --> 01:26:17.440
und, ähm,

01:26:17.440 --> 01:26:19.700
in, äh, jetzt eben der letzten

01:26:19.700 --> 01:26:21.680
Release von Pandas war auch ein natives

01:26:21.680 --> 01:26:23.720
Spars-Datenformat mit drin,

01:26:23.720 --> 01:26:25.620
das hab ich mir aber noch nicht angeguckt, aber das sieht auch

01:26:25.620 --> 01:26:27.500
interessant aus, ich weiß auch nicht, ob man das jetzt in, in

01:26:27.500 --> 01:26:29.680
Sci-Cat Launcher verwenden kann, aber

01:26:29.680 --> 01:26:31.540
das ist, äh, genau, das

01:26:31.540 --> 01:26:32.640
wird halt auch noch mit abgedeckt,

01:26:32.640 --> 01:26:34.980
und, ähm, ja,

01:26:34.980 --> 01:26:37.880
das ist auch noch so ein nicht uninteressantes

01:26:37.880 --> 01:26:38.300
Detail.

01:26:39.520 --> 01:26:41.180
Gibt's noch andere, äh,

01:26:41.180 --> 01:26:43.560
Bibliotheken aus den Web- und Sci-Learn

01:26:43.560 --> 01:26:45.520
Starts Models, Sci-Py,

01:26:45.520 --> 01:26:47.680
ja, äh,

01:26:47.680 --> 01:26:49.500
die ganzen Visualisierungsgeschichten,

01:26:49.500 --> 01:26:51.980
ähm,

01:26:51.980 --> 01:26:53.560
oh, ja, doch eine, eine Geschichte,

01:26:53.560 --> 01:26:55.180
äh, auch noch, äh, wichtig,

01:26:55.180 --> 01:26:57.700
wenn man jetzt, äh, tatsächlich, äh,

01:26:57.700 --> 01:26:59.660
äh, größere Datenmengen hat, oder halt auch,

01:26:59.660 --> 01:27:01.400
äh, Operationen, die lange dauern, und man hatte

01:27:01.400 --> 01:27:02.880
irgendwie so eine dicke Kiste mit irgendwie,

01:27:02.880 --> 01:27:05.760
äh, weiß ich nicht,

01:27:05.760 --> 01:27:07.480
64 Prozessoren, irgendwie

01:27:07.480 --> 01:27:09.080
in einem halben Terabyte Hauptspeicher oder so,

01:27:09.400 --> 01:27:11.460
äh, und, äh,

01:27:11.460 --> 01:27:13.740
man ist so ein bisschen angeödet davon,

01:27:13.740 --> 01:27:15.580
dass das irgendwie immer nur auf einem Prozessor läuft,

01:27:15.580 --> 01:27:16.840
dann kann man da was tun.

01:27:16.840 --> 01:27:19.300
Da gibt's ein auch sehr schönes Projekt, das nennt sich

01:27:19.300 --> 01:27:21.440
DARS, ähm,

01:27:21.440 --> 01:27:23.720
und damit kann man das halt so ein bisschen

01:27:23.720 --> 01:27:25.540
auf mehrere Prozessoren skalieren, also was das,

01:27:25.540 --> 01:27:27.540
äh, letztendlich tut, ist,

01:27:27.540 --> 01:27:29.480
ein DataFrame halt in viele Kleider

01:27:29.480 --> 01:27:31.420
zu zahacken, und dann halt, äh,

01:27:31.420 --> 01:27:33.720
die Operationen halt

01:27:33.720 --> 01:27:35.540
auf Prozessoren zu

01:27:35.540 --> 01:27:37.760
verteilen, und dann halt das hinterher wieder zusammenzuführen,

01:27:37.760 --> 01:27:39.280
aber es kann halt

01:27:39.280 --> 01:27:41.300
komp-, also, ich hab mehr oder weniger

01:27:41.300 --> 01:27:43.340
beliebige Compute

01:27:43.340 --> 01:27:44.960
Drafts kann man da irgendwie angeben,

01:27:44.960 --> 01:27:47.540
so, es ist halt, äh,

01:27:47.540 --> 01:27:49.520
einfache Dinge sind halt einfach

01:27:49.520 --> 01:27:51.160
damit zu parallelisieren, wenn man komplizierte Sachen

01:27:51.160 --> 01:27:53.540
machen möchte, dann muss man dann auch so ein bisschen nachdenken

01:27:53.540 --> 01:27:55.620
und dann halt eventuell, äh,

01:27:55.620 --> 01:27:57.360
sich überlegen, wie man das halt ausgeführt kriegt, aber,

01:27:57.360 --> 01:27:59.120
äh, im Grunde

01:27:59.120 --> 01:28:01.260
funktioniert das so, man hat halt so eine Deferred

01:28:01.260 --> 01:28:03.400
API, man sagt halt, was man tun möchte, und dann am Schluss

01:28:03.400 --> 01:28:04.860
sagt man irgendwie jetzt Collect oder so,

01:28:04.860 --> 01:28:07.800
und dann, äh, oder, äh,

01:28:07.800 --> 01:28:08.900
ich glaub, weiß gar nicht, also,

01:28:09.160 --> 01:28:11.260
man ruft halt irgendwie eine Funktion auf, die

01:28:11.260 --> 01:28:13.380
sagt so, und jetzt rechnet das halt alles mal aus, und dann

01:28:13.380 --> 01:28:15.200
wird das halt auf die unterschiedlichen Prozessoren verteilt,

01:28:15.200 --> 01:28:16.960
wird alles ausgerechnet, und am Schluss hat man

01:28:16.960 --> 01:28:19.560
das alles wieder in einem DataFrame, und, ähm,

01:28:19.560 --> 01:28:21.620
die Geschwindigkeit

01:28:21.620 --> 01:28:23.180
hat sich dann, wenn man Glück gehabt hat,

01:28:23.180 --> 01:28:24.720
halt irgendwie linear, äh,

01:28:24.720 --> 01:28:27.260
ähm, ist dann

01:28:27.260 --> 01:28:29.260
linear skaliert, und man braucht nur noch ein Sechzigstel

01:28:29.260 --> 01:28:30.820
der Zeit, oder so, ja.

01:28:30.820 --> 01:28:33.500
Ähm, genau.

01:28:33.500 --> 01:28:37.160
Das ist auf jeden Fall auch ein Ding,

01:28:37.160 --> 01:28:39.040
was man sich auch angucken sollte, also,

01:28:39.040 --> 01:28:41.400
was, was zu Skalierungsgeschichten angeht, ja, wenn die Datenmengen

01:28:41.400 --> 01:28:43.260
dann noch viel größer sind, so, oder dass sie halt

01:28:43.260 --> 01:28:45.240
nicht mehr in den Hauptspeicher auf einer Maschine passen, oder so,

01:28:45.240 --> 01:28:47.060
äh, dann

01:28:47.060 --> 01:28:49.500
muss man sich nochmal was anderes überlegen, dann, äh,

01:28:49.500 --> 01:28:51.240
bleibt eigentlich nur, dass man das dann,

01:28:51.240 --> 01:28:52.700
dass man irgendwie dann in Richtung

01:28:52.700 --> 01:28:54.600
Spark geht, oder sowas.

01:28:54.600 --> 01:28:57.160
Aber diesen, diesen Fall hat man fast nie, äh,

01:28:57.160 --> 01:28:58.780
weil mittlerweile,

01:28:58.780 --> 01:29:01.100
ja, die Maschinen so viele Hauptspeicher haben, dass das irgendwie

01:29:01.100 --> 01:29:01.780
kaum vorkommt.

01:29:01.780 --> 01:29:05.260
Wenn's nicht mehr in den Hauptspeicher passt, Geld dagegen

01:29:05.260 --> 01:29:06.840
werfen und mehr Hauptspeicher besorgen.

01:29:06.840 --> 01:29:07.140
Ja.

01:29:08.920 --> 01:29:10.760
Ja, wenn wir schon beim halben Terabyte

01:29:10.760 --> 01:29:12.820
angekommen sind, da ist ja schon noch ein bisschen Platz.

01:29:12.820 --> 01:29:13.820
Ja.

01:29:13.820 --> 01:29:15.720
Geht eine ganze Menge rein.

01:29:15.720 --> 01:29:18.780
Ja, so, Skalierung hatten wir jetzt auch

01:29:18.780 --> 01:29:21.040
so ein bisschen. Wir hatten noch, glaube ich, dieses, äh,

01:29:21.040 --> 01:29:22.880
äh, Wes McKinney, hast du kurz erwähnt,

01:29:22.880 --> 01:29:24.620
da hatten wir, glaube ich, einmal in unserer Weihnachtsfolge

01:29:24.620 --> 01:29:26.340
dieses Ten Things I Hate About Pandas, irgendwie.

01:29:26.340 --> 01:29:27.920
Ah, ja, ja, ja, genau.

01:29:27.920 --> 01:29:30.300
Ähm, ich weiß nicht, ob da noch was rauskam.

01:29:30.300 --> 01:29:32.820
Ja, der, ähm,

01:29:32.820 --> 01:29:34.880
also, er arbeitet

01:29:34.880 --> 01:29:36.560
halt hauptsächlich an dem Arrow-Projekt,

01:29:36.560 --> 01:29:38.740
dass, da geht's darum, eine neue Grundlage zu schaffen,

01:29:38.800 --> 01:29:40.720
äh, und zwar nicht nur

01:29:40.720 --> 01:29:42.780
für Python, sondern, ähm, für

01:29:42.780 --> 01:29:44.640
äh, alle anderen

01:29:44.640 --> 01:29:46.880
Programmiersprachen auch, weil man hat halt das Problem, dass man

01:29:46.880 --> 01:29:48.700
man möchte eigentlich

01:29:48.700 --> 01:29:50.580
nicht, wenn man Daten hat, die groß sind,

01:29:50.580 --> 01:29:52.860
und, äh, man möchte die nicht

01:29:52.860 --> 01:29:54.820
mehrfach im Hauptspeicher halten, aber momentan kommt man nicht drum rum,

01:29:54.820 --> 01:29:56.240
wenn man jetzt, äh,

01:29:56.240 --> 01:29:58.720
beispielsweise in R

01:29:58.720 --> 01:30:01.000
und in Python irgendwie auf Daten

01:30:01.000 --> 01:30:02.720
irgendwie was machen möchte, dann muss man die

01:30:02.720 --> 01:30:04.780
halt irgendwie erst, wenn man die jetzt in Python

01:30:04.780 --> 01:30:06.540
hat, serialisieren, irgendwo hin auf die Platte schreiben,

01:30:06.540 --> 01:30:08.680
dann in R wieder einlesen und

01:30:08.680 --> 01:30:10.640
hat sie dann, im Endeffekt zahlen wir im Hauptspeicher, was natürlich

01:30:10.640 --> 01:30:12.600
irgendwie doof ist, äh, und

01:30:12.600 --> 01:30:14.540
das Projekt ist sozusagen, äh,

01:30:14.540 --> 01:30:16.220
äh, äh,

01:30:16.220 --> 01:30:18.440
stellt halt sozusagen Schnittstellen für alle Programmiersprachen

01:30:18.440 --> 01:30:20.580
bereit, aber die Daten selber

01:30:20.580 --> 01:30:22.460
werden nur, äh, im Hauptspeicher

01:30:22.460 --> 01:30:24.480
an einer Stelle gehalten, da kann man mit allen Sprachen,

01:30:24.480 --> 01:30:26.480
also, was weiß ich, von Java bis C,

01:30:26.480 --> 01:30:28.460
äh, C++, Rust,

01:30:28.460 --> 01:30:30.680
äh, was auch immer, irgendwelche Leute schreiben gerade eine Query Engine

01:30:30.680 --> 01:30:31.980
für Arrow in, in Rust,

01:30:31.980 --> 01:30:34.860
äh, Python A, äh, darauf zugreifen

01:30:34.860 --> 01:30:36.560
und, äh, da irgendwelche

01:30:36.560 --> 01:30:38.140
Manipulationen drauf machen,

01:30:38.560 --> 01:30:40.480
äh, ohne dass es halt dann

01:30:40.480 --> 01:30:42.460
jedes Mal eine Kopie macht. Und das ist

01:30:42.460 --> 01:30:44.300
natürlich auch eine sehr, sehr interessante Geschichte,

01:30:44.300 --> 01:30:46.400
weil das ist eben,

01:30:46.400 --> 01:30:48.240
davon hatten wir jetzt ja auch schon ein paar Mal,

01:30:48.240 --> 01:30:50.280
äh, irgendwie momentan so ein, wenn man mit so

01:30:50.280 --> 01:30:52.220
Big Data-Geschichten, Hadoop-Clustern zu tun hat,

01:30:52.220 --> 01:30:54.280
so ein Problem, dass man da nicht so gut an die

01:30:54.280 --> 01:30:56.920
Daten rankommt, ähm,

01:30:56.920 --> 01:30:58.700
und, ähm,

01:30:58.700 --> 01:31:00.380
ja, das war auch eines der ersten

01:31:00.380 --> 01:31:02.520
Geschichten, die Arrow gemacht hat, war, äh,

01:31:02.520 --> 01:31:03.720
Parquet

01:31:03.720 --> 01:31:06.220
Fileparser, äh,

01:31:06.220 --> 01:31:08.440
zu implementieren, sodass man halt zumindest

01:31:08.440 --> 01:31:10.280
die Files, äh, in denen die Daten liegen,

01:31:10.280 --> 01:31:11.240
halt irgendwie lesen kann.

01:31:11.240 --> 01:31:14.440
Ähm, ja, und, äh,

01:31:14.440 --> 01:31:16.120
ähm,

01:31:16.120 --> 01:31:18.660
das, äh, das ist, das ist,

01:31:18.660 --> 01:31:19.980
glaube ich, also mittlerweile

01:31:19.980 --> 01:31:22.560
funktioniert das irgendwie fast allen Sprachen,

01:31:22.560 --> 01:31:23.880
dass man das halt sozusagen als,

01:31:23.880 --> 01:31:25.960
äh, ähm,

01:31:25.960 --> 01:31:28.360
äh, Ersatz für NumPy auch nehmen

01:31:28.360 --> 01:31:30.180
kann, äh, äh,

01:31:30.180 --> 01:31:32.240
und, dass das, also eine, eine

01:31:32.240 --> 01:31:34.080
Geschichte ist so, dass, dass in, in,

01:31:34.080 --> 01:31:36.520
in Pandas das nicht so wirklich schmerzfrei

01:31:36.520 --> 01:31:38.100
NumPy aushauschen kann, weil das halt,

01:31:38.320 --> 01:31:40.400
äh, viele Sachen in, in Pandas

01:31:40.400 --> 01:31:41.940
beruhen halt darauf, dass NumPy so ist, wie es ist.

01:31:41.940 --> 01:31:44.420
Das wird halt schwierig. Da gibt's auch, äh,

01:31:44.420 --> 01:31:46.100
eine Serie von Artikeln zu,

01:31:46.100 --> 01:31:47.640
nennt sich Pandas 2.0 irgendwie,

01:31:47.640 --> 01:31:50.060
wo man dann halt überlegt, dass man die API

01:31:50.060 --> 01:31:52.120
so nicht abwärtskompatibel ändert.

01:31:52.120 --> 01:31:54.440
Das, das hat

01:31:54.440 --> 01:31:56.060
Wesmerkini 2015 ein paar Artikel

01:31:56.060 --> 01:31:58.200
geschrieben. Bisher ist da nicht so viel

01:31:58.200 --> 01:32:00.280
passiert, aber man müsste, wenn man jetzt komplett auf Arrow umsteigen

01:32:00.280 --> 01:32:02.180
wollte und so, dann müsste man da wahrscheinlich, äh,

01:32:02.180 --> 01:32:04.160
irgendwie viel auch an dem Frontend

01:32:04.160 --> 01:32:05.880
von Pandas ändern und das wird dann

01:32:05.880 --> 01:32:07.360
nochmal, nochmal schwierig.

01:32:08.200 --> 01:32:08.640
Ähm,

01:32:08.640 --> 01:32:12.060
und, äh, ist es so, dass, äh,

01:32:12.060 --> 01:32:13.780
was auch noch in, in nächster Zeit

01:32:13.780 --> 01:32:15.920
bei Arrow ansteht, ist, es gibt

01:32:15.920 --> 01:32:17.760
so einen großen, so ein großes

01:32:17.760 --> 01:32:19.720
Kluft, äh, zwischen dem, was halt

01:32:19.720 --> 01:32:21.380
im Datenbankenbereich passiert ist

01:32:21.380 --> 01:32:23.700
und dem, was halt in, äh,

01:32:23.700 --> 01:32:25.580
im Data Science-Bereich passiert ist und

01:32:25.580 --> 01:32:27.840
da geht's auch darum, das so ein bisschen

01:32:27.840 --> 01:32:29.620
anzugleichen. Also, was man zum Beispiel nicht hat, ist eine

01:32:29.620 --> 01:32:31.740
Query-Engine für Arrow. Also, das wird, da

01:32:31.740 --> 01:32:33.280
wird halt grad geschrieben. Also, nächsten,

01:32:33.280 --> 01:32:35.920
ich glaub, das ist das Projekt so für die nächsten drei, zwei, drei Jahre

01:32:35.920 --> 01:32:38.080
in Arrow ist halt so, wer

01:32:38.080 --> 01:32:39.940
doch schickt, da auch so eine SQL-Engine

01:32:39.940 --> 01:32:41.940
drauf zu haben, sodass man halt Arrow

01:32:41.940 --> 01:32:43.100
auch als, ja,

01:32:43.100 --> 01:32:45.820
Ersatz oder Alternative

01:32:45.820 --> 01:32:47.740
zu Impala oder sowas halt auf Clustern

01:32:47.740 --> 01:32:48.340
verwenden könnte.

01:32:48.340 --> 01:32:52.300
Weil das ist im Grunde auch eine, äh, SQL-Engine

01:32:52.300 --> 01:32:53.480
äh, in C geschrieben,

01:32:53.480 --> 01:32:55.920
die halt, ähm,

01:32:55.920 --> 01:32:57.840
äh, äh, die halt auf so einem

01:32:57.840 --> 01:33:00.000
Hadoop-Cluster laufen kann. Ähm,

01:33:00.000 --> 01:33:01.280
und dann

01:33:01.280 --> 01:33:03.820
kann das aber viele der Sachen, die man halt in so

01:33:03.820 --> 01:33:05.360
Datenbanken hat, auch noch nicht. Also, ganzen

01:33:05.360 --> 01:33:07.960
Indiz-Index-Geschichten und so

01:33:07.960 --> 01:33:10.000
und, ähm,

01:33:10.000 --> 01:33:10.440
ja,

01:33:10.440 --> 01:33:13.860
da, da, da, da, da läuft

01:33:13.860 --> 01:33:15.600
das aber irgendwie so hin. Also, ich meine, wenn man jetzt

01:33:15.600 --> 01:33:17.600
sich so eine ideale Zukunft mal ausmalen

01:33:17.600 --> 01:33:19.160
würde, könnte,

01:33:19.160 --> 01:33:21.880
würde ich sagen, wäre das eigentlich sowas, man hat, äh,

01:33:21.880 --> 01:33:23.880
äh, äh, irgend so ein

01:33:23.880 --> 01:33:26.120
In-Memory-Storage, äh,

01:33:26.120 --> 01:33:27.920
also In-Memory-Storage-Arrow oder so.

01:33:27.920 --> 01:33:29.820
Man hat, äh, irgendwie

01:33:29.820 --> 01:33:31.940
als Frontend etwas Pandas-ähnliches.

01:33:31.940 --> 01:33:33.960
Ähm, es gab da auch schon

01:33:33.960 --> 01:33:35.880
einen, ähm, Ansatz von, äh,

01:33:35.880 --> 01:33:37.840
eben auch wieder von West McKinney, das ist so ein zentraler

01:33:37.840 --> 01:33:39.820
Figur, äh, das nennt sich Ibis, das

01:33:39.820 --> 01:33:41.540
Projekt, äh, wo es darum geht,

01:33:41.540 --> 01:33:44.000
eine, ein Superset

01:33:44.000 --> 01:33:45.740
von SQL zu haben,

01:33:45.740 --> 01:33:47.540
das möglichst Pandas-ähnlich ist,

01:33:47.540 --> 01:33:49.820
ähm, mit dem man aber all das

01:33:49.820 --> 01:33:51.840
machen kann, was man sonst auch mit SQL-Datenbanken macht.

01:33:51.840 --> 01:33:53.420
Und, ähm,

01:33:53.420 --> 01:33:55.840
ja, das halt auch so eine, so eine

01:33:55.840 --> 01:33:57.500
Default-Execution-Geschichte macht,

01:33:57.500 --> 01:33:59.640
dass man halt hinterher nur sagt, äh, irgendwie man, man

01:33:59.640 --> 01:34:01.720
definiert die ganzen Transformationen, Abfragen,

01:34:01.720 --> 01:34:03.780
die man da macht und dann am Schluss sagt man, so, und jetzt ausführen

01:34:03.780 --> 01:34:05.720
und dann geht das quasi an so ein

01:34:05.720 --> 01:34:07.540
Cluster raus. Und das ist,

01:34:07.720 --> 01:34:30.200
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.

01:34:30.200 --> 01:34:41.840
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.

01:34:41.840 --> 01:34:52.920
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.

01:34:52.920 --> 01:35:00.180
Und ja, also ich würde mir eine ideale Welt, würde ich mir so vorstellen, also für kleine Datenmengen funktioniert man das.

01:35:00.200 --> 01:35:09.580
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.

01:35:09.580 --> 01:35:29.580
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.

01:35:30.200 --> 01:35:38.340
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.

01:35:38.340 --> 01:35:51.400
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.

01:35:51.400 --> 01:35:58.220
So dass man dann halt auch wirklich große Datenmengen einfach so Transformation machen kann wie in Pandas.

01:35:58.940 --> 01:36:02.560
Das wird vielleicht noch ein paar Jahre dauern, aber das wäre so das, was ich mir wünschen würde, was passiert.

01:36:02.560 --> 01:36:16.600
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.

01:36:16.600 --> 01:36:20.880
Aber das kann auch sein, dass das nie passiert, weil so viele Leute jetzt Pandas verwenden.

01:36:27.680 --> 01:36:53.120
Ja, ich weiß nicht, von meiner Seite, ich wüsste jetzt spontan nichts mehr.

01:36:53.120 --> 01:36:56.260
Wenn ihr mich jetzt fragen würdet, fragt doch mal.

01:36:56.420 --> 01:37:00.800
Was sind so die drei wichtigsten Sachen, die ich mit nach Hause nehmen muss, wenn ich mal mit Pandas anfangen möchte?

01:37:00.800 --> 01:37:05.200
Was sind die wichtigsten drei Sachen, die du mit nach Hause nehmen musst, lieber Simon, wenn du mal mit Pandas anfangen möchtest?

01:37:05.200 --> 01:37:14.880
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.

01:37:14.880 --> 01:37:18.420
Ja, okay.

01:37:18.420 --> 01:37:22.240
Ja, ich würde sagen, Read CSV sollte man sich auch mal angucken.

01:37:22.240 --> 01:37:26.100
Ja, okay, also Datenimport, ja.

01:37:26.420 --> 01:37:29.880
Aber sonst, ja, nee, klar, doch.

01:37:29.880 --> 01:37:33.440
Ja, schön, schön.

01:37:33.440 --> 01:37:34.620
Ja.

01:37:34.620 --> 01:37:38.460
Schöne Strukturierung mit unseren Daten über Pandas, ich finde es hervorragend.

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

01:37:42.440 --> 01:37:47.440
Und vielleicht machen wir noch so ein bisschen Abschluss und erzählen noch ein bisschen was von euren Lieblings-Picks oder sowas.

01:37:47.440 --> 01:37:48.860
Ja.

01:37:48.860 --> 01:37:48.920
Ja.

01:37:48.920 --> 01:37:51.740
Erstmal.

01:37:51.740 --> 01:37:54.720
Sieben, möchtest du anfangen? Irgendwie hast du einen Lieblings-Pick, irgendein Modul, weißt du?

01:37:56.420 --> 01:37:58.380
Muss ich kurz einen Moment drüber nachdenken.

01:37:58.380 --> 01:37:59.500
Bitte, dann ist nicht offen zuerst.

01:37:59.500 --> 01:38:16.620
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.

01:38:16.620 --> 01:38:26.040
Das ist so ein Django-ORM-Style-Ding, aber für flache Files.

01:38:26.420 --> 01:38:42.500
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.

01:38:42.500 --> 01:38:56.300
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.

01:38:56.420 --> 01:39:02.540
Das fand ich ganz witzig, die Idee. Deswegen würde ich das mal, das mal picken, aber ja.

01:39:02.540 --> 01:39:08.960
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.

01:39:08.960 --> 01:39:15.720
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.

01:39:15.720 --> 01:39:20.780
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.

01:39:20.780 --> 01:39:24.620
Doch, kann man mit DataFrames auch machen. Ist auch tatsächlich ziemlich schnell.

01:39:26.420 --> 01:39:32.140
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.

01:39:32.140 --> 01:39:33.020
Ja, ja.

01:39:33.020 --> 01:39:34.180
Und spart sich dann immer die Zeit beim Ausführen.

01:39:34.180 --> 01:39:46.640
Ja, also genau, das ist, nee, das ist tatsächlich, wenn man, also ich finde DataFrames zu picklen, es funktioniert ganz gut.

01:39:46.640 --> 01:39:49.820
Also man muss, man muss vielleicht dazu sagen, man muss dem Ganzen vertrauen.

01:39:49.820 --> 01:40:01.160
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.

01:40:01.160 --> 01:40:06.740
Willst du ein Pickel-File von mir realisieren?

01:40:06.740 --> 01:40:13.880
Genau, dann lieber nicht machen, weil das kann, führt halt beliebigen Code aus und ja, das ist vielleicht nicht so schön.

01:40:13.880 --> 01:40:16.020
Aber wenn man das selber generiert hat, dann ist das vielleicht okay.

01:40:16.020 --> 01:40:18.240
Und dann ist es auch sehr schnell.

01:40:18.240 --> 01:40:19.080
Also.

01:40:19.820 --> 01:40:32.920
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.

01:40:32.920 --> 01:40:37.660
Also ich habe damit auch schon, da ging halt so Gigabyte pro Sekunde, geht halt durch.

01:40:37.660 --> 01:40:39.820
Also bei CSV ist, CSV ist richtig langsam.

01:40:39.820 --> 01:40:47.620
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.

01:40:49.280 --> 01:40:57.020
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.

01:40:57.020 --> 01:40:59.580
Und das ist natürlich schon schön.

01:40:59.580 --> 01:41:09.840
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.

01:41:09.840 --> 01:41:15.040
Heute würde man eher dann eben Arrow verwenden und dann ein paar K-Files lesen und schreiben.

01:41:15.040 --> 01:41:17.400
Das ist auch sehr schnell.

01:41:19.280 --> 01:41:29.400
Ä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?

01:41:29.400 --> 01:41:36.100
Es gibt dieses NetCDF4, das ist die Weiterentwicklung von HDF5 und, ähm, da hat man dann...

01:41:36.100 --> 01:41:37.340
NetCDF4 ist die Weiterentwicklung von 5?

01:41:37.340 --> 01:41:45.400
NetCDF4, ähm, das ist schon die vierte Iteration von NetCDF, aber irgendwann sind die wohl aus HDF entstanden.

01:41:45.400 --> 01:41:48.940
Wie das genau zustande gekommen ist, weiß ich auch nicht.

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

01:41:57.960 --> 01:42:05.260
Äh, das ist ganz spannend, wenn man sehr große, äh, Datensätze als Chunks auf, auf seiner Festplatte hat.

01:42:05.260 --> 01:42:09.700
Ähm, aber technische Details dazu weiß ich jetzt auch nicht.

01:42:09.700 --> 01:42:13.720
Tja, Tim, hast du noch ein Lieblingsmodul?

01:42:13.720 --> 01:42:19.180
Ja, ich hab ja eben schon gesagt, ich mag Plotly unheimlich gerne, aber wenn man Plotly grafen,

01:42:19.280 --> 01:42:23.940
erstellen möchte, dann muss man irgendwie so ein ganz tief verschachteltes Data-Dictionary bauen

01:42:23.940 --> 01:42:27.080
und dann ein Layout-Dictionary bauen und super viel konfigurieren.

01:42:27.080 --> 01:42:29.580
Und Matplotlib geht halt schnell.

01:42:29.580 --> 01:42:37.220
Und, ähm, Plotly hat kürzlich noch ein Tool rausgebracht, Matplotlib-to-Plotly-Grafen,

01:42:37.220 --> 01:42:45.780
wo man, das, das funktioniert noch nicht perfekt, aber so, so die Basis-Grafen wie Boxplots oder Scatterplots oder sowas

01:42:45.780 --> 01:42:49.220
kriegt man damit in Matplotlib ganz schnell definiert.

01:42:49.280 --> 01:42:55.080
Irgendwie mit zwei, drei Zeilen Code und dann mit einer Zeile konvertiert in Plotly-Grafen.

01:42:55.080 --> 01:43:01.380
Und dann hat man direkt dieses interaktive, ähm, man hat Mouse-Hover und man kann zoomen und, und so.

01:43:01.380 --> 01:43:04.780
Das, das fand ich ganz schön, ist aber noch, ähm,

01:43:04.780 --> 01:43:05.780
In den Kinderschuhen.

01:43:05.780 --> 01:43:07.280
Ist noch in den Kinderschuhen, ja.

01:43:07.280 --> 01:43:09.780
Ja, aber schön, das spannend zu verfolgen, ja.

01:43:09.780 --> 01:43:11.780
Cool.

01:43:11.780 --> 01:43:12.780
Ja.

01:43:12.780 --> 01:43:18.280
Habt ihr noch irgendwas, was ihr loswerden wollt, irgendwie das, euer Modul der Woche, oder sind wir damit durch und, äh?

01:43:18.280 --> 01:43:18.780
Loswerden.

01:43:18.780 --> 01:43:19.840
Nö, ich glaub damit.

01:43:19.840 --> 01:43:33.240
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.

01:43:33.240 --> 01:43:34.280
Ja, die Subscribe.

01:43:34.280 --> 01:43:36.540
Bei uns genau um die Ecke ist, da gehen wir auch mal hin.

01:43:36.540 --> 01:43:38.240
Genau, und da wüsstet ihr uns finden.

01:43:38.240 --> 01:43:43.140
Und, äh, genau, da könnte man, äh, uns, äh, treffen, wenn man, wenn man wollte, also.

01:43:43.140 --> 01:43:43.600
Ja, das.

01:43:43.600 --> 01:43:45.520
Wer möchte, kann einfach eine Mail an uns fragen, ja.

01:43:45.520 --> 01:43:48.520
Das, das kommt in den Veranstaltungen bei Ihnen, genau, aber ihr könnt uns sehr gerne treffen, tatsächlich.

01:43:48.580 --> 01:43:56.200
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.

01:43:56.200 --> 01:43:58.140
Das, äh, besprechen wir noch genauer.

01:43:58.140 --> 01:43:59.480
Ja, kommst du.

01:43:59.480 --> 01:44:02.580
Äh, ist ja immer mal wieder Django zur Sprache gekommen.

01:44:02.580 --> 01:44:05.760
Anfang April ist die DjangoCon in Kopenhagen.

01:44:05.760 --> 01:44:06.300
Oh, ja.

01:44:06.300 --> 01:44:10.280
Vom 10. bis zum 14. April ist es, glaub ich.

01:44:10.280 --> 01:44:13.540
Sieht man dich da?

01:44:13.540 --> 01:44:16.580
Äh, mich nur am 9. April.

01:44:16.580 --> 01:44:18.480
Äh, da ist das Django Girls Camp.

01:44:18.580 --> 01:44:21.880
Einen Tag Django, ähm, äh, lernen.

01:44:21.880 --> 01:44:22.560
Ja, ja.

01:44:22.560 --> 01:44:25.140
Äh, da fliege ich kurz hin als Mentor.

01:44:25.140 --> 01:44:27.020
Ich habe leider für die Konferenz selber keine Zeit.

01:44:27.020 --> 01:44:28.060
Ja, ja, okay, super.

01:44:28.060 --> 01:44:34.240
Ja, äh, wolltest du noch was zu, zu dem Cast sagen, zum Django-Cast, Jochen, oder machen wir das von anders?

01:44:34.240 --> 01:44:48.560
Ä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.

01:44:48.580 --> 01:44:53.500
Zum Beispiel sowas wie Episoden, Nummern sollten nicht im Titel sein und so.

01:44:53.500 --> 01:44:55.600
Das machen aber alle, äh, ich auch.

01:44:55.600 --> 01:45:07.040
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.

01:45:07.040 --> 01:45:15.480
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.

01:45:15.480 --> 01:45:18.540
Ähm, aber, ja, mal gucken.

01:45:18.580 --> 01:45:24.440
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.

01:45:24.440 --> 01:45:26.280
Mal gucken, ob ich die drei Zeilen zuschraffe.

01:45:26.280 --> 01:45:26.600
Ja.

01:45:26.600 --> 01:45:29.640
Also mindestens so, so den, den First Step oder so.

01:45:29.640 --> 01:45:30.500
Ja.

01:45:30.500 --> 01:45:31.660
So den, den großen Struggle.

01:45:31.660 --> 01:45:34.200
Ja, wenn ihr irgendwie so Anfänger seid wie ich, dann kommt ihr da bestimmt noch irgendwo dran.

01:45:34.200 --> 01:45:35.260
Ja.

01:45:35.260 --> 01:45:36.620
Ja, ansonsten.

01:45:36.620 --> 01:45:38.620
Ja, dann vielen Dank, dass ihr zugehört habt heute wieder.

01:45:38.620 --> 01:45:39.720
Dass ihr eingeschaltet habt.

01:45:39.720 --> 01:45:41.440
Wie auch immer, wann auch immer, wo auch immer.

01:45:41.440 --> 01:45:41.840
Mhm.

01:45:41.840 --> 01:45:42.920
Lasst uns das übrigens wissen.

01:45:42.920 --> 01:45:48.540
Schreibt eure E-Mails, Kommentare an hallo-at-python-podcast.de und, ja, kippt uns.

01:45:48.580 --> 01:45:52.880
Äh, weiter an alle Leute, die Python interessiert in eurer Nähe, erzählt eure Freunden, Kommilitonen.

01:45:52.880 --> 01:46:00.600
Ä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.

01:46:00.600 --> 01:46:05.140
Ähm, aber, äh, genau, ähm, ansonsten, ja.

01:46:05.140 --> 01:46:06.340
Ja, genau.

01:46:06.340 --> 01:46:07.680
Sagt Bescheid.

01:46:07.680 --> 01:46:10.100
Erstmal, äh, hört uns gerne, vor allen Dingen wieder und so.

01:46:10.100 --> 01:46:11.920
Bleibt uns gewogen, wie man so schön sagt.

01:46:11.920 --> 01:46:13.540
Und bis zum nächsten Mal.

01:46:13.540 --> 01:46:14.200
Bis zum nächsten Mal.

01:46:14.200 --> 01:46:14.480
Tschüss.

01:46:14.480 --> 01:46:15.340
Vielen Dank für die Einladung.

01:46:15.340 --> 01:46:15.700
Tschüss.

01:46:15.700 --> 01:46:15.940
Tschüss.

01:46:15.940 --> 01:46:16.460
Tschüss.
