WEBVTT

00:00:00.660 --> 00:00:05.140
Ja, hallo liebe Hörerinnen und Hörer, willkommen beim Paisen-Podcast in der mittlerweile sechsten Episode.

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

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

00:00:14.740 --> 00:00:15.760
Ja, hallo Simon.

00:00:16.980 --> 00:00:17.120
Hi.

00:00:17.580 --> 00:00:22.500
Genau, vielleicht kannst du dich einfach mal kurz vorstellen, bevor wir über das Thema reden.

00:00:22.500 --> 00:00:38.020
Klar. Ja, ich bin Simon. Ich bin von Haus aus Biologe, immer mit Interesse für Informatik und Spieleentwicklung gesegnet gewesen und habe das dann irgendwie auch zu meinem Beruf gemacht.

00:00:38.020 --> 00:00:47.480
Also ich habe nach meinem Bio-Studium ein bisschen geforscht in der Bio-Informatik. Da ging es dann viel um Datenanalyse von DNA-Sequenzen und so Dingen.

00:00:47.780 --> 00:00:48.420
Game of Life.

00:00:48.740 --> 00:00:52.240
Game of Life, ja, quasi. Nur in echt echt.

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

00:01:00.520 --> 00:01:11.560
mache ich heute als selbstständiger IT-Trainer Trainings für Game Engines und Trainings für Softwareentwicklung und parallel noch ein paar Softwareprojekte.

00:01:11.580 --> 00:01:14.840
Um das Gaming haben wir uns ja schon ein bisschen unterhalten, das machen wir auch nach der Folge ein bisschen intensiver.

00:01:14.960 --> 00:01:16.100
Aber heute soll es ja um Pandas gehen.

00:01:16.500 --> 00:01:17.420
Genau, heute...

00:01:17.420 --> 00:01:23.140
Deswegen, ja, super, dass du das auch ganz viel mit deinem zu tun hattest in deinem Fach, in deiner Wissenschaft.

00:01:24.220 --> 00:01:26.120
Bevor wir aber jetzt auf das Pandas-Thema eingehen,

00:01:26.120 --> 00:01:27.520
würde ich gerne noch so ein bisschen wieder

00:01:27.520 --> 00:01:29.520
Formalkrams abarbeiten.

00:01:31.040 --> 00:01:32.260
Wenn ihr Fragen, Anmerkungen

00:01:32.260 --> 00:01:33.860
habt, Lobkommentare, Hass,

00:01:34.100 --> 00:01:35.660
dann schreibt uns doch an

00:01:35.660 --> 00:01:37.320
hallo-podcast.de

00:01:37.320 --> 00:01:39.840
Ihr findet natürlich die links und alle zusätzlichen Informationen

00:01:39.840 --> 00:01:40.780
wie in den Shownotes.

00:01:41.900 --> 00:01:43.540
Es gab noch ein bisschen User-Feedback und zwar

00:01:43.540 --> 00:01:46.040
sollten wir irgendwann mal eine Folge machen

00:01:46.040 --> 00:01:48.120
über Do's und Don'ts im Programmieren.

00:01:48.740 --> 00:01:50.000
Also seid doch bitte so nett

00:01:50.000 --> 00:01:51.880
und schickt uns einfach per E-Mail eure

00:01:51.880 --> 00:01:53.780
Do's und eure Don'ts. Das wäre super,

00:01:53.780 --> 00:01:55.740
dann schneiden wir das ein bisschen zusammen und fragen

00:01:55.740 --> 00:01:57.780
euch in einer der nächsten Folgen bestimmt irgendwann mal danach.

00:01:58.960 --> 00:01:59.040
Ja.

00:01:59.480 --> 00:02:02.120
Doch, es gab noch ein anderes eben zu der Datenbank-

00:02:02.120 --> 00:02:03.720
Folge, dass sie, dass das gar nicht so

00:02:03.720 --> 00:02:05.260
schlimm gewesen wäre mit der Länge und das

00:02:05.260 --> 00:02:07.800
ja, fand ich

00:02:07.800 --> 00:02:09.600
auch ganz gut. Ist übrigens vielleicht ganz interessant, also wenn man sich

00:02:09.600 --> 00:02:11.660
anguckt, welche Folgen komplett

00:02:11.660 --> 00:02:13.860
runtergeladen wurden, dann hat die beste Quote tatsächlich

00:02:13.860 --> 00:02:15.500
die Datenbank-Folge zur Zeit.

00:02:15.820 --> 00:02:17.640
Was ich ein bisschen überraschend finde. Ich hätte jetzt auch erwartet,

00:02:17.780 --> 00:02:18.920
dass es eher ein bisschen runter geht, aber ja.

00:02:19.000 --> 00:02:21.300
Vielleicht müssen wir noch mehr so Buzzword-Bingo-Sachen machen

00:02:21.300 --> 00:02:23.160
und dann ganz viele tolle Klickzahlen bekommen.

00:02:23.220 --> 00:02:35.540
Nein, wir machen das natürlich für alle unsere Hörer, vor allen Dingen für die, die sich dafür wirklich interessieren und natürlich auch für die Leute, die was lernen wollen und für alle Leute, die einfach so reinhören oder denen langweilig ist oder ihr wisst ja, morgens, abends, nachts, beim Aufstehen im Flugzeug könnt ihr immer hören.

00:02:36.480 --> 00:02:42.620
Ja, bevor wir in das Thema gehen, ist weiterhin noch ein paar News aus der Szene und zwar gab es so ein bisschen was Neues, glaube ich.

00:02:43.640 --> 00:02:45.100
Python 3.8, zweite Alpha.

00:02:45.740 --> 00:02:45.880
Ja.

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

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

00:02:51.260 --> 00:02:52.640
Ja, das ist eine gute Frage.

00:02:53.220 --> 00:02:55.600
wann habe ich denn das da reingeschrieben?

00:02:55.800 --> 00:02:57.620
Oh, ja, das ist auch schon ein bisschen her, kann ich gar nicht.

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

00:03:00.420 --> 00:03:01.100
Das ist ja immer so.

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

00:03:06.000 --> 00:03:10.800
Also man muss ja, wenn man jetzt über mehrere Prozessoren

00:03:10.800 --> 00:03:13.060
Berechnungen verteilen will in Python,

00:03:13.560 --> 00:03:14.820
das auf mehreren Prozessen machen,

00:03:14.980 --> 00:03:17.180
weil man ja irgendwie so ein Global Interpreter-Log hat,

00:03:17.260 --> 00:03:20.000
das halt verhindert, dass man das innerhalb von einem Prozess

00:03:20.620 --> 00:03:22.460
irgendwie mehrere Prozessoren benutzen kann.

00:03:23.220 --> 00:03:45.180
Und ja, früher hat man halt immer so das, oder hat man jetzt immer noch in der stabilen Version, aber vielleicht hat man das mit 3.8. nicht mehr so, das Problem, dass man, wenn man jetzt eine Funktion aufrufen möchte und, sagen wir mal so, man startet halt einen Pool von 5 Prozessen oder sowas oder 10 und eben so viele üblicherweise, wie man Prozessoren hat und ruft jetzt eine Funktion auf jedem Prozessor sozusagen auf.

00:03:45.180 --> 00:04:03.920
Also man hat jetzt eine Liste von Dingen, die man irgendwie abarbeiten möchte, man hat eine Funktion, die das dann halt tut, dann sagt man, okay, starte mit diesem Job irgendwie diese Funktion und das geht dann halt irgendwie auf jeden Prozess, der halt in diesem Pool ist, wird dann halt das irgendwie gestartet.

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

00:04:08.100 --> 00:04:35.080
Ja, ja, ja. Das Problem ist jetzt, dass man, wenn man da irgendwie auch Daten hat, auf denen da gearbeitet wird, dann muss man die Daten irgendwie zu diesen Prozessen bringen. Das ist jetzt ein anderer Prozess. Das heißt, man kann nicht einfach das, also im Code ist es schon so, dass man einfach einen Funktionsaufruf macht. Aber was dann im Hintergrund passieren muss, ist ja irgendwie, dass die Daten serialisiert werden. Dann müssen sie irgendwie durch die Gegend geschoben werden und dann auf der anderen Seite wieder deserialisiert werden.

00:04:35.080 --> 00:04:36.460
In so kleine Häppchen und dass

00:04:36.460 --> 00:04:38.720
die ganze große Bestellung an verschiedenen Kassen

00:04:38.720 --> 00:04:40.560
abgearbeitet wird, um danach wieder in der richtigen Reihenfolge

00:04:40.560 --> 00:04:42.560
im Einkaufskraub zu landen.

00:04:43.240 --> 00:04:43.960
So ungefähr?

00:04:45.580 --> 00:04:46.640
Ja, man kann...

00:04:46.640 --> 00:04:47.620
15 Fehler wieder in einem Kasten.

00:04:48.420 --> 00:04:50.740
Ich weiß nicht, ob die Analogie da in der Stunde

00:04:50.740 --> 00:04:51.380
so gut passt.

00:04:52.180 --> 00:04:53.460
Ich weiß auch nicht genau.

00:04:55.500 --> 00:04:56.600
Ja, man

00:04:56.600 --> 00:04:57.880
muss es, ja.

00:04:58.560 --> 00:05:00.300
Man kann sich vielleicht vorstellen, dass man, wenn man jetzt

00:05:00.300 --> 00:05:02.160
einen riesen Einkaufswagen voll Zeug hat

00:05:02.160 --> 00:05:04.060
und möchte jetzt das an fünf Kassen

00:05:04.060 --> 00:05:06.220
aber bezahlen, dann

00:05:06.220 --> 00:05:08.100
muss man halt auch fünf Einkaufswagen haben, in die man

00:05:08.100 --> 00:05:10.040
das jetzt aufteilt und mit jedem Einkaufswagen

00:05:10.040 --> 00:05:12.040
einzeln zu einer Kasse und

00:05:12.040 --> 00:05:13.960
dann muss die

00:05:13.960 --> 00:05:16.140
irgendwer umpacken. Dann muss man die umpacken,

00:05:16.260 --> 00:05:17.380
genau, und das ist halt alles

00:05:17.380 --> 00:05:19.840
halbwegs aufwendig und

00:05:19.840 --> 00:05:22.000
kann halt auch zu Problemen führen, wenn die Daten sehr groß

00:05:22.000 --> 00:05:23.960
werden zum Beispiel, dann kann es sein, dass irgendwelche

00:05:23.960 --> 00:05:25.980
Dinge dazwischen halt aussteigen und das ist alles

00:05:25.980 --> 00:05:27.500
nicht so schön und

00:05:27.500 --> 00:05:29.840
ist es halt unter Umständen auch etwas, was

00:05:29.840 --> 00:05:32.000
Dinge langsam macht und jetzt geht es aber

00:05:32.000 --> 00:05:33.740
transparent mit Chat-Memory sozusagen.

00:05:33.740 --> 00:05:51.240
Das heißt, man hat halt die Daten, genau, das ist ja auch so ein Problem, wenn man jetzt Daten serialisiert und deserialisieren muss, dann kopiert man sie damit natürlich auch. Das heißt, wenn man große Daten hat, die jetzt vielleicht insgesamt nur einmal in den Hauptspeicher passen, aber nicht zweimal, wenn man sie kopiert, dann hat man sie halt zweimal drin und dann hat man so wenig Hauptspeicher, ist ja auch blöd.

00:05:52.640 --> 00:06:04.980
Und was halt schon immer viel, viel cooler war, ist, wenn man halt einfach Shared Memory reservieren kann und sagt dann den einzelnen Prozessen, gibt denen nur einen Pointer auf diese Shared Memory und sagt so, da sind deine Datenstrukturen drin.

00:06:05.720 --> 00:06:13.080
Also das heißt, jemand nimmt sich einfach so einen Unterkorb aus dem Einkaufswagen raus, der schon fertig ist und der Einkaufskorb, der fährt dann automatisch auf das richtige Förderband.

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

00:06:19.820 --> 00:06:22.140
Ja, Shared Memory, ein eingeteilter Einkaufswagen

00:06:22.140 --> 00:06:23.220
fällt mir jetzt auch tatsächlich schwer.

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

00:06:26.320 --> 00:06:27.720
Jede Kasse greift nur auf

00:06:27.720 --> 00:06:30.040
einen Teil von dem Korb selber zu.

00:06:30.080 --> 00:06:31.800
Stimmt, wir haben eine Bohre von Kassen.

00:06:31.900 --> 00:06:33.780
Die Kasse ist oben, unten, rechts und links und man kann einfach

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

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

00:06:38.020 --> 00:06:39.880
Und das heißt, man hat halt

00:06:39.880 --> 00:06:41.560
selbst wenn man jetzt Daten hat, die

00:06:41.560 --> 00:06:43.580
so gerade in den Hauptspeicher vielleicht passen,

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

00:06:45.600 --> 00:06:47.020
Und das macht natürlich

00:06:47.020 --> 00:06:49.520
Multiprocessing auf Python deutlich attraktiver und

00:06:49.520 --> 00:06:51.660
das ist irgendwie eine ziemlich coole Geschichte, wenn ihr jetzt in 3.8

00:06:51.660 --> 00:06:53.280
kommt. Da wird Python ja schneller.

00:06:53.880 --> 00:06:55.600
Ja, also, oder es wird einfacher

00:06:55.600 --> 00:06:57.560
damit, also man kann ja auch, das konnte man auch sowieso

00:06:57.560 --> 00:06:58.900
schon immer machen, man kann ja auch einfach

00:06:58.900 --> 00:07:01.440
Standard-Memory reservieren, da Dinge

00:07:01.440 --> 00:07:03.480
reinpacken, da gibt es übrigens auch

00:07:03.480 --> 00:07:04.060
ein schönes

00:07:04.060 --> 00:07:07.560
Modul in der

00:07:07.560 --> 00:07:09.180
Standard-Bibliothek, das heißt Struct.

00:07:09.900 --> 00:07:11.480
Struct? Genau, damit

00:07:11.480 --> 00:07:13.500
kann man zum Beispiel Daten

00:07:13.500 --> 00:07:15.240
halt so binär

00:07:15.240 --> 00:07:17.420
irgendwie in den

00:07:17.420 --> 00:07:18.060
Hauptspeicher schreiben.

00:07:19.520 --> 00:07:19.920
Und

00:07:19.920 --> 00:07:22.500
das zum Beispiel so tun, dass das halt

00:07:22.500 --> 00:07:23.400
C-Structs sind.

00:07:24.960 --> 00:07:26.780
Und dann kann man

00:07:26.780 --> 00:07:28.220
das halt, also das ist halt so etwas,

00:07:28.500 --> 00:07:30.140
so haben wir das früher halt gemacht, wenn wir Daten

00:07:30.140 --> 00:07:32.360
nicht so groß waren, dass man da nicht einfach

00:07:32.360 --> 00:07:33.240
irgendwas mehr tun konnte.

00:07:34.960 --> 00:07:36.520
Das heißt, man hat halt irgendwie

00:07:36.520 --> 00:07:38.260
einen Shared-Memory-Bereich, in den schreibt man halt

00:07:38.260 --> 00:07:40.060
irgendwie per Struct irgendwie

00:07:40.060 --> 00:07:42.220
sozusagen C-Struct-Daten

00:07:42.220 --> 00:07:44.000
irgendwie rein und hat dann Python-Prozesse,

00:07:44.200 --> 00:07:46.080
die wiederum einen Pointer auf diese Shared-Memory

00:07:46.080 --> 00:07:47.340
kriegen und

00:07:47.340 --> 00:07:49.640
die dann halt wieder ein C-Modul

00:07:49.640 --> 00:07:51.480
haben, das dann halt irgendwas mit den Daten macht und so.

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

00:07:53.520 --> 00:07:55.460
und jetzt kriegt man das quasi so geschenkt

00:07:55.460 --> 00:07:57.500
und das passiert alles automatisch und das ist halt

00:07:57.500 --> 00:07:58.020
schon sehr, sehr nett.

00:07:59.340 --> 00:08:01.320
Hört ja auch gerade diese Hintergrundmusik, das ist so ein bisschen wie

00:08:01.320 --> 00:08:02.560
in Battlestar Galactica, diese

00:08:02.560 --> 00:08:04.920
G...

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

00:08:07.940 --> 00:08:09.580
Ja, die nächsten News aus der Szene.

00:08:11.720 --> 00:08:13.420
Doppelte Keys, gab es einen Post

00:08:13.420 --> 00:08:15.400
von Guido irgendwo, der hat irgendwas geshared.

00:08:15.640 --> 00:08:19.240
Es gibt ein neues Python-Enhancement-Proposal,

00:08:19.840 --> 00:08:23.860
das eine ganz interessante Geschichte vorschlägt.

00:08:23.860 --> 00:08:26.900
Und zwar geht es darum, dass man halt für Dicts

00:08:26.900 --> 00:08:31.580
vielleicht auch die Plus und Minus als Operatoren haben möchte,

00:08:31.700 --> 00:08:34.220
sodass man halt sagen kann, irgendwie Dict A plus Dict B.

00:08:34.960 --> 00:08:37.260
Und dann werden sozusagen die Keys hinzugefügt

00:08:37.260 --> 00:08:38.680
oder halt wird das eine,

00:08:39.520 --> 00:08:41.720
werden halt die Keys, die in dem einen Ding drin sind, entfernt,

00:08:41.780 --> 00:08:42.880
wenn man das halt abzieht.

00:08:43.120 --> 00:08:44.060
Und das ist natürlich auch eine ganz,

00:08:44.420 --> 00:08:45.640
Also es ist eigentlich relativ naheliegend.

00:08:45.820 --> 00:08:47.500
Es wundert mich, dass da bisher noch niemand drauf gekommen ist,

00:08:47.540 --> 00:08:48.680
dass man das irgendwie mal machen könnte.

00:08:48.820 --> 00:08:51.280
Aber das ist auf jeden Fall eine ganz interessante Idee.

00:08:51.620 --> 00:08:54.880
Und Guido hat da einen Artikel zugeschrieben.

00:08:54.880 --> 00:08:58.180
Ja genau, der hat zweimal den Key irgendwie draus zugewiesen

00:08:58.180 --> 00:09:02.660
und dann quasi einen Dictionary mit zwei identischen Keys erzeugt,

00:09:02.660 --> 00:09:04.260
wo dann nur einer von überlebt hat.

00:09:06.760 --> 00:09:07.160
Ja.

00:09:07.840 --> 00:09:08.260
Irgendwie so.

00:09:08.420 --> 00:09:11.000
Also wenn man halt, ich glaube, welcher Post war das?

00:09:11.140 --> 00:09:14.100
Wo er A einmal die Nullen, A einmal die Eins zugewiesen hat

00:09:14.100 --> 00:09:15.940
und dann war eins

00:09:15.940 --> 00:09:17.240
übrig, weil das die letzte Zuweisung war.

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

00:09:19.520 --> 00:09:21.940
Genau, das war das Verhalten, was mich irgendwie

00:09:21.940 --> 00:09:24.320
gewundert hat, aber das ist generell

00:09:24.320 --> 00:09:25.840
so, das war schon immer so, offenbar,

00:09:26.240 --> 00:09:27.880
wenn man halt, also insofern

00:09:27.880 --> 00:09:29.500
ist es halt kompatibel mit diesem Verhalten,

00:09:30.280 --> 00:09:31.740
dass wenn man

00:09:31.740 --> 00:09:34.060
jetzt irgendwie ein Key mehrfach in einem Dikt hat,

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

00:09:36.440 --> 00:09:37.920
Und das war mir auch gar nicht klar,

00:09:37.920 --> 00:09:39.080
dass das so ist, aber...

00:09:39.080 --> 00:09:42.840
Also kein Duplicate Value oder Key Error oder sowas?

00:09:42.900 --> 00:09:44.080
nein, nein, es wird einfach das Letzte genommen.

00:09:44.640 --> 00:09:46.660
Und da hat er halt dazu, oder auf der Mail-Industrie geschrieben,

00:09:46.920 --> 00:09:50.140
dass, ja, er hat damals lange drüber nachgedacht,

00:09:50.600 --> 00:09:52.140
weil irgendjemand die Frage gestellt hat,

00:09:52.180 --> 00:09:53.260
ob das Absicht wäre oder nicht.

00:09:53.640 --> 00:09:55.480
Er meinte so, ich habe damals lange drüber nachgedacht

00:09:55.480 --> 00:09:56.520
und es ist Absicht.

00:09:59.340 --> 00:10:01.000
Ich erinnere mich an ein Programm, wo ich das dachte,

00:10:01.080 --> 00:10:02.040
wo ich irgendwie einen komischen Fehler hatte,

00:10:02.100 --> 00:10:03.600
und das, glaube ich, genau daran gelegen hat.

00:10:04.160 --> 00:10:07.040
Weil, ja, irgendwelche Duplikate dann zwar drin waren,

00:10:07.040 --> 00:10:08.580
ich das aber nicht gemerkt habe, erst irgendwann später,

00:10:08.680 --> 00:10:09.460
als mir um die Ohren flog.

00:10:10.200 --> 00:10:22.960
Ja, aber Guido hatte auch noch einen Blogpost dazu geschrieben, wo er überlegt hat, ob das mit diesen Operatoren halt eine gute Idee ist oder nicht.

00:10:23.600 --> 00:10:28.440
Siehst du, wie diese Code Active State heißen, Ideas?

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

00:10:32.460 --> 00:10:37.820
Und ja, da macht er tatsächlich den Punkt, dass das halt schon eine gute Idee ist.

00:10:38.100 --> 00:10:42.420
hat da so das als Beispiel

00:10:42.420 --> 00:10:44.160
quasi, wenn man jetzt mathematische, also

00:10:44.160 --> 00:10:46.140
arithmetische Geschichten halt nicht

00:10:46.140 --> 00:10:48.320
als Operatoren hätte, sondern

00:10:48.320 --> 00:10:50.440
wenn man das mit Funktionen ausschreiben würde,

00:10:50.840 --> 00:10:52.660
dann wird es halt sehr viel unklarer,

00:10:52.700 --> 00:10:54.300
was eigentlich gemeint ist, jedenfalls wenn das

00:10:54.300 --> 00:10:56.320
irgendwie komplizierter wird, weil man dann halt immer

00:10:56.320 --> 00:10:58.780
erst die Funktion

00:10:58.780 --> 00:10:59.760
mit den Klammern auflösen muss,

00:11:00.280 --> 00:11:02.400
bevor man sieht, was passiert und während man

00:11:02.400 --> 00:11:04.320
quasi, wenn man das als Operatoren

00:11:04.320 --> 00:11:06.460
hinschreibt, hat man so eine Art visuelles Pattern-Matching

00:11:06.460 --> 00:11:08.460
direkt schon, dass einem sagt, was

00:11:08.460 --> 00:11:10.520
da passiert und daher sind für so

00:11:10.520 --> 00:11:12.420
arithmetische Geschichten, um zu sehen, was da

00:11:12.420 --> 00:11:13.820
passiert, ist es halt viel

00:11:13.820 --> 00:11:16.200
sinnvoller, das mit Operatorenschreibweise

00:11:16.200 --> 00:11:18.400
hinzuschreiben als mit Funktionen,

00:11:18.400 --> 00:11:19.280
was man ja auch tun könnte.

00:11:20.620 --> 00:11:22.420
Und für Dicts ist

00:11:22.420 --> 00:11:23.820
halt die Frage, ob das Sinn macht, aber

00:11:23.820 --> 00:11:26.340
also immer dann, wenn einem das dabei beim

00:11:26.340 --> 00:11:28.460
Verständnis hilft, wenn man das anders hinschreiben

00:11:28.460 --> 00:11:30.420
kann, dann kann es natürlich schon gut sein,

00:11:30.500 --> 00:11:32.240
dass das irgendwie sinnvoll ist.

00:11:32.240 --> 00:11:34.400
Und ja, das ist auf jeden Fall

00:11:34.400 --> 00:11:36.340
glaube ich hier ein starkes Argument,

00:11:36.460 --> 00:11:38.440
dafür und mal sehen.

00:11:38.600 --> 00:11:40.400
Ich bin mir nicht sicher, ob wir das in Python 3.8

00:11:40.400 --> 00:11:42.120
dann schon direkt sehen werden, aber es wäre auf jeden Fall

00:11:42.120 --> 00:11:43.440
irgendwie eine interessante Idee

00:11:43.440 --> 00:11:46.660
und ja, ich bin mal gespannt, wie das sich so weiterentwickelt.

00:11:47.320 --> 00:11:47.940
Okay, okay.

00:11:49.420 --> 00:11:50.520
Ja, noch eine

00:11:50.520 --> 00:11:52.260
kleine News hatten wir, glaube ich, und das war der

00:11:52.260 --> 00:11:53.680
Django Chat Podcast.

00:11:54.220 --> 00:11:56.300
Genau, ja, es kommen ab und zu

00:11:56.300 --> 00:11:57.640
neue Podcasts dazu und jetzt

00:11:57.640 --> 00:12:00.200
fand ich besonders interessant

00:12:00.200 --> 00:12:02.160
eben auch Django, ein Podcast,

00:12:02.300 --> 00:12:04.160
der sich nur Django widmet, da

00:12:04.160 --> 00:12:06.380
einer der beiden ist irgendwie einer der beiden

00:12:06.380 --> 00:12:08.700
Django Fellows, die halt quasi sich, also

00:12:08.700 --> 00:12:10.700
dafür auch bezahlt werden, da tatsächlich

00:12:10.700 --> 00:12:12.680
an Django zu arbeiten und so die ganzen

00:12:12.680 --> 00:12:14.620
Sachen zu machen, die halt normalerweise niemand tut, wenn er

00:12:14.620 --> 00:12:15.920
nicht dafür bezahlt wird, halt irgendwie

00:12:15.920 --> 00:12:18.800
zum Issue-Tracker kümmern

00:12:18.800 --> 00:12:19.440
und

00:12:19.440 --> 00:12:22.200
Releases machen und so.

00:12:22.860 --> 00:12:23.380
Ja, und

00:12:23.380 --> 00:12:26.580
das war schon, die ersten beiden

00:12:26.580 --> 00:12:28.340
Episoden sind erschienen, die

00:12:28.340 --> 00:12:30.580
erste war irgendwie relativ interessant.

00:12:31.040 --> 00:12:32.740
Ich fand, das war auch so, dass da irgendwie eine ganze

00:12:32.740 --> 00:12:34.440
Menge Überschneidung war zu dem, was wir in unserer

00:12:34.440 --> 00:12:36.200
Django-Folge irgendwie erzählt haben, so von dem

00:12:36.200 --> 00:12:38.300
so Rundtenor.

00:12:38.860 --> 00:12:40.820
Ich seh grad, ich hab den auch gehört, ich bin begeistert.

00:12:41.060 --> 00:12:42.260
Ja. Und eine Folge.

00:12:42.840 --> 00:12:44.040
Gefällt mir sehr gut, also es ist

00:12:44.040 --> 00:12:46.120
wirklich toll. Jetzt kam noch eine zweite Folge, die war

00:12:46.120 --> 00:12:48.320
so eine kurze Folge dazu. Fünf Minuten.

00:12:49.160 --> 00:12:50.340
Könnt ihr mal sehen, wie man in der

00:12:50.340 --> 00:12:52.320
Kürze die Würze finden kann. Ja.

00:12:53.260 --> 00:12:54.200
Weil sie halt irgendwie mal

00:12:54.200 --> 00:12:55.600
ein Release von Django kaputt gemacht haben.

00:12:56.780 --> 00:12:58.320
Ja. Und

00:12:58.320 --> 00:13:00.400
ich bin mal gespannt, wie sich das so weiterentwickelt.

00:13:00.400 --> 00:13:02.220
Das ist auf jeden Fall eine sehr empfehlenswerte

00:13:02.220 --> 00:13:03.860
Geschichte. Dann gab's noch einen anderen

00:13:03.860 --> 00:13:06.260
Pouted Patent Out Loud, aber da müssen wir nochmal gucken, also den fand ich

00:13:06.260 --> 00:13:08.200
jetzt gar nicht so interessant

00:13:08.200 --> 00:13:10.240
am Anfang. Ja, falls ihr noch einen Podcast

00:13:10.240 --> 00:13:12.340
kennt, den wir noch nicht kennen, dann schickt ihn uns,

00:13:12.380 --> 00:13:13.460
wir sind neugierig natürlich.

00:13:14.660 --> 00:13:16.200
Ja, ich würde sagen, am Ende stellen wir nochmal so ein bisschen die

00:13:16.200 --> 00:13:18.260
Pics der Woche, der Woche, des

00:13:18.260 --> 00:13:20.200
Monats vor, aber wir sind glaube ich mittlerweile

00:13:20.200 --> 00:13:22.040
so weit, dass wir so ein bisschen jetzt was über Pandas

00:13:22.040 --> 00:13:24.060
erzählen können. Ja, Pandas, was ist das denn

00:13:24.060 --> 00:13:26.040
überhaupt? Also beim Eishockey, ich bin ja

00:13:26.040 --> 00:13:27.940
Eishockey-Finder, haben die Schiedsrichter jetzt so ein Pandasymbol

00:13:27.940 --> 00:13:30.060
gehabt auf den Trikots, weil die eine

00:13:30.060 --> 00:13:32.140
Kooperation mit dem WWF haben und dann

00:13:32.140 --> 00:13:34.380
waren sie am Ende ein bisschen enttäuscht, dass der WWF da so eine Spendenaffäre

00:13:34.380 --> 00:13:36.300
hatte. Aber ja, es ist manchmal so,

00:13:36.380 --> 00:13:38.040
aber Pandas und Spendenaffäre hat wahrscheinlich jetzt bei uns

00:13:38.040 --> 00:13:39.720
so viel nicht miteinander zu tun.

00:13:40.500 --> 00:13:42.020
Nee, aber der Name bietet

00:13:42.020 --> 00:13:44.180
natürlich schon so ein bisschen Verwechslungspotenzial.

00:13:44.300 --> 00:13:46.000
Wir hatten da auch genau darüber

00:13:46.000 --> 00:13:47.800
gesprochen haben, ob wir nicht irgendwie mal zusammen

00:13:47.800 --> 00:13:50.240
eine Podcast-Episode machen wollen.

00:13:50.360 --> 00:13:52.240
Hatte Simon auch irgendwie zuerst was anderes verstanden,

00:13:52.340 --> 00:13:54.060
glaube ich. Ja, genau. Also es gibt

00:13:54.060 --> 00:13:56.360
nicht nur Python Pandas

00:13:56.360 --> 00:13:58.120
das Data Frame Framework,

00:13:58.120 --> 00:14:00.500
sondern auch Python Pandas

00:14:00.500 --> 00:14:01.920
3D, die Game Engine.

00:14:02.140 --> 00:14:03.960
Ah. Und weil

00:14:03.960 --> 00:14:05.940
ich ja irgendwie beide Themen abdecke,

00:14:06.240 --> 00:14:07.760
war das, was ich gerade zuletzt

00:14:07.760 --> 00:14:09.680
gemacht hatte, das Erste, was im Kopf wieder

00:14:09.680 --> 00:14:11.700
aufgetaucht ist und das war die Game Engine und

00:14:11.700 --> 00:14:13.620
dann haben wir, weiß nicht, fünf Minuten aneinander

00:14:13.620 --> 00:14:15.620
vorbeigeredet. Wir können doch jetzt gerne noch mal

00:14:15.620 --> 00:14:17.760
fünf Minuten über die Game Engine, Pandas 3D reden, wenn du magst.

00:14:18.620 --> 00:14:19.420
Ist die in Python? Also

00:14:19.420 --> 00:14:22.060
ich glaube, Game-Entwicklung

00:14:22.060 --> 00:14:23.580
in Python ist vielleicht

00:14:23.580 --> 00:14:25.380
eine Folge, zu der ich nochmal wiederkommen sollte.

00:14:25.440 --> 00:14:27.540
Oh ja. Einfach, weil das sehr,

00:14:27.760 --> 00:14:29.220
sehr umfangreich ist. Und es geht?

00:14:29.440 --> 00:14:30.800
Es gibt es im Wesentlichen irgendwie

00:14:30.800 --> 00:14:33.320
Pygame und Pandas als die beiden

00:14:33.320 --> 00:14:35.220
großen etablierten, dann gibt es noch

00:14:35.220 --> 00:14:37.040
so ein paar kleinere. Und damit kann man wirklich auch

00:14:37.040 --> 00:14:39.300
Spiele machen, die auch gehen und die auch aussehen

00:14:39.300 --> 00:14:41.120
oder sowas? Oder braucht man dafür noch Qt oder

00:14:41.120 --> 00:14:43.220
sowas? Ich sage es mal vorsichtig, ja, damit kann man

00:14:43.220 --> 00:14:45.240
Spiele machen, mit Pygame

00:14:45.240 --> 00:14:47.020
2D-Spiele, mit Pandas 3D sogar

00:14:47.020 --> 00:14:49.220
3D-Spiele. Was man

00:14:49.220 --> 00:14:51.080
damit sehr gut machen kann, ist zu lernen,

00:14:51.240 --> 00:14:52.860
wie so eine Game Engine wirklich funktioniert.

00:14:54.280 --> 00:14:55.140
Ich glaube

00:14:55.140 --> 00:14:56.920
aber nicht, dass man Triple-A-Titel

00:14:56.920 --> 00:14:58.820
darin machen möchte, weil es dann doch irgendwann

00:14:58.820 --> 00:15:00.440
umständlicher ist, als

00:15:00.440 --> 00:15:03.000
eine von den großen 3D-Game-Engines,

00:15:03.080 --> 00:15:04.180
die so am Markt sind,

00:15:04.500 --> 00:15:06.420
die vielleicht auch ein bisschen mehr

00:15:06.420 --> 00:15:08.440
klickbar sind, zu verwenden.

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

00:15:10.800 --> 00:15:12.140
Unity und

00:15:12.140 --> 00:15:15.000
CryEngine.

00:15:15.140 --> 00:15:16.420
Ja, okay, dann CryEngine ist ja nicht

00:15:16.420 --> 00:15:18.660
frei. It 7 oder so 8.

00:15:19.520 --> 00:15:20.440
Weiß ich gerade gar nicht.

00:15:20.540 --> 00:15:21.780
Ich glaube, wir sind gerade völlig off-topic.

00:15:22.180 --> 00:15:24.560
Wir wollten über Pandas sprechen. Genau, also Pandas 3D

00:15:24.560 --> 00:15:26.500
ist die Game-Engine, darüber sprechen wir heute dann

00:15:26.500 --> 00:15:28.700
nicht. Und Pandas

00:15:28.700 --> 00:15:30.300
ist im Wesentlichen

00:15:30.300 --> 00:15:31.780
eins der Python-Tools,

00:15:32.460 --> 00:15:34.500
an denen man nicht vorbeikommt, wenn man Datenanalyse

00:15:34.500 --> 00:15:36.540
betreibt. Okay, wir sind

00:15:36.540 --> 00:15:38.560
wieder mal bei der Datenanalyse.

00:15:38.860 --> 00:15:40.300
Datenbanken hatten wir übrigens in der letzten Folge,

00:15:40.380 --> 00:15:42.640
für alle, die sich das noch nicht angehört haben, eine ziemliche Mammut-Folge

00:15:42.640 --> 00:15:44.320
mit, wie lange, drei Stunden haben wir

00:15:44.320 --> 00:15:46.300
gebraucht? Ja, ein bisschen mehr, aber

00:15:46.300 --> 00:15:48.440
genau um den Dreh. Wenn ihr mal wieder die Wohnung

00:15:48.440 --> 00:15:50.380
richtig putzen wollt, dann was soll ich, die Ohren?

00:15:51.660 --> 00:15:51.840
Ja,

00:15:52.380 --> 00:15:54.260
an der Stelle würde ich ganz gerne noch kurz

00:15:54.260 --> 00:15:56.320
meinen Hintergrund in der Datenanalyse

00:15:56.320 --> 00:15:58.400
erwähnen, damit man so ein bisschen einordnen kann,

00:15:58.400 --> 00:16:00.300
aus welcher Richtung meine Kommentare

00:16:00.300 --> 00:16:02.260
kommen. Als

00:16:02.260 --> 00:16:03.840
Biologe war damals

00:16:03.840 --> 00:16:06.460
Perl die große

00:16:06.460 --> 00:16:08.340
Programmiersprache, um alles zu lösen.

00:16:09.240 --> 00:16:10.360
Und erst zum Ende

00:16:10.360 --> 00:16:12.320
meiner Forschungszeit hat sich dann irgendwann

00:16:12.320 --> 00:16:14.340
Python durchgesetzt. Das heißt, ich habe noch sehr

00:16:14.340 --> 00:16:16.320
viel in Perl gemacht. Und

00:16:16.320 --> 00:16:18.320
was man in Perl gar nicht gut

00:16:18.320 --> 00:16:20.260
konnte, zumindest ich konnte das nicht, ist

00:16:20.260 --> 00:16:22.560
Daten nachher analysieren

00:16:22.560 --> 00:16:24.220
und visualisieren. Aber die

00:16:24.220 --> 00:16:26.220
Aufbereitung war da sehr gut. Das heißt,

00:16:26.220 --> 00:16:28.280
für die Analyse und die

00:16:28.280 --> 00:16:30.140
Visualisierung sind wir dann immer zu R

00:16:30.140 --> 00:16:31.760
rüber gewechselt. R ist

00:16:31.760 --> 00:16:33.320
auch eine Programmiersprache,

00:16:34.420 --> 00:16:36.420
ist eine eher mathematische

00:16:36.420 --> 00:16:38.180
Annotation zur

00:16:38.180 --> 00:16:39.000
Datenanalyse.

00:16:40.580 --> 00:16:41.680
Und wenn ich so

00:16:41.680 --> 00:16:44.240
die Branche, sage ich mal, richtig

00:16:44.240 --> 00:16:46.120
überblicke, dann wird am meisten

00:16:46.120 --> 00:16:48.220
R und Python

00:16:48.220 --> 00:16:49.940
benutzt und vielleicht dann noch

00:16:49.940 --> 00:16:52.180
MATLAB als

00:16:52.180 --> 00:16:53.520
dritte Alternative,

00:16:54.160 --> 00:16:56.340
wenn Leute heute Datenanalyse machen.

00:16:56.920 --> 00:16:58.120
Was meinst du denn

00:16:58.120 --> 00:16:58.960
mit Datenbereinigung?

00:17:00.400 --> 00:17:02.000
In der Biologie ist das so,

00:17:02.120 --> 00:17:06.020
dass die Daten immer unheimlich fuzzy sind.

00:17:06.420 --> 00:17:08.880
Also man hat nie ganz konkrete Messwerte,

00:17:08.880 --> 00:17:11.020
sondern man hat immer super viele Abweichungen,

00:17:11.140 --> 00:17:15.260
mal Fehlmessungen, mal Werte, die man gar nicht erheben konnte.

00:17:16.480 --> 00:17:17.300
Du musst dich dann entscheiden,

00:17:17.400 --> 00:17:18.720
ob du eine Rundung anwendest oder nicht.

00:17:19.100 --> 00:17:22.200
Vieles davon führt dann erst mal dazu,

00:17:22.300 --> 00:17:24.120
dass die Daten nicht mehr so strukturiert sind,

00:17:24.180 --> 00:17:26.100
wie man das eigentlich dachte in der Tabelle.

00:17:27.400 --> 00:17:30.820
Das kommt auf die Messinstrumente im Wesentlichen an.

00:17:32.080 --> 00:17:34.640
Das heißt, die erste Aufbereitung ist erstmal,

00:17:34.800 --> 00:17:37.240
die Daten in ein maschinenlesbares Format zu bringen.

00:17:38.240 --> 00:17:41.940
Und da ist es von unfassbarem Wert, wenn man programmieren kann.

00:17:43.280 --> 00:17:45.400
Dann muss man jede einzelne Zeile oder Zelle durchgehen

00:17:45.400 --> 00:17:46.640
und die manuell korrigieren.

00:17:47.220 --> 00:17:50.920
Genau, also ich habe auch tatsächlich schon Kollegen damals gesehen,

00:17:51.160 --> 00:17:53.580
die von Programmierung gar keine Ahnung hatten,

00:17:53.580 --> 00:17:56.840
die dann angefangen haben, in Excel sich das händisch zusammenzustellen

00:17:56.840 --> 00:18:15.120
Und dann haben wir uns kurz zusammengesetzt, ein Makro geschrieben und dann ging das irgendwie doch schneller. Und fehlerfreier an der Stelle auch. Und dieser erste Schritt, überhaupt die Daten erstmal maschinenlesbar zu kriegen, der ist im Wesentlichen unabhängig von der Analyse, aber notwendig.

00:18:15.120 --> 00:18:19.000
Und nochmal für unsere ganz Anfängerhörer, was denn überhaupt maschinenlesbar bedeutet?

00:18:20.380 --> 00:18:29.980
Ich habe da mal irgendwann ein Beispiel vorbereitet für Mediziner, die von Excel zu R wechseln wollten.

00:18:30.980 --> 00:18:36.060
Und das Beispiel war eine Tabelle, eine Excel-Tabelle aus meinem Laboralltag,

00:18:36.840 --> 00:18:43.300
wo dann in einem Tabellenblatt an mehreren verschiedenen Stellen so kleine Subtabellen zu sehen waren,

00:18:43.860 --> 00:18:45.280
wo die Messdaten drin standen.

00:18:45.860 --> 00:18:50.660
Da gab es dann quasi einmal Experiment A war so ein 5x4-Raster,

00:18:51.220 --> 00:18:55.020
Experiment B war so ein 5x4-Raster, was irgendwie rechts daneben stand.

00:18:55.560 --> 00:18:58.820
Und dann gab es noch ein Experiment C, was dann mittig darunter stand,

00:18:58.900 --> 00:18:59.920
auch 5x4-Raster.

00:19:00.540 --> 00:19:02.120
Das ist für den Menschen super lesbar,

00:19:02.120 --> 00:19:04.460
weil man kann sofort die Blöcke identifizieren

00:19:04.460 --> 00:19:05.940
und sich die Messdaten angucken.

00:19:06.820 --> 00:19:09.760
Für eine Maschine ist das aber nicht mehr strukturiert lesbar,

00:19:10.040 --> 00:19:12.060
weil die Koordinaten nicht klar sind.

00:19:13.340 --> 00:19:34.460
Und was häufig passiert ist, wenn Menschen Tabellen ausfüllen, um die visuell ansprechend zu machen, verletzen die ein wichtiges Kriterium, dass in jeder Zeile oder Spalte, je nachdem, woran man sich orientieren möchte, nur ein Datensatz wirklich drinsteht.

00:19:34.960 --> 00:19:48.940
Oder stehen sollte, weil da unterschiedliche Informationen sind, die nicht voneinander getrennt sind. Dann stehen zum Beispiel sowas wie eine Spalte, wo zwei verschiedene Datensachen auf einmal drin stehen. Einmal Temperatur in Celsius, einmal in Fahrenheit oder sowas. Oder ist das legitim?

00:19:48.940 --> 00:20:05.780
Das könnte ja noch zusammenpassen, aber einmal die Temperaturen in Celsius und Fahrenheit für das eine Experiment und dann das Ganze nochmal für das andere Experiment irgendwo weiter hinten in der gleichen Zeile, aber nicht klar strukturiert abgrenzbar.

00:20:06.960 --> 00:20:16.940
Ja, also das ist halt quasi bei Datenmarken die erste Normalform, dass man in der Spalte immer nur einen Wert stehen hat und nicht mehrere zum Beispiel, was halt dann manche Leute tun.

00:20:17.580 --> 00:20:25.880
Also Fahnenheit und Zeltes wäre okay, wenn man die Information enthalten wäre in der Zelle, ob es Zeltes oder Fahnenheit wäre.

00:20:27.680 --> 00:20:29.000
Weil das wäre sonst problematisch.

00:20:29.460 --> 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:37.620 --> 00:20:44.520
Grundsätzlich, wenn man so eine Tabelle hat, wo man Zeilenbeschriftungen hat und Spaltenbeschriftungen hat und die ganze Tabelle ist rechteckig,

00:20:45.100 --> 00:20:47.920
dann kriegt man die auch sinnvoll maschinenlesbar ausgewertet.

00:20:49.500 --> 00:20:53.400
Also Probleme fangen dann an, wenn man keine zweidimensionalen Tabellen mehr hat,

00:20:53.480 --> 00:20:55.660
keine, die man mal eben so auf seinen Whiteboard malen kann,

00:20:56.240 --> 00:20:59.340
welche, die man bauen müsste oder wo man irgendwelche Dimensionen verbraucht,

00:20:59.400 --> 00:21:01.100
die wir uns jetzt nicht so räumlich vorstellen können.

00:21:01.260 --> 00:21:06.660
Oder wo tatsächlich Lücken drin sind und die Muster für Menschen zwar noch erkennbar bleiben,

00:21:07.420 --> 00:21:10.340
aber für eine Maschine die Koordinaten dann zum Beispiel nicht mehr zusammenpassen.

00:21:10.860 --> 00:21:11.140
Okay.

00:21:11.140 --> 00:21:11.220
Okay.

00:21:15.100 --> 00:21:21.960
Ja, okay, das haben wir so ungefähr verstanden, was so maschinenlesbar dann bedeutet für die einzelnen Daten. Und wo kommt jetzt Pandas dann ins Spiel?

00:21:22.900 --> 00:21:51.800
Ich habe mal, ich glaube, das war Python User Group Treffen oder irgendwie sowas in der Richtung, habe ich mal eine Folie gesehen in einem Vortrag. Ich habe die leider nie wiedergefunden. Da fand ich das ganz schön beschrieben. Da waren irgendwie so Python-Module konzentrisch angeordnet und im innersten Kreis war NumPy oder NumPy, SciPy und Matplotlib für die Darstellung von Vektoren.

00:21:51.800 --> 00:21:53.480
NumPy und für

00:21:53.480 --> 00:21:55.940
einfache statistische Analysen

00:21:55.940 --> 00:21:57.620
SciPy und für Visualisierung

00:21:57.620 --> 00:21:59.660
Matplotlib. Und dann war

00:21:59.660 --> 00:22:01.340
der Kreis eins weiter draußen

00:22:01.340 --> 00:22:03.380
so ein bisschen das, was darauf aufbaut.

00:22:03.620 --> 00:22:04.880
Das war dann Pandas,

00:22:05.660 --> 00:22:06.500
das war

00:22:06.500 --> 00:22:09.600
Statsmodels, war das

00:22:09.600 --> 00:22:11.700
glaube ich. Also für Zeitreihen

00:22:11.700 --> 00:22:13.380
und so. Genau. Und

00:22:13.380 --> 00:22:15.640
Seaborn. Und das waren dann die

00:22:15.640 --> 00:22:17.540
Pendants. Also Seaborn auch

00:22:17.540 --> 00:22:19.760
wieder zur Visualisierung und Statsmodels

00:22:19.760 --> 00:22:21.440
im Prinzip zur statistischen

00:22:21.440 --> 00:22:24.260
Auswertung und Pandas eben zum

00:22:24.260 --> 00:22:27.920
Data Handling, aber

00:22:27.920 --> 00:22:30.220
jenseits von einfachen Vektoren.

00:22:31.780 --> 00:22:32.340
Aha, okay.

00:22:33.620 --> 00:22:36.240
So, und da kommen wir im Prinzip auch schon wieder in den Bereich,

00:22:36.400 --> 00:22:39.780
wo man immer den Vergleich zwischen Excel normalerweise

00:22:39.780 --> 00:22:42.700
führt, wenn man das mit Leuten

00:22:42.700 --> 00:22:44.500
bespricht, mit denen man zusammenarbeitet,

00:22:45.360 --> 00:22:48.120
weil Excel kennt irgendwie jeder. Also

00:22:48.120 --> 00:22:50.260
Tabellenkalkulation ist jedem sofort

00:22:50.260 --> 00:22:52.500
ein Begriff und alle wissen auch sofort,

00:22:52.680 --> 00:22:53.860
okay, es gibt Zeilen und Spalten.

00:22:54.500 --> 00:22:55.560
Das ist so, dass das

00:22:55.560 --> 00:22:57.960
bare minimum, was man wissen muss, um

00:22:57.960 --> 00:22:59.860
mit Pandas was anfangen zu können.

00:22:59.880 --> 00:23:01.840
Das hat man wahrscheinlich in der Schule schon mal aufgemacht oder so,

00:23:02.000 --> 00:23:03.680
oder aufmachen müssen. In der Regel schon, ja.

00:23:06.160 --> 00:23:08.240
Genau, das heißt, bei Pandas

00:23:08.240 --> 00:23:10.300
sind wir jetzt in dem Bereich von

00:23:10.300 --> 00:23:12.120
Data Handling.

00:23:12.120 --> 00:23:13.720
Also, wie kann ich meine Daten

00:23:13.720 --> 00:23:15.680
laden, verarbeiten,

00:23:16.460 --> 00:23:17.800
zur Verfügung stellen für

00:23:17.800 --> 00:23:19.960
Analysen. Und wie

00:23:19.960 --> 00:23:20.580
macht Pandas das?

00:23:23.160 --> 00:23:23.480
Gibt es da Spezies?

00:23:23.480 --> 00:23:25.880
Also ich würde sagen, also das ist auch das

00:23:25.880 --> 00:23:28.000
denke ich

00:23:28.000 --> 00:23:29.820
Hauptfeature von Pandas ist, dass

00:23:29.820 --> 00:23:31.920
man damit die Daten überhaupt erstmal irgendwie

00:23:31.920 --> 00:23:34.220
in so ein

00:23:34.220 --> 00:23:35.000
ja,

00:23:35.160 --> 00:23:37.180
reinbekommt irgendwie. Also

00:23:37.180 --> 00:23:39.160
Westman Kinney hat das auch mal gesagt, dass die

00:23:39.160 --> 00:23:41.560
populärste und wichtigste Methode, die

00:23:41.560 --> 00:23:43.180
Pandas halt hat, ist halt Read CSV,

00:23:43.880 --> 00:23:45.740
die sehr, sehr

00:23:45.740 --> 00:23:47.620
flexibel ist und man kann irgendwie so ungefähr

00:23:47.620 --> 00:23:49.760
jedes CSV, was irgendwo, ein CSV ist

00:23:49.760 --> 00:23:51.560
ein sehr hässliches Format und

00:23:51.560 --> 00:23:53.740
Leute machen unglaubliche und unheilige

00:23:53.740 --> 00:23:55.060
Dinge damit, aber

00:23:55.060 --> 00:23:57.420
man kann irgendwie mit dieser

00:23:57.420 --> 00:23:59.840
Funktion kann man das fast alles parsen.

00:24:00.400 --> 00:24:00.980
Die hat sehr viele

00:24:00.980 --> 00:24:03.660
Argumente und sehr viele Dinge, an denen man da irgendwie

00:24:03.660 --> 00:24:05.800
was drehen kann und man kriegt fast alles damit geparsed

00:24:05.800 --> 00:24:06.660
und

00:24:06.660 --> 00:24:09.720
das heißt, egal wie komisch die Daten aussehen,

00:24:09.740 --> 00:24:11.640
die man so hat, man kriegt sie irgendwie

00:24:11.640 --> 00:24:13.780
mit Readsys wie oft irgendwie

00:24:13.780 --> 00:24:15.480
in Pandas rein und hat sie dann halt in einem

00:24:15.480 --> 00:24:17.860
sauberen Format und kann das dann halt wieder in anderen Formaten

00:24:17.860 --> 00:24:19.840
rausschreiben. Aber gut, Pandas kann nicht nur

00:24:19.840 --> 00:24:21.960
CSV lesen, sondern halt auch diverse andere

00:24:21.960 --> 00:24:22.500
Formate

00:24:22.500 --> 00:24:25.760
von JSON

00:24:25.760 --> 00:24:28.220
über, keine Ahnung, XML oder was auch immer.

00:24:28.560 --> 00:24:29.840
Teilweise werden dann halt andere

00:24:29.840 --> 00:24:32.200
Bibliotheken unten drunter verwendet, um das halt einzulesen.

00:24:32.720 --> 00:24:32.880
Aber

00:24:32.880 --> 00:24:35.620
das ist halt,

00:24:36.020 --> 00:24:37.740
also Pandas ist eigentlich immer so der erste

00:24:37.740 --> 00:24:40.000
Schritt, wenn man irgendwo Daten herbekommt,

00:24:40.460 --> 00:24:41.120
um die halt in

00:24:41.120 --> 00:24:43.780
ein Format zu bringen, mit dem man irgendwas machen kann, um es halt

00:24:43.780 --> 00:24:45.980
irgendwie einzulesen in Programmen,

00:24:46.080 --> 00:24:47.740
da nimmt man halt eigentlich immer Pandas, weil das halt

00:24:47.740 --> 00:24:49.440
Pandas hat so vorbereitete Funktionen für, weiß nicht,

00:24:49.480 --> 00:24:51.320
eine Zeitreihenanalyse oder sowas.

00:24:51.520 --> 00:24:53.460
Nein, nein, der Analyseteil ist nochmal ein bisschen,

00:24:54.000 --> 00:24:55.680
also ja, Pandas kommt auch daher,

00:24:55.880 --> 00:24:57.520
also das ist mal

00:24:57.520 --> 00:24:59.560
entwickelt worden, Westman Kenny hat das

00:24:59.560 --> 00:25:01.400
gestartet, das Projekt 2008, als er bei

00:25:01.400 --> 00:25:03.900
RQ Capital, glaube ich, irgendwie so ein

00:25:03.900 --> 00:25:05.900
Hedgefonds-Investment-Dings

00:25:05.900 --> 00:25:07.880
da gearbeitet hat und

00:25:07.880 --> 00:25:09.960
da ging es um

00:25:09.960 --> 00:25:11.040
Zeitreihen und

00:25:11.040 --> 00:25:13.600
tatsächlich ist bei Pandas immer noch so

00:25:13.600 --> 00:25:15.740
der Hauptfokus, oder es ist halt das, was

00:25:15.740 --> 00:25:17.860
Pandas auch besonders gut kann, sind halt so Zeitreihen-Geschichten.

00:25:20.000 --> 00:25:21.800
Aber man kann auch diverse andere Dinge damit machen.

00:25:22.680 --> 00:25:24.520
ja,

00:25:24.780 --> 00:25:26.980
da gab es halt noch nichts

00:25:26.980 --> 00:25:29.760
in Python. Die Leute haben

00:25:29.760 --> 00:25:31.600
damals Excel verwendet oder halt

00:25:31.600 --> 00:25:33.800
irgendwie kommerzielle Software

00:25:33.800 --> 00:25:35.240
und ja,

00:25:37.220 --> 00:25:37.780
da wurde halt

00:25:37.780 --> 00:25:39.280
dann ist halt dieses Projekt gestartet.

00:25:41.040 --> 00:26:10.200
Und so ein bisschen, auch heute ist es halt noch so, dass viel Geld geht halt so in Deep-Learning-Geschichten, also wenn man sich anguckt, wie viel Geld wird halt eigentlich ausgegeben für Open-Source-Entwicklungen, ist sowieso irgendwie relativ erschreckend, wie wenig Ressourcen sozusagen Open-Source-Projekte haben und wie viele Leute dann und wie viele Firmen im Grunde darauf angewiesen sind, weil wenn man dann anguckt, was Firmen machen, auch große Firmen, dann ist das ja doch im Endeffekt machen die halt ganz viel mit so freier Infrastruktur, Software, die halt irgendwie auch alle Leute kennen und so.

00:26:11.040 --> 00:26:18.100
Aber die wird wenig, bekommt eigentlich wenig Ressourcen, da gibt es wenig Geld, da gibt es wenig Leute, die überhaupt beruflich daran arbeiten.

00:26:20.000 --> 00:26:25.960
Und die Projekte, die am meisten Geld bekommen, sind sowas wie TensorFlow oder so, weil man drüber schreiten kann, inwiefern das halt noch Open Source ist.

00:26:28.340 --> 00:26:34.620
Und auch die ganzen Cloud-Dienste oder so, die haben alle irgendwie Methoden, Daten da reinzubekommen, Daten wieder rauszubekommen.

00:26:34.620 --> 00:26:36.640
bekommen und auch in denen steckt

00:26:36.640 --> 00:26:38.280
relativ viel Geld drin, aber

00:26:38.280 --> 00:26:39.400
diese Sachen sind alle

00:26:39.400 --> 00:26:42.400
ziemlich schlecht irgendwie

00:26:42.400 --> 00:26:44.540
und Pandas füllte halt so eine Lücke.

00:26:44.760 --> 00:26:46.560
Ist halt eigentlich ultra wichtig, weil

00:26:46.560 --> 00:26:48.740
irgendwie diese ganzen Datenimport-Export-

00:26:48.740 --> 00:26:50.540
Geschichten sind halt etwas, was man immer braucht

00:26:50.540 --> 00:26:52.620
und irgendwie es gibt

00:26:52.620 --> 00:26:54.580
außer Pandas gibt es keine

00:26:54.580 --> 00:26:56.560
Projekte, die das irgendwie ordentlich gemacht haben

00:26:56.560 --> 00:26:58.100
und du kannst natürlich irgendwie deine

00:26:58.100 --> 00:27:00.440
tolle Deep Learning TensorFlow-Geschichte nehmen

00:27:00.440 --> 00:27:02.140
irgendwie, aber wenn du die Daten halt nicht

00:27:02.140 --> 00:27:04.300
hast, um damit irgendwas machen zu können,

00:27:04.300 --> 00:27:05.800
dann hilft dir das alles nichts

00:27:05.800 --> 00:27:08.080
und ja, das

00:27:08.080 --> 00:27:12.240
ja, eben Westman Kenny erzählt

00:27:12.240 --> 00:27:14.020
davon halt auch immer, dass ihn das total wundert

00:27:14.020 --> 00:27:16.180
und dass er das total seltsam findet, dass halt so ein wichtiger

00:27:16.180 --> 00:27:18.280
Teil der Infrastruktur so wenig

00:27:18.280 --> 00:27:19.540
Liebe erfährt quasi

00:27:19.540 --> 00:27:21.940
und

00:27:21.940 --> 00:27:24.040
dass seine Hauptmotivation war

00:27:24.040 --> 00:27:26.020
zu sagen, okay, da muss man mal was tun

00:27:26.020 --> 00:27:28.200
das muss doch irgendwie, dieses Problem muss man

00:27:28.200 --> 00:27:30.220
doch lösen, das ist halt irgendwie ein Problem, was alle haben

00:27:30.220 --> 00:27:31.780
und was irgendwie sehr ärgerlich ist und

00:27:31.780 --> 00:27:32.840
ja

00:27:32.840 --> 00:27:49.840
Ja, und das ist halt, das macht Pandas auch sehr gut irgendwie. Und das ist immer so ein erster Schritt, wenn man irgendwie Daten, auch wenn man jetzt hinterher Machine Learning machen möchte oder so, hat man trotzdem immer Pandas mit dabei, weil man die Daten ja erstmal irgendwie in ein Format bringen muss vorher und vielleicht aufräumen muss, sauber machen muss.

00:27:50.140 --> 00:28:06.240
Da gibt es auch immer so einen schönen Spruch, irgendwie Data Science ist halt so, oder auch Machine Learning ist halt, 80% ist halt Data Cleaning und 20% ist sich darüber beschweren, dass irgendwie 80% Data Cleaning sind.

00:28:07.540 --> 00:28:24.320
Ja, das trifft es sehr gut. Ja, ich meine, die andere Sache ist, als Mensch möchte man ja auch sich die Daten vielleicht zwischendurch mal angucken können. Und dafür braucht man irgendwie eine Datenstruktur, in der man sehr schnell zu Rahmendaten kommt.

00:28:24.320 --> 00:28:54.220
Vielleicht braucht man mal einen Mittelwert oder will sich mal die Verteilung angucken, gruppiert bei irgendwelchen Kategorien oder sowas. Also sicherlich ist diese Import-Geschichte von Pandas eine der mächtigsten, die ich bisher gesehen habe, was auch so fehlende Datenpunkte angeht und wenn die Struktur mal nicht ganz stimmt und man kann einzelne Zeilen überspringen, wenn da mal was kaputt geht oder sowas.

00:28:54.320 --> 00:29:12.380
Da habe ich jetzt übrigens direkt eine doofe Frage zu, weil es gibt ja irgendwie bei Pandas so ein paar Werte, die, wenn die halt nicht da sind, die man irgendwie füllen kann. Da gibt es ja irgendwie jetzt aber so drei Typen. So Null und None und None. Warum, wieso braucht man da drei?

00:29:16.300 --> 00:29:18.120
In Pandas? Also ich wüsste jetzt

00:29:18.120 --> 00:29:19.700
eigentlich nur, dass es da Not-a-Number gibt.

00:29:20.400 --> 00:29:21.900
Ja. Und das ist

00:29:21.900 --> 00:29:23.780
historisch sozusagen der

00:29:23.780 --> 00:29:25.820
hier ist kein Wert

00:29:25.820 --> 00:29:27.200
von NumPy.

00:29:28.100 --> 00:29:29.980
Das ist auch irgendwie sozusagen ganz

00:29:29.980 --> 00:29:31.920
unten drunter ist das

00:29:31.920 --> 00:29:32.760
tatsächlich ein

00:29:32.760 --> 00:29:35.580
in Float kann man das halt ausdrücken und

00:29:35.580 --> 00:29:37.780
ja, das hat halt auch so die

00:29:37.780 --> 00:29:39.340
leichten, das leichte Problem, dass

00:29:39.340 --> 00:29:41.740
man im Grunde immer dann, wenn man solche Werte hat, dann

00:29:41.740 --> 00:29:43.740
halt auch der Datentyp irgendwie

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

00:29:45.880 --> 00:29:48.740
Bis vor ganz kurzem war das noch so,

00:29:49.180 --> 00:29:52.060
dass man halt, wenn man jetzt eine Integer-Spalte hatte

00:29:52.060 --> 00:29:53.380
und da fehlt halt jetzt ein Wert,

00:29:53.680 --> 00:29:54.580
und man hat halt gesagt, okay,

00:29:56.560 --> 00:30:00.480
da kommt irgendwie was dazu, was halt irgendwie fehlt oder so,

00:30:00.660 --> 00:30:02.820
und man macht einen Re-Index und guckt,

00:30:02.940 --> 00:30:04.940
und dann hat sich plötzlich der Typ der Spalte in Float geändert,

00:30:05.620 --> 00:30:11.600
weil es halt keine fehlenden Werte in Integer-Typ-Typ-Spalten gibt.

00:30:12.280 --> 00:30:15.020
Und das ist ein ziemlich blödes Problem.

00:30:15.880 --> 00:30:29.980
Aber jetzt gibt es halt irgendwie seit einiger Zeit diese Array Extensions, Array Extensions API für Pandas und die halt mit Cyber Pandas dazugekommen ist.

00:30:29.980 --> 00:30:43.080
Ich weiß gar nicht, welche Version das genau war. Und jetzt hat auch Ende Januar ist die letzte größere Release von Pandas erschienen. Ich glaube 0.244 oder so.

00:30:43.280 --> 00:30:44.200
0.244, ja.

00:30:44.220 --> 00:30:51.940
Und da ist jetzt halt auch ein natives Integer-Spaltenformat drin, das halt auch nannen kann.

00:30:52.460 --> 00:30:54.220
Und das ist natürlich total cool irgendwie.

00:30:55.900 --> 00:31:09.500
Und dadurch, dass man jetzt quasi nicht mehr NumPy unten drunter liegen hat, kann man da auch diverse andere coole Datentypen irgendwie verwenden, die vorher so nicht möglich waren, weil man ja immer auf NumPy angewiesen war.

00:31:09.500 --> 00:31:38.740
Also NumPy ist auch ganz cool, aber NumPy hat halt das Problem, dass das grundlegende Design dafür ist halt jetzt doch schon wahrscheinlich fast 20 Jahre alt und passt halt auch nicht mehr so richtig auf die Anforderungen von heute und dummerweise hat Panas aber viele der Implementationsdetails in NumPy halt rausgelegt und das kann man jetzt auch nicht mehr so einfach ändern, weil das halt schon, also wenn man das wieder ändern würde, würde das Code brechen und dann wäre keine abwärtskompatiblen Änderungen mehr.

00:31:38.740 --> 00:31:40.700
Und das ist natürlich alles so ein bisschen eine blöde Situation.

00:31:42.520 --> 00:31:42.880
Aber

00:31:42.880 --> 00:31:44.820
irgendwie mit dieser Array-Extension-API hat man

00:31:44.820 --> 00:31:46.500
auf jeden Fall eine Möglichkeit, wenn man den Typ ändert, dann

00:31:46.500 --> 00:31:48.700
ist das alles eigentlich in Ordnung.

00:31:48.840 --> 00:31:50.660
Und dann kann man da auch schöne neue Sachen machen,

00:31:50.820 --> 00:31:52.840
ohne dass man auf NumPy irgendwie angewiesen ist.

00:31:53.620 --> 00:31:54.500
Zum Beispiel was halt,

00:31:55.140 --> 00:31:56.640
also es sind so Beschränkungen, die sind echt blöd.

00:31:56.800 --> 00:31:57.780
Also wenn man auf NumPy

00:31:57.780 --> 00:32:00.720
unten drunter basierendes

00:32:00.720 --> 00:32:02.660
Pandas hat, dann hat man halt

00:32:02.660 --> 00:32:04.040
sowas nicht wie zum Beispiel

00:32:04.040 --> 00:32:05.520
Decimal-Types.

00:32:06.640 --> 00:32:08.400
Also einmal man hat keine fehlenden, keine

00:32:08.400 --> 00:32:10.420
Missing-Value-Support für sowas wie

00:32:10.420 --> 00:32:12.540
Integer, was auch schon schlimm ist, aber man hat halt

00:32:12.540 --> 00:32:14.420
auch, wenn man jetzt mit Geld zu tun hat,

00:32:14.520 --> 00:32:15.900
was man ja vielleicht auch irgendwie,

00:32:16.540 --> 00:32:18.200
dann hat man halt bloß Float,

00:32:18.460 --> 00:32:19.940
das will man auch nicht. Also man

00:32:19.940 --> 00:32:22.400
würde das dann irgendwie wahrscheinlich eher

00:32:22.400 --> 00:32:24.640
Geld in Integer, also in Cent-Integer

00:32:24.640 --> 00:32:25.500
oder sowas verwenden.

00:32:26.540 --> 00:32:28.580
Viele werden wahrscheinlich irgendwie Float

00:32:28.580 --> 00:32:29.960
nehmen, so,

00:32:30.540 --> 00:32:32.500
und dann denken, ach, das wird schon irgendwie hinhauen

00:32:32.500 --> 00:32:34.340
und dann böse Überraschungen überleben,

00:32:34.440 --> 00:32:36.360
weil das funktioniert halt

00:32:36.360 --> 00:32:38.260
überhaupt gar nicht. Und man

00:32:38.260 --> 00:32:40.460
kriegt diverse richtig böse Probleme, wenn man das

00:32:40.460 --> 00:32:42.740
macht. Und in Datenbanken

00:32:42.740 --> 00:32:44.240
ist das Problem eigentlich auch schon lange gelöst.

00:32:44.320 --> 00:32:46.780
Da gibt es den Decimal-Type

00:32:46.780 --> 00:32:48.400
genau für sowas, der dann

00:32:48.400 --> 00:32:50.520
halt auch ordentlich

00:32:50.520 --> 00:32:52.220
rundet und so. Und

00:32:52.220 --> 00:32:54.560
in Python gibt es auch einen nativen

00:32:54.560 --> 00:32:56.620
Decimal-Type. Der ist blöderweise

00:32:56.620 --> 00:32:58.520
nur total super langsam. Also den kann man eigentlich auch

00:32:58.520 --> 00:32:58.880
nicht nehmen.

00:33:01.060 --> 00:33:01.820
Und jetzt gibt es halt

00:33:01.820 --> 00:33:05.040
sozusagen als Array-Extension

00:33:05.040 --> 00:33:06.480
Type halt auch Decimal,

00:33:06.580 --> 00:33:08.300
sodass man das halt auch in Pandas Data

00:33:08.300 --> 00:33:10.520
Frames halt Geld quasi mit Kommastellen

00:33:10.520 --> 00:33:12.060
verwenden kann, ohne dass es da irgendwie,

00:33:12.360 --> 00:33:14.460
ohne dass man da mit schlimmen

00:33:14.460 --> 00:33:16.300
Konsequenzen rechnen muss.

00:33:16.800 --> 00:33:17.820
Und es gibt sowas wie

00:33:17.820 --> 00:33:20.440
DateTime mit Timezonen

00:33:20.440 --> 00:33:21.880
dran und so, das ging vorher auch nicht.

00:33:22.620 --> 00:33:24.160
Und das ist... Achso, sowas wie

00:33:24.160 --> 00:33:26.080
Grad mit Celsius-Erfahrenheit vielleicht.

00:33:26.600 --> 00:33:27.980
Das ist nochmal ein anderes, genau,

00:33:28.120 --> 00:33:29.680
das möchte man auch gerne haben.

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

00:33:32.300 --> 00:33:34.080
Es gibt Bibliotheken dafür, dass man halt

00:33:34.080 --> 00:33:36.080
an Spalten auch noch irgendwie so eine

00:33:36.080 --> 00:33:37.620
Maßeinheit dran klebt.

00:33:38.880 --> 00:33:40.520
Die Annotationen

00:33:40.520 --> 00:33:42.240
und auch Skalierungsfaktoren

00:33:42.240 --> 00:33:43.840
kommen auch mit unter aus dem

00:33:43.840 --> 00:33:46.040
zugrunde liegenden Datenformat, aus dem man nachher

00:33:46.040 --> 00:33:47.900
importiert. Also es gibt irgendwie

00:33:47.900 --> 00:33:50.000
wissenschaftliche Datenformate, die speichern sowas

00:33:50.000 --> 00:33:52.020
alles mit. HDF5

00:33:52.020 --> 00:33:54.100
oder NetCDF oder

00:33:54.100 --> 00:33:55.980
wie das inzwischen heißt. Wie sieht das dann aus?

00:33:56.060 --> 00:33:57.380
Ist da eine Spalte, ein Tupel drin?

00:33:58.740 --> 00:34:00.260
Da gibt es im Prinzip

00:34:00.260 --> 00:34:02.160
irgendwie so eine Tabelle von

00:34:02.160 --> 00:34:03.660
Metadaten, wo drin steht,

00:34:03.860 --> 00:34:06.020
welche Spalten, welche Maßeinheit, welches

00:34:06.020 --> 00:34:08.080
Skalierungsfaktoren haben, wann die zuletzt

00:34:08.080 --> 00:34:12.140
bearbeitet wurden. Und darunter

00:34:12.140 --> 00:34:13.820
stehen dann serialisiert die Daten drin.

00:34:14.840 --> 00:34:16.180
Und dadurch hat man

00:34:16.180 --> 00:34:18.160
sehr, sehr schnellen, sequentiellen

00:34:18.160 --> 00:34:20.160
Zugriff auf seine Daten, hat aber

00:34:20.160 --> 00:34:22.120
trotzdem die Möglichkeit, diese

00:34:22.120 --> 00:34:26.060
Skalierung und Einheiten

00:34:26.060 --> 00:34:27.940
mitzuführen. Und

00:34:27.940 --> 00:34:30.000
in Pandas weiß ich nicht, ob das

00:34:30.000 --> 00:34:32.020
inzwischen mit importiert wird,

00:34:32.320 --> 00:34:32.640
aber

00:34:32.640 --> 00:34:35.100
diese Erweiterung.

00:34:35.960 --> 00:34:37.320
Ja, ich habe jetzt

00:34:37.320 --> 00:34:39.260
normalerweise auch nicht mehr parat, wie die

00:34:39.260 --> 00:34:41.460
Bibliothek, es gibt eine Bibliothek für so Maßeinheiten und so was.

00:34:41.940 --> 00:34:43.160
Ich weiß aber nicht genau, wie das

00:34:43.160 --> 00:34:45.300
gemacht ist, müsste ich nochmal nachgucken.

00:34:45.400 --> 00:34:46.900
Vielleicht können wir das einfach dann

00:34:46.900 --> 00:34:49.500
beim nächsten Mal nachreichen oder so.

00:34:50.320 --> 00:34:51.480
Auf jeden Fall, da gibt es etwas

00:34:51.480 --> 00:34:52.800
und das kriegt man schon irgendwie

00:34:52.800 --> 00:34:55.060
alles auch mit dazu geschrieben.

00:34:56.160 --> 00:34:57.320
Ja, also genau, das

00:34:57.320 --> 00:34:58.880
eigentlich, so wie früher, oder

00:34:58.880 --> 00:35:01.180
der Default ist immer noch bei Pandas,

00:35:01.300 --> 00:35:03.520
wie Sachen gespeichert werden, das

00:35:03.520 --> 00:35:05.860
nennt sich irgendwie Block Manager oder Block Storage

00:35:05.860 --> 00:35:07.740
und das sind immer

00:35:07.740 --> 00:35:09.760
2D NumPy Arrays

00:35:09.760 --> 00:35:12.340
und

00:35:12.340 --> 00:35:13.660
die sind halt immer sozusagen, also man

00:35:13.660 --> 00:35:15.300
würde eigentlich denken, dass

00:35:15.300 --> 00:35:17.720
ein DataFrame, dass jede Spalte

00:35:17.720 --> 00:35:18.800
irgendwie ein

00:35:18.800 --> 00:35:22.000
eindimensionales NumPy Array

00:35:22.000 --> 00:35:24.080
ist, aber das ist halt nicht so,

00:35:24.220 --> 00:35:26.020
sondern ein DataFrame besteht

00:35:26.020 --> 00:35:28.240
aus Blocks

00:35:28.240 --> 00:35:29.500
von 2D

00:35:29.500 --> 00:35:32.240
NumPy-Arrays jeweils

00:35:32.240 --> 00:35:34.280
zu einem, also unterteilt

00:35:34.280 --> 00:35:36.280
nach Datentyp, also wenn ich jetzt sagen habe

00:35:36.280 --> 00:35:38.320
ein

00:35:38.320 --> 00:35:40.400
DataFrame, der drei Spalten

00:35:40.400 --> 00:35:41.980
hat, zwei davon float, einer

00:35:41.980 --> 00:35:44.320
Integer, dann besteht das

00:35:44.320 --> 00:35:46.280
Ding aus zwei NumPy-Arrays, eins

00:35:46.280 --> 00:35:48.140
mit Integer und eins mit float,

00:35:48.360 --> 00:35:49.400
das halt zwei Spalten hat.

00:35:50.380 --> 00:35:52.280
Da muss man jetzt natürlich aufpassen, von welcher

00:35:52.280 --> 00:35:54.040
Seite man drauf guckt, weil

00:35:54.040 --> 00:35:56.080
aus Pandas Sicht ist das erstmal

00:35:56.080 --> 00:35:58.420
eine Liste von Pandas Series,

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

00:36:01.560 --> 00:36:03.120
Die Abbildung als

00:36:03.120 --> 00:36:05.020
NumPy-Arrays ist natürlich

00:36:05.020 --> 00:36:06.960
dann irgendwie die technische zugrunde

00:36:06.960 --> 00:36:08.300
liegende Abbildung.

00:36:09.500 --> 00:36:10.680
Ja, genau. Das ist halt,

00:36:10.920 --> 00:36:12.260
eigentlich sollte das egal sein.

00:36:13.180 --> 00:36:14.720
Sollte man sich eigentlich keine Gedanken darüber machen,

00:36:14.820 --> 00:36:16.920
sondern, genau, eigentlich ist eine Series halt quasi,

00:36:16.920 --> 00:36:18.940
kann man es verstehen als Spalte oder eben Vektor,

00:36:19.140 --> 00:36:19.900
eindimensionale

00:36:19.900 --> 00:36:22.820
Datenstruktur mit halt vielleicht noch einem Index dran.

00:36:23.620 --> 00:36:23.980
Aber

00:36:23.980 --> 00:36:26.820
so wird es halt nicht gespeichert und

00:36:26.820 --> 00:36:28.720
das Blöde ist, dass diese

00:36:28.720 --> 00:36:30.700
Abstraktion halt auch so liegt, weil

00:36:30.700 --> 00:36:31.340
wenn man jetzt

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

00:36:35.760 --> 00:36:36.960
dann hat man das Problem,

00:36:37.320 --> 00:36:38.880
dass dadurch,

00:36:39.220 --> 00:36:40.640
dass jetzt, wenn man schon ein paar

00:36:40.640 --> 00:36:42.660
Float-Spalten da drin hat und man

00:36:42.660 --> 00:36:43.820
fügt jetzt eine dazu, dann

00:36:43.820 --> 00:36:46.920
geht das ja nicht mehr wirklich,

00:36:47.160 --> 00:36:48.700
sondern dann müssen die kompletten Daten alle

00:36:48.700 --> 00:36:49.540
kopiert werden dafür.

00:36:50.800 --> 00:36:52.720
Und wenn man jetzt in der Schleife

00:36:52.720 --> 00:36:54.580
irgendwie Spalten hinzufügt oder so, dann

00:36:54.580 --> 00:36:56.680
kann es sein, dass einem der Speicher platzt und man weiß überhaupt

00:36:56.680 --> 00:36:58.720
nicht warum. Das heißt, man muss im Grunde wissen,

00:36:59.040 --> 00:37:00.180
dass Pandas das so macht

00:37:00.180 --> 00:37:03.000
und dann gibt es dann immer so Tipps,

00:37:03.300 --> 00:37:04.660
die dann sagen, wenn man da irgendwie viele

00:37:04.660 --> 00:37:06.820
Spalten hinzufügt, dann immer erst mal die einzelnen

00:37:06.820 --> 00:37:08.520
Spalten sammeln und dann hinterher alle

00:37:08.520 --> 00:37:09.740
zusammenfügen oder so, nicht

00:37:09.740 --> 00:37:12.700
irgendwie auf einem großen Data-Frame eine Spalte hinzufügen,

00:37:12.760 --> 00:37:14.000
dann noch eine hinzufügen, das ist schlecht

00:37:14.000 --> 00:37:16.660
und das sollte eigentlich natürlich,

00:37:16.740 --> 00:37:18.600
das sind so Schwächen bei Pandas, das sollte ja eigentlich

00:37:18.600 --> 00:37:20.540
nicht, das sollte einen gar nicht interessieren, wenn man das

00:37:20.540 --> 00:37:22.580
benutzt. Dummerweise muss man solche

00:37:22.580 --> 00:37:24.540
Sachen aber dann vielleicht doch wissen, weil

00:37:24.540 --> 00:37:27.780
man halt dieses Problem da an der Stelle

00:37:27.780 --> 00:37:29.600
noch hat. Aber das kann sein, dass das jetzt

00:37:29.600 --> 00:37:31.140
alles demnächst besser wird oder das ist jetzt

00:37:31.140 --> 00:37:33.640
mit der letzten Version ist es halt schon ein Stück

00:37:33.640 --> 00:37:35.740
besser geworden und da sind halt

00:37:35.740 --> 00:37:37.680
die einzelnen Spalten haben ihren eigenen Typ und ihre

00:37:37.680 --> 00:37:39.720
eigene Speichergeschichte und dann ist das alles

00:37:39.720 --> 00:37:40.380
nicht mehr so ein Problem.

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

00:37:44.200 --> 00:37:45.760
Also Pandas ist gedacht für so Daten,

00:37:46.400 --> 00:37:47.840
also Small Data kann man

00:37:47.840 --> 00:37:48.580
quasi sagen, also

00:37:48.580 --> 00:37:51.560
Daten im Bereich von so ein paar

00:37:51.560 --> 00:37:53.200
Gigabyte, also einstellig Gigabyte,

00:37:54.320 --> 00:37:56.140
weil halt da fast

00:37:56.140 --> 00:37:58.180
alle Operationen dazu führen, dass das irgendwie kopiert wird,

00:37:58.260 --> 00:38:00.040
kann es sehr schnell sein, dass man halt

00:38:00.040 --> 00:38:01.760
irgendwie auch, dass man halt 5 oder

00:38:01.760 --> 00:38:04.020
vielleicht sogar bis zu 10-facher der

00:38:04.020 --> 00:38:06.000
Datenmenge, die tatsächlich auf der Platte landet oder so,

00:38:06.080 --> 00:38:08.080
man dann als Hauptspeicher braucht, weil

00:38:08.080 --> 00:38:10.120
ja, man kopiert ein paar,

00:38:10.300 --> 00:38:12.080
äh, man fügt ein paar Spalten hinzu, transformiert

00:38:12.080 --> 00:38:14.100
ein bisschen was und dann schon hat man irgendwie einen 5-fachen Hauptspeicher

00:38:14.100 --> 00:38:15.240
verbraucht.

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

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

00:38:20.400 --> 00:38:21.700
Aber, äh, also für

00:38:21.700 --> 00:38:23.880
größere Sachen kann man Pandas nicht so super

00:38:23.880 --> 00:38:26.220
benutzen, aber

00:38:26.220 --> 00:38:28.160
für diese kleinen

00:38:28.160 --> 00:38:30.260
Datenmengen ist es halt sehr, sehr cool, weil es super

00:38:30.260 --> 00:38:32.320
interaktiv ist und da auch viel Optimierung

00:38:32.320 --> 00:38:34.340
reingesteckt wurde, die Operationen

00:38:34.340 --> 00:38:36.260
halt auf so, auf den Datenmengen halt

00:38:36.260 --> 00:38:38.300
schnell zu machen, sodass man halt

00:38:38.300 --> 00:38:40.260
oft dann nicht ein paar Sekunden warten muss,

00:38:40.340 --> 00:38:42.180
sondern eigentlich immer nur so ein paar hundert Millisekunden

00:38:42.180 --> 00:38:43.520
und das,

00:38:44.260 --> 00:38:46.400
gerade wenn man das jetzt zusammen mit

00:38:46.400 --> 00:38:47.760
Jupyter Notebooks halt

00:38:47.760 --> 00:38:49.420
interaktiv in einem Browser verwendet,

00:38:49.980 --> 00:38:51.980
ist es halt sehr wichtig, dass man da nicht irgendwie, wenn man

00:38:51.980 --> 00:38:53.980
irgendwas ausführt, halt lange warten muss, sondern

00:38:53.980 --> 00:38:56.160
man drückt irgendwo drauf, es wird ausgeführt

00:38:56.160 --> 00:38:57.240
und man sieht ein Ergebnis und

00:38:57.240 --> 00:38:59.360
kann damit direkt weiterarbeiten.

00:39:00.580 --> 00:39:00.760
Genau.

00:39:01.940 --> 00:39:04.240
Ja, vielleicht noch mal kurz

00:39:04.240 --> 00:39:06.000
in Jupyter Notebooks, also tolles Tool tatsächlich,

00:39:06.140 --> 00:39:07.980
wenn man sich so gerade so Daten aus der

00:39:07.980 --> 00:39:09.820
Wissenschaft angucken will, einfach ein

00:39:09.820 --> 00:39:12.180
DataFrame laden, da die ganzen Daten reinkloppen

00:39:12.180 --> 00:39:13.880
und dann mit Matplotlib und Seaborn

00:39:13.880 --> 00:39:15.700
irgendwo direkt live immer

00:39:15.700 --> 00:39:18.040
Änderungen verfolgen können. Ja, ich würde fast noch

00:39:18.040 --> 00:39:20.260
sagen, also der ganz, ganz klassische

00:39:20.260 --> 00:39:22.300
Workflow ist, man ruft einmal

00:39:22.300 --> 00:39:24.280
Describe auf, dann kriegt man so einmal die

00:39:24.280 --> 00:39:26.100
Rahmendaten, Streumaß und

00:39:26.100 --> 00:39:28.440
Lagemaß auf dem Dataframe

00:39:28.440 --> 00:39:30.480
und dann kriegt man direkt alle statistischen

00:39:30.480 --> 00:39:32.360
Auswertungskennzahlen, die man so kennt.

00:39:32.660 --> 00:39:34.220
Genau, .describe, Klammer auf Klammer zu,

00:39:34.340 --> 00:39:36.400
fertig, dann kriegt man erstmal einen groben

00:39:36.400 --> 00:39:38.400
Überblick über seine Daten. Dann kann man

00:39:38.400 --> 00:39:40.180
natürlich auch in die Daten direkt reingucken mit

00:39:40.180 --> 00:39:41.740
Head und Tail und

00:39:41.740 --> 00:39:44.360
das ist in meiner Erfahrung auch das, was man

00:39:44.360 --> 00:39:46.760
bei einem neuen Datensatz als allererstes

00:39:46.760 --> 00:39:48.520
mal macht, um sich anzugucken, womit

00:39:48.520 --> 00:39:49.500
arbeite ich denn überhaupt?

00:39:50.260 --> 00:40:00.020
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:01.240 --> 00:40:09.840
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.

00:40:10.360 --> 00:40:16.580
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.720 --> 00:40:18.120
Nö, das kann gut sein, dass das funktioniert, ja.

00:40:19.940 --> 00:40:21.340
Also kann man sich halt auch ganz kleine

00:40:21.340 --> 00:40:23.560
Datenchunks, kleine Tabellen direkt

00:40:23.560 --> 00:40:25.120
aus der Zwischenablage

00:40:25.120 --> 00:40:27.400
in seinen Data-Frame reinladen.

00:40:28.380 --> 00:40:29.480
Das heißt, wenn wir jetzt von diesem

00:40:29.480 --> 00:40:31.360
Gigabyte-Bereich liegen, ich glaube, für wissenschaftliche

00:40:31.360 --> 00:40:33.500
Anwendung müsste das in den meisten Fällen noch relativ

00:40:33.500 --> 00:40:35.540
ausreichend sein. Ja, ja, absolut. Also das ist sowieso

00:40:35.540 --> 00:40:36.960
so, die allermeisten Leute haben

00:40:36.960 --> 00:40:39.400
nicht mehr Daten. Also für die allermeisten

00:40:39.400 --> 00:40:41.420
Leute reicht es aus. Wenn man mehr

00:40:41.420 --> 00:40:43.420
hat, dann weiß man das und dann kann man auch was anderes

00:40:43.420 --> 00:40:43.680
nehmen.

00:40:45.680 --> 00:40:46.040
Ja.

00:40:47.980 --> 00:40:49.480
Ja, aber stimmt, wir hatten

00:40:49.480 --> 00:40:51.480
eben noch gar nicht genau, vielleicht sollten wir da so ein bisschen

00:40:51.480 --> 00:40:53.460
systematisch auch nochmal kurz reingehen, was

00:40:53.460 --> 00:40:54.680
also Pandas,

00:40:55.240 --> 00:40:57.520
genau, das hat auch was damit zu tun,

00:40:57.740 --> 00:40:59.520
wo der Name herkommt, also Pandas steht

00:40:59.520 --> 00:41:01.480
eigentlich für Panel Data oder

00:41:01.480 --> 00:41:03.480
das war halt auch mal das, was halt so in der Finanzwelt

00:41:03.480 --> 00:41:05.660
wo Leute von gerätet haben, von Panel Data

00:41:05.660 --> 00:41:07.500
und damit meinen sie

00:41:07.500 --> 00:41:09.000
dann halt oft Excel Sheets

00:41:09.000 --> 00:41:10.520
irgendwie oder mehrere davon

00:41:10.520 --> 00:41:13.340
und das kann Pandas auch, ist

00:41:13.340 --> 00:41:15.420
aber irgendwie nicht mehr so, also es gibt auch noch

00:41:15.420 --> 00:41:17.700
es gibt halt einmal Series, es gibt Data Frames

00:41:17.700 --> 00:41:19.180
das ist halt sozusagen die zweidimensionale

00:41:19.180 --> 00:41:22.700
Tabelle

00:41:22.700 --> 00:41:24.620
irgendwie, Serious ist eindimensional

00:41:24.620 --> 00:41:26.760
und dann gibt es auch noch Panels, die sind halt

00:41:26.760 --> 00:41:28.100
dann mehrdimensional

00:41:28.100 --> 00:41:30.520
und die werden aber eigentlich nicht mehr

00:41:30.520 --> 00:41:31.580
verwendet, glaube ich, oder

00:41:31.580 --> 00:41:33.700
wurden eigentlich nie so wirklich

00:41:33.700 --> 00:41:36.500
viel verwendet und das ist, glaube ich,

00:41:36.520 --> 00:41:38.480
überliegen die Leute auch gerade, ob sie das irgendwie wieder

00:41:38.480 --> 00:41:40.340
rausnehmen, weil es eigentlich ziemlich sinnlos ist

00:41:40.340 --> 00:41:42.800
und der Hauptnutzen irgendwie bei den Data Frames

00:41:42.800 --> 00:41:43.060
ist.

00:41:47.940 --> 00:41:48.340
Genau.

00:41:48.920 --> 00:41:50.020
Daher kommt der Name.

00:41:50.300 --> 00:41:52.820
Es ist ein bisschen blöd, wenn man danach googeln will

00:41:52.820 --> 00:41:54.640
und dann hat man Tierbilder.

00:41:56.640 --> 00:41:58.980
Aber wir haben immer wieder Tierbilder

00:41:58.980 --> 00:42:00.700
dabei. Auch interessant, dass das Vorbild

00:42:00.700 --> 00:42:02.720
für Pandas ist R,

00:42:02.840 --> 00:42:03.400
denke ich mal.

00:42:04.460 --> 00:42:06.120
Das ist mit Googeln auch nicht viel einfacher, aber

00:42:06.120 --> 00:42:07.400
genau.

00:42:09.460 --> 00:42:10.840
Ja, ich weiß nicht,

00:42:11.060 --> 00:42:12.580
du hast auch schon mal mit A gearbeitet,

00:42:13.060 --> 00:42:13.240
Simon.

00:42:14.340 --> 00:42:17.060
Wie kann man

00:42:17.060 --> 00:42:18.320
das eigentlich miteinander vergleichen?

00:42:18.920 --> 00:42:21.460
Und es ist ja vielleicht auch ganz interessant zu sehen, wo das herkommt.

00:42:22.200 --> 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:33.800
Und tatsächlich muss ich sagen, die R-Data-Frames, die den Pandas-Data-Frames sehr, sehr ähnlich sind,

00:42:34.700 --> 00:42:42.120
die hatten irgendwie so zwei, drei zentrale Vorteile gegenüber Excel, weswegen ich irgendwann komplett gewechselt bin.

00:42:42.780 --> 00:42:46.900
Einer ist sicherlich, dass die Data-Frames immer rechteckig sind.

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

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

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

00:42:59.100 --> 00:43:04.960
Genau, wenn es ein Not a Number ist, ist das okay, aber es muss auf jeden Fall irgendeinen Eintrag geben.

00:43:05.580 --> 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:14.720 --> 00:43:21.740
dann gibt es bei DataFrames grundsätzlich auch Typen je Spalte.

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

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

00:43:29.080 --> 00:43:31.740
Und da kann man auch ganz viel bösen Schabernack mit treiben.

00:43:33.780 --> 00:43:39.660
Und in DataFrames, dadurch einfach, dass man eine Series pro Spalte hat,

00:43:39.800 --> 00:43:41.760
hat auch eine Spalte immer nur einen Typ.

00:43:43.120 --> 00:44:08.840
Und das Dritte, was ich an Data Frames unheimlich zu schätzen wusste, waren, 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 Text erscheinen, sowas wie, weiß ich nicht, Beispiele.

00:44:10.840 --> 00:44:14.540
Blau, Rot, Gelb als Farben in einer Spalte.

00:44:15.540 --> 00:44:19.940
Dass die in dem zugrunde liegenden Datenformat

00:44:19.940 --> 00:44:21.620
erst mal sowas wie Integer sind

00:44:21.620 --> 00:44:24.780
und entsprechend auch relativ schnell

00:44:24.780 --> 00:44:26.340
zum Indizieren benutzt werden können,

00:44:27.100 --> 00:44:30.560
aber für die Anzeige, für das Menschenlesbare

00:44:30.560 --> 00:44:33.920
wieder als Rot, Gelb, Grün, Blau dargestellt werden.

00:44:34.120 --> 00:44:37.000
Okay. Wie macht Pandas das? Als Dictionary dann?

00:44:37.600 --> 00:45:05.960
Das war lange, also in Pandas heißen die Dinger Categorials und das wurde dann quasi intern irgendwie auf Integers abgebildet. Man hatte die einfach durchnummeriert und dann war das halt, was halt natürlich auch viel weniger Platz braucht als Text, aber jetzt auch glaube ich mit 0.24 ist es jetzt so, es hat auch einen eigenen Datentyp bekommen, sodass es halt jetzt auch so ein First Class Citizen im Grunde ist.

00:45:05.960 --> 00:45:07.920
so vorher war es halt auch mal so, naja,

00:45:08.180 --> 00:45:10.000
es sind komische Dinge passiert. Ich hatte zum Beispiel mal

00:45:10.000 --> 00:45:10.480
irgendwann

00:45:10.480 --> 00:45:14.900
mit Categoricals

00:45:14.900 --> 00:45:16.220
auch so ein Problem. Ich habe da irgendwie

00:45:16.220 --> 00:45:18.500
größere Data Frames irgendwie zusammengebastelt

00:45:18.500 --> 00:45:20.280
und dann ist mir

00:45:20.280 --> 00:45:21.960
irgendwie so regelmäßig der Hauptspeicher explodiert

00:45:21.960 --> 00:45:24.260
und ich wusste nicht warum, habe ich dann auch einen Bug

00:45:24.260 --> 00:45:25.540
irgendwie bei Panas gefeilt und

00:45:25.540 --> 00:45:27.520
der war dann ziemlich lange offen.

00:45:28.360 --> 00:45:30.100
Das hatte halt auch damit zu tun, dass es nicht

00:45:30.100 --> 00:45:32.100
irgendwie nativ irgendwie da drin war,

00:45:32.100 --> 00:45:33.960
sondern das war halt mit den anderen IntelliJer-Geschichten

00:45:33.960 --> 00:45:35.600
irgendwie verknuselt und

00:45:35.600 --> 00:45:36.740
Ja, das ist schrecklich.

00:45:38.980 --> 00:45:42.620
Ja, aber genau, das ist natürlich eine sehr nette Sache,

00:45:42.780 --> 00:45:45.460
wenn man das halt so machen kann.

00:45:46.420 --> 00:45:49.900
Ja, das heißt, man sieht halt den Text in der Tabelle,

00:45:50.080 --> 00:45:52.280
aber in Wirklichkeit speichert man halt viel weniger Daten,

00:45:52.400 --> 00:45:53.360
halt nur eine Zahl.

00:45:55.300 --> 00:45:56.700
Ja, praktisch.

00:45:57.460 --> 00:45:58.860
Wie schaut man sich denn so Daten dann an?

00:45:59.100 --> 00:46:00.820
Also ich musste ja irgendwie eine Struktur bringen.

00:46:00.820 --> 00:46:04.140
Ich habe jetzt irgendwie ganz viele Spalten irgendwie mit Zeilen

00:46:04.140 --> 00:46:06.120
in meinem großen rechteckigen Datenfeld

00:46:06.120 --> 00:46:08.020
drin oder sowas und ich möchte jetzt irgendwie

00:46:08.020 --> 00:46:08.660
die kombinieren.

00:46:10.820 --> 00:46:12.140
Also man kann auch direkt auf dem,

00:46:12.340 --> 00:46:13.760
also das benutze ich tatsächlich ziemlich gerne,

00:46:14.120 --> 00:46:15.560
man kann sagen,

00:46:16.080 --> 00:46:17.960
also DataFrame, man kürzt es normalerweise immer ab

00:46:17.960 --> 00:46:19.800
mit df, also das

00:46:19.800 --> 00:46:21.460
Standardobjekt, was man dann halt sozusagen hat,

00:46:22.140 --> 00:46:23.300
heißt einfach df

00:46:23.300 --> 00:46:25.480
und da kann man einfach sagen df.plot

00:46:25.480 --> 00:46:28.060
und dem halt noch so ein bisschen Parameter

00:46:28.060 --> 00:46:29.300
mitgeben und dann

00:46:29.300 --> 00:46:31.660
plottet das halt direkt.

00:46:31.660 --> 00:46:33.580
Dann kannst du ja dann Daten anzeigen,

00:46:33.680 --> 00:46:34.800
die du dann reingegeben hast, also

00:46:34.800 --> 00:46:37.080
die Visualisierungsebene dann damit quasi.

00:46:37.300 --> 00:46:39.480
Genau, genau. Und im Notebook sieht man halt auch dann direkt irgendwie

00:46:39.480 --> 00:46:40.520
quasi grafisch was.

00:46:41.760 --> 00:46:43.260
Standardmäßig ist es dann halt ein Matplotlib,

00:46:43.980 --> 00:46:45.340
aber man kann halt das auch,

00:46:45.460 --> 00:46:47.220
dieses Plotting-Backend von Panda

00:46:47.220 --> 00:46:49.380
sozusagen austauschen, also es ist halt so pluggable und man kann

00:46:49.380 --> 00:46:51.500
das austauschen und man kann halt auch Bokeh

00:46:51.500 --> 00:46:52.740
zum Beispiel nehmen oder

00:46:52.740 --> 00:46:55.320
weiß gar nicht, ist auch noch viel

00:46:55.320 --> 00:46:57.480
andere. Ich habe Plotly

00:46:57.480 --> 00:46:59.500
schon gesehen in dem Zusammenhang

00:46:59.500 --> 00:47:01.500
und Seaborn ist ja im Prinzip

00:47:01.500 --> 00:47:03.600
Matplotlib nochmal ein bisschen erweitert

00:47:03.600 --> 00:47:06.120
kann man da auch reinpluggen.

00:47:06.240 --> 00:47:07.840
Genau, so dass es halt, man hat halt

00:47:07.840 --> 00:47:10.000
immer, kann es dann anders aussehen

00:47:10.000 --> 00:47:11.840
lassen, so dass zum Beispiel bei Bokeh oder

00:47:11.840 --> 00:47:13.760
Plotly ist es halt so, wenn man dann sagt

00:47:13.760 --> 00:47:15.760
DF Plot irgendwas, dann kann man

00:47:15.760 --> 00:47:17.500
das, dann ist das, was man sieht,

00:47:17.760 --> 00:47:19.700
dann halt auch scrollbar zum Beispiel,

00:47:19.780 --> 00:47:21.260
man kann da drin zoomen oder so,

00:47:21.700 --> 00:47:23.800
was man bei einem Matplotlib-Bild jetzt nicht machen kann,

00:47:23.860 --> 00:47:25.480
weil da ist einfach, das ist quasi dann halt so ein

00:47:25.480 --> 00:47:27.960
statisch rausgerendertes PNG oder so

00:47:27.960 --> 00:47:29.700
und dann, wenn man da reinzoomt,

00:47:29.700 --> 00:47:31.720
wird es nur pixelig, aber man sieht

00:47:31.720 --> 00:47:33.060
nicht mehr, während halt bei

00:47:33.060 --> 00:47:35.680
eben dieser, bei Plotly

00:47:35.680 --> 00:47:37.400
oder so hat man dann, kann man, wenn man

00:47:37.400 --> 00:47:38.940
reinsucht, sieht man einfach an der Stelle mehr

00:47:38.940 --> 00:47:41.460
und das, man muss

00:47:41.460 --> 00:47:43.360
an dem Plotaufruf eigentlich

00:47:43.360 --> 00:47:45.320
nichts ändern, sondern man tauscht einfach nur das

00:47:45.320 --> 00:47:46.360
Backend aus und

00:47:46.360 --> 00:47:49.260
ja, das ist schon sehr nett und das verwende ich tatsächlich

00:47:49.260 --> 00:47:51.440
oft irgendwie

00:47:51.440 --> 00:47:52.460
um Sachen zu visualisieren.

00:47:52.860 --> 00:47:54.740
Wenn man so einmal kurz schnell so einen Überblick bekommt.

00:47:55.300 --> 00:47:57.280
Wie suche ich mir die Daten denn aus? Also wie kopiere ich

00:47:57.280 --> 00:47:59.240
denn da irgendwas von den Daten, wenn ich ja so ganz viele

00:47:59.240 --> 00:48:01.340
Spalten und Teilen habe? Also wenn

00:48:01.340 --> 00:48:03.500
man gar nicht weiß, wie man anfangen soll,

00:48:04.500 --> 00:48:05.520
wenn ich mich richtig erinnere,

00:48:05.600 --> 00:48:07.140
macht Plot standardmäßig einfach ein

00:48:07.140 --> 00:48:08.820
Pair-Plot. Alles gegen alles.

00:48:09.420 --> 00:48:11.360
Dann sieht man schon mal, wie sind die Daten zueinander

00:48:11.360 --> 00:48:13.420
verteilt. Dann kann

00:48:13.420 --> 00:48:14.880
man Effekte sehen, wie

00:48:14.880 --> 00:48:17.540
auf zwei bestimmten Variablen

00:48:17.540 --> 00:48:19.240
ist die Verteilung eher so bimodal.

00:48:19.320 --> 00:48:21.220
Man hat zwei Felder von Punkten oder sowas.

00:48:21.860 --> 00:48:23.480
Also da kann man schon grundsätzlich

00:48:23.480 --> 00:48:25.360
mal sehen, wie sind meine Daten überhaupt verteilt.

00:48:26.860 --> 00:48:27.340
Ansonsten

00:48:27.340 --> 00:48:29.360
gibt es ja oft eine Fragestellung.

00:48:30.720 --> 00:48:33.720
ideellen Welt gibt es im Vorfeld

00:48:33.720 --> 00:48:36.800
eine Fragestellung und dann kann man auf diese Fragestellung

00:48:36.800 --> 00:48:39.620
hinzuarbeiten. Dann weiß man genau, welche Spalten brauche ich

00:48:39.620 --> 00:48:42.700
jetzt gleich. Spaltenzugriffe sind

00:48:42.700 --> 00:48:45.680
in Pandas, finde ich, super, super easy

00:48:45.680 --> 00:48:48.760
und convenient. Man gibt im Prinzip einfach nur

00:48:48.760 --> 00:48:51.500
von seinem DataFrame-Objekt per

00:48:51.500 --> 00:48:54.120
.syntax den Spaltennamen an oder in

00:48:54.120 --> 00:48:56.660
eckigen Klammern wie bei einem Listenzugriff.

00:48:58.640 --> 00:49:00.220
Jetzt muss ich gerade genau überlegen.

00:49:00.720 --> 00:49:02.880
Doch, da geht der Spaltenname

00:49:02.880 --> 00:49:04.600
auch. Ja, es gibt

00:49:04.600 --> 00:49:06.320
zwei Interfaces. Es gibt halt mit

00:49:06.320 --> 00:49:08.720
man kann halt entweder den Namen

00:49:08.720 --> 00:49:10.580
nehmen oder man kann halt auch den numerischen Index

00:49:10.580 --> 00:49:12.680
nehmen. Das ist Log

00:49:12.680 --> 00:49:14.720
und I-Log, glaube ich, sind die unterschiedlichen

00:49:14.720 --> 00:49:16.380
Funktionen, die man da aufrufen kann.

00:49:17.100 --> 00:49:18.560
Aber also ich würde auch eigentlich

00:49:18.560 --> 00:49:20.480
immer eher, also mit den Indizes

00:49:20.480 --> 00:49:21.720
ist eine ältere Geschichte und

00:49:21.720 --> 00:49:24.160
ich würde eher die Namen immer nehmen, weil das

00:49:24.160 --> 00:49:25.900
klarer ist, was da eigentlich gemeint ist.

00:49:26.300 --> 00:49:28.640
Und die werden dann irgendwie mit GroupBy irgendwie so vorsortiert

00:49:28.640 --> 00:49:30.580
oder sowas und dann gibt es irgendwelche Alternativen und dann kann

00:49:30.580 --> 00:49:32.280
man die in Beziehung setzen und dann

00:49:32.280 --> 00:49:34.680
alles plotten? Also erst mal

00:49:34.680 --> 00:49:36.720
hat man Zugriff auf seine tabellarischen

00:49:36.720 --> 00:49:38.540
Daten. Und da kann man sagen,

00:49:38.640 --> 00:49:40.600
ich möchte jetzt Spalten A,

00:49:40.780 --> 00:49:42.140
B und E plotten

00:49:42.140 --> 00:49:44.640
auf einer X-Achse,

00:49:44.800 --> 00:49:46.780
die ist in Spalte D meinetwegen.

00:49:47.380 --> 00:49:48.100
Aber nur die roten.

00:49:48.660 --> 00:49:50.480
Oder die roten und die gelben vergleichen. Genau.

00:49:50.480 --> 00:49:51.860
Das ist dann der zweite Schritt,

00:49:52.460 --> 00:49:54.200
dass man anfängt, vorher zu

00:49:54.200 --> 00:49:56.040
aggregieren. Man kann dann

00:49:56.040 --> 00:49:57.680
überlegen, will ich

00:49:57.680 --> 00:50:00.180
nur bestimmte Gruppierungen haben?

00:50:00.580 --> 00:50:02.320
Es gibt Funktionen, die heißen GroupBy.

00:50:02.960 --> 00:50:12.500
Es gibt auch Funktionen, um eine kumulative Summe über irgendeinen Datensatz direkt per Funktion aufzurufen.

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

00:50:16.740 --> 00:50:23.420
Dass man sagt, okay, ich habe jetzt hier meine Daten und ich plotte dahinter in einer zweiten Serie auch noch die kumulative Summe.

00:50:24.160 --> 00:50:27.940
Dann ist das quasi per einzelnen Funktionsaufruf in Pandas möglich.

00:50:29.880 --> 00:50:46.900
Das ist spannend für die ganze Anwendung, wenn man irgendwie so kategorisierbare Daten mit verschiedenen Merkmalen hat und man dann bestimmten Merkmalen, bestimmte Wahrscheinlichkeiten zuordnen will, also mehrere Merkmale hat, also keine Ahnung, Leute ab zwei Meter und trotzdem unter, weiß nicht, 70 Kilo und welche Wahrscheinlichkeit haben die für bestimmte Dinge?

00:50:46.900 --> 00:51:14.040
Genau, da kommen wir in einen anderen Bereich so ein bisschen rein und das ist Indizierung auf Basis von Boolean Werten. Also man kann jetzt zum Beispiel sagen, ich möchte aus meinem Datensatz eigentlich nur alle Zeilen auswählen, in denen Spalte A, was zum Beispiel die Höhe sein könnte, sagen wir Höhe eines Menschen kleiner als 1,80 Meter und größer als 1,60 Meter ist.

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

00:51:23.540 --> 00:51:32.080
Was wird denn da technisch erzeugt? Also macht der eine Kopie der Tabelle mit diesen Werten oder setzt der halt dann noch eine neue Tabelle daneben mit so Bolian-Werten, ist wahr, ist falsch?

00:51:32.360 --> 00:51:35.060
Oder macht der auch so einen Index, den er nur liest?

00:51:37.760 --> 00:51:45.820
Gut, also meistens wird tatsächlich, wenn man jetzt irgendwie da irgendwas extrahiert, wird kopiert. Man kann aber auch sagen, dass es nicht kopiert werden soll.

00:51:49.460 --> 00:52:06.320
Ja, also das sind meistens diese Boolean, also im Grunde erzeugt das halt eine Spalte, wenn man jetzt zum Beispiel sowas hat, man sagt DF, eckige Klammer auf, irgendwie, DF-Funktionalität ist größer irgendwas und DF-Funktionalität ist kleiner irgendwas.

00:52:08.240 --> 00:52:10.340
Bullshit-Ausdruck sozusagen dann halt

00:52:10.340 --> 00:52:12.300
irgendwie in eine Spalte verwendet,

00:52:12.540 --> 00:52:14.440
wo dann irgendwie in jeder Zeile True oder False

00:52:14.440 --> 00:52:16.440
drinsteht. Und dann wird das halt,

00:52:16.580 --> 00:52:17.800
wenn man jetzt zeilenweise filtert,

00:52:18.660 --> 00:52:20.460
werden halt alle Zeilen,

00:52:20.520 --> 00:52:23.000
die halt True sind, rausgesucht

00:52:23.000 --> 00:52:24.580
und alle anderen werden halt ignoriert quasi.

00:52:26.220 --> 00:52:26.400
Und

00:52:26.400 --> 00:52:28.500
ja, ganz genau, wie das

00:52:28.500 --> 00:52:30.120
technisch unten drunter funktioniert, weiß ich jetzt aber auch nicht.

00:52:34.220 --> 00:52:34.620
Und

00:52:34.620 --> 00:52:36.160
ja, das sind halt so,

00:52:36.420 --> 00:52:37.980
ich kann mir vorstellen, dass irgendwie so ein

00:52:37.980 --> 00:52:39.840
NumPy hat irgendwie als Feature drin, dass man Sachen,

00:52:40.140 --> 00:52:42.160
dass man so Masken verwenden kann, aber ich bin mir

00:52:42.160 --> 00:52:43.480
nicht sicher, ob es wirklich verwendet wird, keine Ahnung.

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

00:52:47.280 --> 00:52:47.920
Ja, und

00:52:47.920 --> 00:52:50.140
dann kann man da

00:52:50.140 --> 00:52:52.040
irgendwie weitere Dinge mitmachen.

00:52:52.180 --> 00:52:53.480
Das ist halt recht

00:52:53.480 --> 00:52:55.940
schön, schöne Methode,

00:52:56.060 --> 00:52:57.960
um da halt irgendwie Sachen rauszuselecten. Vielleicht kann man

00:52:57.960 --> 00:52:59.680
an der Stelle auch mal grad eine

00:52:59.680 --> 00:53:02.060
Blogartikel-Reihe erwähnen, das fällt mir da grad ein,

00:53:02.640 --> 00:53:04.040
die ich immer

00:53:04.040 --> 00:53:05.180
wieder, wenn ich irgendwie Leuten

00:53:05.180 --> 00:53:07.240
Panas Erzähler

00:53:07.240 --> 00:53:09.080
auch mit erwähne, weil die so toll ist.

00:53:09.240 --> 00:53:13.160
Das ist von Tom Augsburger

00:53:13.160 --> 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.680
und das ist Teil 1

00:53:21.680 --> 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.320
momentan

00:53:26.320 --> 00:53:30.020
Kenne ich noch gar nicht, muss ich auch mal reinschauen

00:53:30.020 --> 00:53:30.260
Ja

00:53:30.260 --> 00:53:32.580
So lernt man immer dazu

00:53:32.580 --> 00:53:35.700
Genau und der beschreibt

00:53:35.700 --> 00:53:37.340
halt sehr ausführlich, wie das mit dem Indexing

00:53:37.340 --> 00:53:39.260
halt eher so aus User-Perspektive, was man damit alles

00:53:39.260 --> 00:53:40.980
machen kann, funktioniert.

00:53:42.580 --> 00:53:42.980
Und

00:53:42.980 --> 00:53:45.120
ja, also gerade wenn man jetzt nicht nur

00:53:45.120 --> 00:53:46.780
einen Index hat, das ist auch etwas, was halt

00:53:46.780 --> 00:53:49.080
Pandas kennt, was ich von Datenbanken

00:53:49.080 --> 00:53:50.560
so nicht kenne. Also Datenbanken bedeuten

00:53:50.560 --> 00:53:53.060
Indizes ein bisschen was anderes als halt jetzt bei Pandas.

00:53:53.600 --> 00:53:55.000
Man kann halt bei Pandas

00:53:55.000 --> 00:53:56.880
auch mehrdimensional Indizes haben und dann da halt

00:53:56.880 --> 00:53:59.120
irgendwie kreuz und quer verschachtelte Abfragen

00:53:59.120 --> 00:54:00.480
macht. Und da

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

00:54:03.060 --> 00:54:05.060
dann raucht einem da relativ schnell so der Kopf.

00:54:05.520 --> 00:54:06.940
Aber wenn man tatsächlich diese

00:54:06.940 --> 00:54:08.900
Probleme hat, dann kann das ultra praktisch

00:54:08.900 --> 00:54:10.520
sein, wenn man da irgendwie sich mit auskennt

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

00:54:13.480 --> 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.740 --> 00:54:18.800
Im ersten Artikel werden

00:54:18.800 --> 00:54:19.760
glaube ich da irgendwie so halt

00:54:19.760 --> 00:54:22.860
diverse Indizie-Geschichten erklärt

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

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

00:54:25.880 --> 00:54:28.780
und ja, dann

00:54:28.780 --> 00:54:30.380
eins zu Indizes

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

00:54:32.020 --> 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:38.460
mit dem neuen Interface an Dingen machen kann

00:54:38.460 --> 00:54:40.320
und da gibt es halt wirklich verrückte

00:54:40.320 --> 00:54:41.640
Abfragen, die man

00:54:41.640 --> 00:54:44.140
Also das Ding auf jeden Fall ist wieder

00:54:44.140 --> 00:54:46.340
super spannend, was der neueste heiße Scheiß

00:54:46.340 --> 00:54:48.140
ist. Was ich jetzt da gekannt habe, ist auch

00:54:48.140 --> 00:54:50.160
die einzige Quelle, deswegen habe ich jetzt den Vergleich natürlich

00:54:50.160 --> 00:54:52.300
wieder nicht, ist diese Einführung in

00:54:52.300 --> 00:54:54.220
Python mit Data Science

00:54:54.220 --> 00:54:56.540
oder Data Science mit Python von Jake Wanderplast

00:54:56.540 --> 00:54:58.320
Da gibt es auch ein schönes Artikel

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

00:55:00.220 --> 00:55:01.660
frei irgendwo bei GitHub

00:55:01.660 --> 00:55:03.260
Ja, die Notebooks

00:55:03.260 --> 00:55:05.920
Und sogar als Notebooks, die er alle hoffentlich hat

00:55:05.920 --> 00:55:07.900
hat er irgendwie unter MIT-Lizenz da online gestellt

00:55:07.900 --> 00:55:10.120
und da kann man auch genau die Sachen als Notebooks

00:55:10.120 --> 00:55:11.760
direkt alle ausprobieren. Das ist ein tolles Beispiel für

00:55:11.760 --> 00:55:14.180
diese, glaube ich, die einfachen

00:55:14.180 --> 00:55:16.040
so die Basissachen drin, dass man so das grundsätzliche

00:55:16.040 --> 00:55:17.980
alte Prinzip mal versteht, das man direkt dann mit

00:55:17.980 --> 00:55:19.960
Pandas potten kann, ich glaube über den Untergang der

00:55:19.960 --> 00:55:21.020
Titanic oder sowas.

00:55:22.500 --> 00:55:23.600
Ja, sonst benutzen die

00:55:23.600 --> 00:55:26.620
Tutorials oft gerne den Iris-Datensatz.

00:55:26.740 --> 00:55:27.680
Da geht es irgendwie um

00:55:27.680 --> 00:55:29.740
Blütenlänge und Breite und

00:55:29.740 --> 00:55:32.020
das war mir immer ein bisschen sympathischer

00:55:32.020 --> 00:55:32.640
als Biologe.

00:55:34.140 --> 00:55:39.440
Also welche Klassen jetzt wie oder wie viele Frauen, Männer und wie viele Jungs und Kinder untergegangen sind, wie viele nicht.

00:55:39.540 --> 00:55:44.380
Ja, genau. Das ist auch super spannend mit diesen Multi-Level-Indizes.

00:55:44.860 --> 00:55:48.760
Da sollten wir gleich auch nochmal vielleicht ein paar Minuten uns Zeit für nehmen.

00:55:50.040 --> 00:55:55.760
Für den Moment sei vielleicht auch nochmal erwähnt, wenn man jetzt ein Pandas DataFrame haben möchte

00:55:55.760 --> 00:56:00.520
und man importiert das nicht aus einer Datei oder aus der Zwischenablage,

00:56:01.200 --> 00:56:03.880
wie komme ich denn überhaupt zu meinem DataFrame-Objekt?

00:56:04.000 --> 00:56:04.780
Und du hast eben gefragt,

00:56:04.860 --> 00:56:06.180
kann man da vielleicht Dictionaries benutzen?

00:56:06.240 --> 00:56:07.000
Ja, kann man tatsächlich.

00:56:07.720 --> 00:56:10.220
Also wenn ich in Python schon ein Dictionary habe,

00:56:11.080 --> 00:56:14.300
was Keys und als Values Listen hat,

00:56:14.900 --> 00:56:17.800
dann kann ich einfach mein DataFrame erzeugen

00:56:17.800 --> 00:56:21.720
mit pandas.dataframe oder pd.dataframe,

00:56:21.720 --> 00:56:23.760
wenn man pandas als pd importiert,

00:56:24.640 --> 00:56:26.880
und da reingeben, mein Dictionary.

00:56:27.460 --> 00:56:29.720
Dann macht er automatisch aus den Keys Spaltennamen

00:56:30.520 --> 00:56:32.320
und aus den Values, aus den Listen

00:56:32.320 --> 00:56:34.180
macht er dann meine

00:56:34.180 --> 00:56:34.660
Series.

00:56:36.040 --> 00:56:38.220
Hat natürlich zur Bedingung, dass die gleich

00:56:38.220 --> 00:56:40.200
lang sind. Ja. Sonst gibt es da

00:56:40.200 --> 00:56:41.920
einen Fehler. Ich weiß gar nicht, ob der da mit

00:56:41.920 --> 00:56:43.660
NA auffüllt oder ob der

00:56:43.660 --> 00:56:45.620
Ja,

00:56:45.840 --> 00:56:48.220
außer dass es einen Fehler wirft.

00:56:48.320 --> 00:56:50.300
Ich weiß es aber auch nicht. Es gibt auch irgendwie so eine andere Funktion.

00:56:50.420 --> 00:56:52.040
Ich weiß jetzt nicht, bei was es genau geht, wenn man halt

00:56:52.040 --> 00:56:54.100
so ein DataFrame über so ein NumPy-Array hat oder

00:56:54.100 --> 00:56:56.220
sowas, dass der automatisch neue Spalten

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

00:56:58.080 --> 00:56:59.980
fortsetzt. Ich weiß nicht, ob das

00:56:59.980 --> 00:57:02.120
linear passiert oder sowas, habe ich irgendwie kurz entdeckt.

00:57:02.780 --> 00:57:03.860
Wenn man einfach eine neue Spalte

00:57:03.860 --> 00:57:06.060
erstellt dann, wenn man schon drei oder vier hat,

00:57:06.180 --> 00:57:08.000
dass du dann, wenn du die fünfte erstellst, einfach

00:57:08.000 --> 00:57:09.460
dann neue Werte reinbaut.

00:57:11.680 --> 00:57:12.180
Kann sein,

00:57:12.240 --> 00:57:12.660
weiß ich nicht so.

00:57:13.560 --> 00:57:14.940
Vielleicht habe ich auch wieder irgendwelchen Quatsch erzählt.

00:57:15.100 --> 00:57:17.620
Ich weiß gerade nicht genau, was du da

00:57:17.620 --> 00:57:18.500
meinst.

00:57:20.180 --> 00:57:22.100
Jetzt habe ich das Buch natürlich zu Hause liegen lassen.

00:57:23.120 --> 00:57:23.880
Irgendwo nachgeschlagen.

00:57:24.880 --> 00:57:26.120
Buch ist aber auch ein gutes

00:57:26.680 --> 00:57:27.080
Stichwort.

00:57:27.900 --> 00:57:31.340
Und man kriegt ja immer den gut gemeinten Ratschlag, guck doch mal ins Handbuch.

00:57:32.440 --> 00:57:34.700
Das Pandas-Handbuch ist tatsächlich länglich.

00:57:34.700 --> 00:57:37.780
Es hat 2.900 irgendwas Seiten.

00:57:38.740 --> 00:57:49.040
Davon sind rund 900 so die Basisfunktionen, 1.400 nur die API-Referenz und dann nochmal weiterführende Informationen.

00:57:49.320 --> 00:57:50.320
Hast du es durchgelesen?

00:57:50.360 --> 00:57:50.540
Nee.

00:57:52.580 --> 00:57:55.040
So bei aller Liebe, das ist dann doch etwas viel.

00:57:55.200 --> 00:57:56.980
aber man kann halt

00:57:56.980 --> 00:57:58.740
relativ schnell kapitelweise,

00:57:59.100 --> 00:58:00.920
wenn man was ganz Bestimmtes sucht,

00:58:00.940 --> 00:58:02.240
da reinspringen. Okay, so als Index.

00:58:02.540 --> 00:58:04.460
Es ist auch alles, also verlinktes

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

00:58:07.020 --> 00:58:08.000
Inhaltsverzeichnis, genau.

00:58:08.880 --> 00:58:10.960
Verlinktes Inhaltsverzeichnis, man kommt schnell dahin.

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

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

00:58:16.440 --> 00:58:18.320
also die ist schon etwas

00:58:18.320 --> 00:58:20.440
trocken oder so, manchmal muss man sich schon so ein bisschen

00:58:20.440 --> 00:58:22.260
ein bisschen quälen.

00:58:22.540 --> 00:58:23.940
Vielleicht liegt das an dem Tabellenthema?

00:58:24.540 --> 00:58:26.340
Könnte, vielleicht liegt es einfach am Thema.

00:58:27.280 --> 00:58:28.340
Sollte man vielleicht eher

00:58:28.340 --> 00:58:29.600
irgendwie Schreiner werden oder so.

00:58:29.920 --> 00:58:32.560
Das ist vielleicht irgendwie,

00:58:33.040 --> 00:58:34.000
ja, das überlege ich mir manchmal.

00:58:34.960 --> 00:58:35.500
Das wäre toll.

00:58:36.680 --> 00:58:37.720
Ja, aber

00:58:37.720 --> 00:58:39.980
genau,

00:58:40.280 --> 00:58:40.540
ja,

00:58:41.380 --> 00:58:43.740
stimmt, was hatten wir?

00:58:44.000 --> 00:58:46.480
Was gibt es für Datentypen, so Serien,

00:58:46.920 --> 00:58:48.020
Data Frames, Panels?

00:58:49.040 --> 00:58:50.220
Was kann man damit machen?

00:58:50.220 --> 00:58:51.160
Ja, so, genau.

00:58:53.020 --> 00:58:54.340
Man kann auch sehr viele Dinge,

00:58:54.480 --> 00:58:55.900
die man sonst vielleicht mit einer Datenbank machen

00:58:55.900 --> 00:58:57.960
würde, damit tun. Und das hat ja auch

00:58:57.960 --> 00:58:59.640
so den Vorteil. 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.800
von Pandas ist halt

00:59:03.800 --> 00:59:05.720
ziemlich angenehm und ist auch relativ kurz.

00:59:06.140 --> 00:59:07.700
Also wenn du mit einer Datenbank arbeitest und

00:59:07.700 --> 00:59:09.740
SQL-Statements schreibst, das geht natürlich auch,

00:59:10.160 --> 00:59:11.120
aber das ist halt viel

00:59:11.120 --> 00:59:13.040
umständlicher.

00:59:14.320 --> 00:59:16.000
Und Pandas hat da halt eine sehr schöne

00:59:16.000 --> 00:59:18.340
UI

00:59:18.340 --> 00:59:18.800
eigentlich.

00:59:19.700 --> 00:59:21.840
Und man kann viel damit machen, was man halt

00:59:21.840 --> 00:59:23.920
auch mit einer Datenbank normalerweise tun würde. Und insofern

00:59:23.920 --> 00:59:26.340
kann ich das auch nur empfehlen, wenn man jetzt irgendwie so ein Datenbankproblem

00:59:26.340 --> 00:59:28.140
hat. Man kann auch irgendwie die komplette Datenbank,

00:59:28.200 --> 00:59:30.440
meistens sind die ja nicht so groß, auch irgendwie in Pandas

00:59:30.440 --> 00:59:32.480
sich reinholen oder als Data Frames aus der Datenbank

00:59:32.480 --> 00:59:34.520
ziehen und dann da irgendwelche Dinge machen

00:59:34.520 --> 00:59:36.380
und dann schon mal, wenn man dann weiß,

00:59:36.540 --> 00:59:38.380
wie es geht, dann kann man es hinterher auch in SQL machen.

00:59:38.840 --> 00:59:40.080
Aber vieles von dem

00:59:40.080 --> 00:59:42.600
lässt sich auch locker in Pandas mal ausprobieren,

00:59:42.700 --> 00:59:44.220
weil Pandas hat ja eben auch solche Funktionen wie

00:59:44.220 --> 00:59:46.160
man kann Joins machen,

00:59:46.380 --> 00:59:48.280
man kann halt Data Frames Merge, also da heißt das

00:59:48.280 --> 00:59:50.300
dann, also ich glaube, da verwendet man

00:59:50.300 --> 00:59:52.540
eher einen Aufruf Merge oder so, aber im Grunde

00:59:52.540 --> 00:59:54.540
macht es dann halt auch ein Join zwischen

00:59:54.540 --> 00:59:56.800
zwei DataFrames. Dann kann man angeben, auf welchen

00:59:56.800 --> 00:59:58.680
Spalten gejoined werden soll und solche

00:59:58.680 --> 01:00:00.060
Dinge. Und

01:00:00.060 --> 01:00:02.860
genau, eben all diese Group-By-Geschichten.

01:00:03.300 --> 01:00:04.720
Gibt es tatsächlich so eine Funktion, wie man

01:00:04.720 --> 01:00:06.640
eine Datenbank in DataFrame bekommt und

01:00:06.640 --> 01:00:08.760
andersrum, wie man eine DataFrame in irgendeinem Datenbanktyp

01:00:08.760 --> 01:00:09.720
speichert? Ja, ja.

01:00:10.420 --> 01:00:12.720
Also für alle Datenbanken gibt es da Adapter,

01:00:12.900 --> 01:00:14.280
mit denen man die Daten noch auslesen kann.

01:00:15.100 --> 01:00:16.820
Genau, also diese Import-

01:00:16.820 --> 01:00:18.580
Export-Geschichten. Also wir haben

01:00:18.580 --> 01:00:20.800
nur über Import gesprochen,

01:00:21.040 --> 01:00:23.000
aber Export gibt es halt auch für

01:00:23.000 --> 01:00:24.880
alle diese Datentypen. Warum schreibt dann

01:00:24.880 --> 01:00:26.120
irgendjemand noch SQL-Statements?

01:00:28.120 --> 01:00:28.860
Ja doch, also

01:00:28.860 --> 01:00:31.060
manchmal, es kann schon sinnvoll

01:00:31.060 --> 01:00:33.120
durchaus

01:00:33.120 --> 01:00:34.760
sinnvoll sein. Also wenn du an der Datenbank ja auch

01:00:34.760 --> 01:00:37.060
irgendwas manipulieren willst an Werten, dann musst du es ja tun.

01:00:37.200 --> 01:00:38.780
Du kannst ja gar nicht, kannst auch

01:00:38.780 --> 01:00:40.720
ein Pandas machen, aber dann hast du das Problem, musst es ja irgendwann wieder

01:00:40.720 --> 01:00:41.580
zurück in die Datenbank schreiben.

01:00:42.520 --> 01:00:43.700
Dann man klöscht eine neue Datenbank.

01:00:43.700 --> 01:00:44.100
Ja.

01:00:46.300 --> 01:00:47.680
Und gegebenenfalls

01:00:47.680 --> 01:00:49.820
ist das, was du in deinem Speicher bearbeiten

01:00:49.820 --> 01:00:50.720
kannst, auch

01:00:50.720 --> 01:00:53.200
kleiner als das, was

01:00:53.200 --> 01:00:54.980
in der gesamten Datenbank ist. Das heißt,

01:00:55.240 --> 01:00:57.000
beim Import würdest du schon nur einen Teil

01:00:57.000 --> 01:00:59.140
aus der Datenbank nehmen, kannst damit

01:00:59.140 --> 01:01:01.100
aber dann relativ komfortabel

01:01:01.100 --> 01:01:01.700
rumspielen.

01:01:03.740 --> 01:01:05.300
Tatsächlich, der Befehl

01:01:05.300 --> 01:01:06.920
ist Join, auch

01:01:06.920 --> 01:01:09.280
in DataFrames. Ich verwechsel es auch immer wieder,

01:01:09.440 --> 01:01:10.840
deswegen habe ich gerade mal kurz nachgeguckt.

01:01:11.600 --> 01:01:13.200
Und es gibt noch Concatenate,

01:01:13.200 --> 01:01:14.720
da kann man aus einem DataFrame

01:01:14.720 --> 01:01:17.420
Spalten in ein anderes

01:01:17.420 --> 01:01:18.000
reinziehen.

01:01:19.100 --> 01:01:21.140
Ja, und dann, genau,

01:01:21.280 --> 01:01:22.920
solche, eben, es gibt

01:01:22.920 --> 01:01:25.500
so Datenmanipulationsgeschichten,

01:01:26.060 --> 01:01:27.140
eben Join, Merge,

01:01:27.340 --> 01:01:28.020
dann gibt es noch

01:01:28.020 --> 01:01:31.320
solche Sachen wie,

01:01:31.760 --> 01:01:33.100
genau, das ist auch schwer

01:01:33.100 --> 01:01:35.200
zu erklären, wenn man das jetzt nur hört,

01:01:35.460 --> 01:01:36.260
fürchtig,

01:01:36.920 --> 01:01:38.640
sowas wie Pivot,

01:01:39.200 --> 01:01:40.580
Unpivot, Melt,

01:01:41.160 --> 01:01:41.860
Stack, Unstack,

01:01:42.700 --> 01:01:45.020
sehr praktische Geschichten, aber ich weiß jetzt ehrlich gesagt nicht genau,

01:01:45.020 --> 01:01:45.500
wie ich das erkläre.

01:01:46.480 --> 01:01:47.780
Ja, du kannst, also wenn du,

01:01:47.960 --> 01:01:49.980
Okay, ich versuche es mal einfach, wenn du jetzt

01:01:49.980 --> 01:01:52.180
du machst im Grunde aus einer

01:01:52.180 --> 01:01:56.160
aus Dingen, die in einer

01:01:56.160 --> 01:01:58.080
Spalte stehen, machst du mit

01:01:58.080 --> 01:02:00.280
Pivot irgendwie zusätzliche Spalten.

01:02:01.600 --> 01:02:02.320
Also ich bin

01:02:02.320 --> 01:02:04.080
gerade völlig auf den Kopf gefallen. Ich habe es natürlich mit der

01:02:04.080 --> 01:02:05.100
Transformation gerade verwechselt.

01:02:06.360 --> 01:02:06.940
Transpose, ja.

01:02:07.080 --> 01:02:10.100
Das ist relativ einfach, aber

01:02:10.100 --> 01:02:12.160
Pivot macht schon so ein bisschen kompliziertere

01:02:12.160 --> 01:02:14.280
Dinge. Das aggregiert irgendwas zur besseren Auswertung.

01:02:16.020 --> 01:02:17.420
Ein Widerfall, doch?

01:02:17.600 --> 01:02:19.340
Nee, das, das, ja, also

01:02:19.340 --> 01:02:21.040
manchmal hat man Daten halt in einem Format,

01:02:21.420 --> 01:02:22.980
in dem man schlecht plotten kann.

01:02:23.840 --> 01:02:25.480
Und manchmal braucht man halt Dinge, die

01:02:25.480 --> 01:02:27.660
in einer Zeile, die irgendwo in einer Zeile stehen,

01:02:27.820 --> 01:02:29.560
die möchte man als Spalte haben, um dann halt die Spalte

01:02:29.560 --> 01:02:31.500
besser plotten zu können. Und dafür fällt man dann auf

01:02:31.500 --> 01:02:33.400
Pivot. Und dann, genau,

01:02:33.560 --> 01:02:35.340
die umgekehrte Funktion dazu ist Melt.

01:02:36.440 --> 01:02:36.800
Und

01:02:36.800 --> 01:02:39.460
die, aber eigentlich

01:02:39.460 --> 01:02:41.480
noch allgemeineren Funktionen, die funktionieren dann eben

01:02:41.480 --> 01:02:43.860
auf so Multilevel-Indizes

01:02:43.860 --> 01:02:44.840
und halt Stack und Unstack.

01:02:45.200 --> 01:02:46.780
Aber das kann auch sehr schnell

01:02:46.780 --> 01:02:48.980
ein bisschen überfordern.

01:02:49.380 --> 01:02:50.940
Also ich kann sagen, so aus dem

01:02:50.940 --> 01:02:53.040
Biologenalltag, dass ich Pivot und Melt

01:02:53.040 --> 01:02:54.920
nie benutzt habe. Einfach

01:02:54.920 --> 01:02:56.980
weil die vielleicht auch

01:02:56.980 --> 01:02:59.040
zu viel Magie im Hintergrund noch machen können.

01:02:59.980 --> 01:03:00.860
Stack und Unstack aber

01:03:00.860 --> 01:03:02.200
sehr häufig, weil

01:03:02.200 --> 01:03:04.420
in der Realität

01:03:04.420 --> 01:03:06.840
sind, wir hatten ja eingangs über die

01:03:06.840 --> 01:03:08.900
Excel-Tabellen gesprochen, die nicht

01:03:08.900 --> 01:03:10.560
immer ganz maschinenlesbar sind.

01:03:10.880 --> 01:03:12.900
Es gibt noch den Zwischenwert, wo

01:03:12.900 --> 01:03:14.900
die zwar maschinenlesbar sind, aber

01:03:14.900 --> 01:03:20.880
mehrere Level von Indizes haben und wenn die mehrere Level von Indizes haben, man könnte

01:03:20.880 --> 01:03:33.600
sich das zum Beispiel vorstellen wie, ich hatte eben noch ein Beispiel im Kopf, sowas

01:03:33.600 --> 01:03:41.520
wie Klausurnoten nach Semestern in zwei verschiedenen Gruppen, sagen wir mal Biologen versus Chemiker

01:03:41.520 --> 01:03:47.220
oder sowas, wie die in der Chemieklausur abschneiden im ersten Semester, im zweiten Semester.

01:03:48.020 --> 01:03:53.820
Und dann hat man diese Gruppierung einmal, zu welcher Gruppe gehören die Personen an,

01:03:54.200 --> 01:03:59.280
aber dann hat man auch für jede Zeile im Prinzip eine spezifische Person.

01:04:00.320 --> 01:04:05.560
Das heißt, mehrere Personen teilen die gleiche Gruppe, also Biologe oder Chemiker,

01:04:06.740 --> 01:04:11.120
aber jede Person hat eigene Noten in Semester 1, in Semester 2.

01:04:11.520 --> 01:04:15.540
Wenn man das jetzt, jetzt muss ich kurz überlegen, in welche Richtung man das stacken würde,

01:04:16.780 --> 01:04:26.500
dann würde man im Prinzip sagen, ich schreibe jetzt jede Person einzeln als Zeile auf

01:04:26.500 --> 01:04:31.960
und habe eine neue Spalte, wo die Gruppe nochmal als sich wiederholender Wert mit drin steht,

01:04:32.720 --> 01:04:39.080
sodass ich wegkomme von, ich habe im Prinzip zwei Zeilen, die jeweils vier Unterzeilen beinhalten,

01:04:39.660 --> 01:04:46.240
Ich habe einfach acht Zeilen, wo in jeder dieser Zeilen die Gruppe nochmal explizit drinsteht.

01:04:47.620 --> 01:04:50.800
Das macht es dann einfacher, nachher Gruppierungen zu machen.

01:04:51.540 --> 01:04:55.240
Außerdem könnte man dann mit Unstack in die andere Richtung wieder sagen,

01:04:55.340 --> 01:04:59.460
ich möchte das jetzt gar nicht nach den Gruppierungen unstacken, sondern nach Semestern zum Beispiel.

01:04:59.460 --> 01:05:02.800
Und dann tauscht man plötzlich die Spaltenidentitäten.

01:05:03.280 --> 01:05:08.700
Aber ja, also Tabellentransformationen einfach nur in einem Audio-Podcast zu erklären, ist sehr schwierig.

01:05:09.660 --> 01:05:11.480
Genau. Ich weiß

01:05:11.480 --> 01:05:13.400
gar nicht, ob es zu dem Stack-on-Stack oder

01:05:13.400 --> 01:05:15.580
so Thema halt auch ein

01:05:15.580 --> 01:05:16.840
Modern Pandas Artikel

01:05:16.840 --> 01:05:19.220
gibt. Ich fürchte nein. Schade.

01:05:20.020 --> 01:05:21.280
Ah ja, muss man einfach mal nach...

01:05:21.280 --> 01:05:23.340
Also, ne, ich verlinke da einfach mal

01:05:23.340 --> 01:05:25.240
einen Artikel zu, wie das so aussieht.

01:05:25.280 --> 01:05:26.900
Wenn man das sieht, ist es eigentlich, dann kann man

01:05:26.900 --> 01:05:28.480
es deutlich besser verstehen.

01:05:29.360 --> 01:05:31.280
Ja, genau. Das sind so die Dinge, die

01:05:31.280 --> 01:05:32.460
man damit dann tut.

01:05:35.240 --> 01:05:35.600
Ja.

01:05:37.560 --> 01:05:39.440
Ja, vielleicht nochmal dieser Pivot kurz,

01:05:39.440 --> 01:05:41.360
das wart ihr gerade kurz dabei, das sind wir kurz

01:05:41.360 --> 01:05:43.360
abgeschreibt. Also was

01:05:43.360 --> 01:05:45.420
macht man damit jetzt genau? Also ich kenne das irgendwie jetzt auch aus Excel,

01:05:45.480 --> 01:05:47.180
dass man irgendeine Auswertung hat, man hat dann irgendwelche

01:05:47.180 --> 01:05:49.280
Datenblätter oder sowas und dann möchte

01:05:49.280 --> 01:05:51.580
man dann irgendwelche Aggregate

01:05:51.580 --> 01:05:53.280
irgendeinem Endnutzer

01:05:53.280 --> 01:05:55.280
auf einem Auswertungs-Dashboard

01:05:55.280 --> 01:05:57.340
zur Verfügung stellen und da wird dann

01:05:57.340 --> 01:05:58.300
irgendwas zusammen gerechnet.

01:06:02.000 --> 01:06:03.440
Ja, Excel genau kann ja auch

01:06:03.440 --> 01:06:04.300
sowas, so Pivot-Tabellen.

01:06:04.680 --> 01:06:06.300
Also ich habe hier gerade mal das

01:06:06.300 --> 01:06:08.720
Data-Science-Cheat-Cheat-Pandas

01:06:08.720 --> 01:06:10.540
offen. Können wir auch nachher verlinken.

01:06:11.660 --> 01:06:12.620
Und da steht

01:06:12.620 --> 01:06:14.280
im Wesentlichen drin, dass

01:06:14.280 --> 01:06:16.800
Pivot Table, wie gesagt, ich habe es noch nie benutzt,

01:06:16.940 --> 01:06:17.580
aber dass es

01:06:17.580 --> 01:06:20.780
eine Pivot-Tabelle macht,

01:06:21.380 --> 01:06:24.640
anhand von

01:06:24.640 --> 01:06:26.240
einer Spalte gruppiert

01:06:26.240 --> 01:06:28.740
und dann aber über andere

01:06:28.740 --> 01:06:30.360
Spalten eine Funktion aufruft.

01:06:30.580 --> 01:06:32.620
Das kann zum Beispiel sowas sein wie Mittelwert oder

01:06:32.620 --> 01:06:33.480
eine Summe oder

01:06:33.480 --> 01:06:36.660
nahezu beliebige Funktionen.

01:06:38.720 --> 01:06:46.260
Möglicherweise habe ich das auch nie benutzt, weil ich die Excel-Funktion nie benutzt habe.

01:06:47.220 --> 01:06:51.160
Was ich allerdings öfter benutzt habe, ist die Funktion Apply.

01:06:51.160 --> 01:07:00.160
Und Apply erlaubt einem jetzt innerhalb eines Data Frames auf Basis einer Achse sozusagen eine Funktion auszuführen.

01:07:00.880 --> 01:07:03.700
Das kann auch wieder nur Mittelwert oder Standardabweichung sein.

01:07:04.360 --> 01:07:07.620
Das können aber auch komplexere Funktionen sein.

01:07:08.580 --> 01:07:14.220
Und also für die, die vielleicht schon Hintergrund in R haben,

01:07:14.380 --> 01:07:20.020
da gibt es T-Apply und L-Apply für Zeilen, Spalten und was weiß ich nicht alles.

01:07:20.620 --> 01:07:24.460
In Pandas DataFrames gibt es im Wesentlichen Apply und man gibt die Achse an.

01:07:24.460 --> 01:07:28.860
Also soll das auf Reihen, auf Spalten agieren.

01:07:29.620 --> 01:07:34.560
Und dann gibt man eine Funktion an und die wird dann entsprechend für eine komplette Spalte

01:07:34.560 --> 01:07:36.020
oder eine komplette Zeile ausgeführt.

01:07:36.960 --> 01:08:05.900
Ja, das ist vielleicht eben genau, das ist auch noch ein ganz wichtiger Punkt, den wir noch gar nicht erwähnt haben, dass man, man kann, was man nicht tun sollte, ist über Data Frames iterieren und dann in der Vorschleife da irgendwelche Dinge mitmachen, das könnte man sich auch vorstellen, dass man das so tut, weil das, wenn man das, wenn man aus Python kommt, dann macht man das ja mit Listen normalerweise so, aber das geht halt nicht, oder das geht schon, ist halt nur dann sehr, sehr langsam, während halt, wenn man jetzt Apply aufruft, dann ist das halt ziemlich schnell.

01:08:06.960 --> 01:08:08.240
weil unten

01:08:08.240 --> 01:08:09.820
drunter, weil eben

01:08:09.820 --> 01:08:11.900
Vorloops in Python sowieso langsam sind

01:08:11.900 --> 01:08:13.820
und man dann eben keine Vorloop machen muss,

01:08:13.940 --> 01:08:15.700
sondern das läuft halt alles irgendwie

01:08:15.700 --> 01:08:17.580
in den entsprechenden, also kommt

01:08:17.580 --> 01:08:20.120
je nachdem, wie der Datentyp ist,

01:08:20.240 --> 01:08:21.940
aber möglicherweise halt landet das in

01:08:21.940 --> 01:08:23.920
einer dieser optimierten Vortragsbibliotheken,

01:08:24.020 --> 01:08:25.760
die unten drunter unter der Lampe liegen

01:08:25.760 --> 01:08:27.880
und es ist halt auch so, dass es dann

01:08:27.880 --> 01:08:29.940
in gewisser Weise schon parallelisiert wird

01:08:29.940 --> 01:08:31.700
oder halt diese, ich weiß jetzt gar nicht,

01:08:31.780 --> 01:08:33.220
wofür SIMD steht,

01:08:33.680 --> 01:08:35.280
diese Instruktionssets, diese

01:08:35.280 --> 01:08:37.120
Single Instruction Multiple Data.

01:08:37.360 --> 01:08:38.720
Ah, okay. Ja, genau.

01:08:39.120 --> 01:08:40.680
Super. Dankeschön.

01:08:42.120 --> 01:08:43.280
Ja, man spricht da auch von

01:08:43.280 --> 01:08:44.940
Vektorisierung. Also man

01:08:44.940 --> 01:08:47.320
kann halt

01:08:47.320 --> 01:08:49.280
mit einem Taktzyklus halt

01:08:49.280 --> 01:08:49.700
mehrere

01:08:49.700 --> 01:08:53.180
Operationen ausführen, weil

01:08:53.180 --> 01:08:54.880
man hat so super lange Register.

01:08:55.840 --> 01:08:57.440
Weiß ich nicht, vielleicht 512

01:08:57.440 --> 01:08:58.900
Byte oder so.

01:08:58.900 --> 01:09:00.180
Und da sind dann halt viele,

01:09:00.940 --> 01:09:03.000
wenn man jetzt Integer hat, 4 Byte

01:09:03.000 --> 01:09:04.880
Werte drin und die werden dann halt

01:09:04.880 --> 01:09:06.520
alle addiert gleichzeitig oder

01:09:06.520 --> 01:09:07.640
multipliziert oder sowas.

01:09:08.660 --> 01:09:10.240
Und man zerlegt halt ein komplettes

01:09:10.240 --> 01:09:12.720
Array sozusagen, auf dem man dann

01:09:12.720 --> 01:09:14.560
irgendwelche Dinge macht, halt in diese Blöcke

01:09:14.560 --> 01:09:16.680
und braucht dann halt viel weniger Takte,

01:09:16.760 --> 01:09:18.080
als wenn man da einen Vorluft drüber machen würde.

01:09:19.840 --> 01:09:20.540
Ja, und das

01:09:20.540 --> 01:09:21.900
macht Sachen super schnell.

01:09:22.980 --> 01:09:24.760
Man hat halt irgendwie so

01:09:24.760 --> 01:09:26.800
Python-Interface und ein Jupyter-Notebook,

01:09:26.880 --> 01:09:28.820
das sieht dann halt so aus, als wäre man

01:09:28.820 --> 01:09:30.620
super high-levelig, aber wenn man eine Operation macht,

01:09:30.620 --> 01:09:32.500
kann es sein, dass dann tatsächlich etwas sehr, sehr

01:09:32.500 --> 01:09:34.580
Optimiertes passiert und es sehr schnell

01:09:34.580 --> 01:09:36.460
ist und wenn jemand da hingehen würde,

01:09:36.520 --> 01:09:38.560
würde er es in C schreiben, ist er möglicherweise

01:09:38.560 --> 01:09:40.120
deutlich langsamer, wenn er

01:09:40.120 --> 01:09:41.380
nicht genau weiß, was er tut.

01:09:43.100 --> 01:09:44.540
Und das ist natürlich für viele

01:09:44.540 --> 01:09:45.520
Leute auch total überraschend.

01:09:46.100 --> 01:09:48.140
Und das ist auch eine sehr, sehr, sehr, sehr schöne Geschichte.

01:09:49.060 --> 01:09:50.160
Aber ja, man muss halt

01:09:50.160 --> 01:09:52.600
auch so ein bisschen eine komische

01:09:52.600 --> 01:09:54.580
Syntax dafür halt in Kauf nehmen.

01:09:54.700 --> 01:09:56.500
Man kann halt nicht mehr For-Loops machen, man muss halt

01:09:56.500 --> 01:09:58.420
immer Apply schreiben und dann halt

01:09:58.420 --> 01:10:00.640
eine Funktion übergeben. Oft übergibt man dann halt so anonyme Funktionen.

01:10:00.700 --> 01:10:02.400
Schreibt dann Apply und dann Lambda, X

01:10:02.400 --> 01:10:04.140
und dann kriegt man halt irgendwie einen Wert übergeben,

01:10:04.220 --> 01:10:04.840
macht dann damit irgendwas.

01:10:07.360 --> 01:10:08.100
Comprehensions oder sowas

01:10:08.100 --> 01:10:09.400
kann man auch vergessen, genau, das selbe Problem.

01:10:09.900 --> 01:10:10.820
Genau, das geht alles nicht mehr.

01:10:11.900 --> 01:10:13.420
Man schreibt halt alles nur noch

01:10:13.420 --> 01:10:15.760
ja, quasi,

01:10:15.960 --> 01:10:18.040
man schreibt eigentlich fast alles in Apply. Ich weiß gar nicht,

01:10:18.080 --> 01:10:20.000
ob es da noch andere Funktionen gibt, die so ähnlich sind wie Apply.

01:10:21.660 --> 01:10:21.940
Naja.

01:10:22.960 --> 01:10:24.160
Nee, das ist eigentlich

01:10:24.160 --> 01:10:24.980
immer Apply, ja.

01:10:24.980 --> 01:10:27.360
Ja, und

01:10:27.360 --> 01:10:29.360
dann chainet man halt die Sachen hintereinander.

01:10:29.960 --> 01:10:31.220
Man kann halt,

01:10:31.660 --> 01:10:33.180
diese Methode liefert dann halt

01:10:33.180 --> 01:10:34.720
das Ergebnis von dem Apply zurück, dann

01:10:34.720 --> 01:10:37.240
ruft man darauf wieder was anderes auf und dann

01:10:37.240 --> 01:10:39.200
hat man halt eine ganze Reihe von so hintereinander

01:10:39.200 --> 01:10:41.000
gechainten Apply-Aufrufen unter Umständen.

01:10:41.500 --> 01:10:42.020
Und ja.

01:10:44.680 --> 01:10:45.280
Das ist auch

01:10:45.280 --> 01:10:47.360
witzig. Fällt mir gerade noch

01:10:47.360 --> 01:10:48.840
zu dieser Vektorisierungsgeschichte ein.

01:10:50.540 --> 01:10:50.940
Früher

01:10:50.940 --> 01:10:52.820
haben auch Leute irgendwie

01:10:52.820 --> 01:10:54.940
erzählt, naja, ach,

01:10:55.420 --> 01:10:56.980
das mit der Parallelisierung,

01:10:57.140 --> 01:10:59.040
das ist ja alles gar kein Problem, wenn wir jetzt viele CPUs haben,

01:10:59.040 --> 01:11:00.340
so irgendwie die

01:11:00.340 --> 01:11:02.840
Steigerung der Taktfrequenzen war ja dann irgendwann auch schon

01:11:02.840 --> 01:11:04.120
vor längerer Zeit irgendwie vorbei,

01:11:04.820 --> 01:11:06.920
mehr oder weniger, und man muss halt, man kriegt halt

01:11:06.920 --> 01:11:08.860
mehr Prozessoren, also Moore's Law ist halt noch nicht

01:11:08.860 --> 01:11:10.900
wirklich weg, weil sich das eigentlich auch nur auf

01:11:10.900 --> 01:11:12.760
die Transistoren, nicht auf die Geschwindigkeit

01:11:12.760 --> 01:11:13.580
als solche irgendwie bezieht.

01:11:15.180 --> 01:11:15.500
Aber

01:11:15.500 --> 01:11:18.980
dann hieß es halt so, naja, das ist kein Problem,

01:11:19.060 --> 01:11:20.900
wenn man mehrere Prozessoren hat, da gibt es dann bestimmt Compiler,

01:11:20.960 --> 01:11:22.600
die das automatisch parallelisieren oder so.

01:11:23.460 --> 01:11:23.620
Nee.

01:11:24.640 --> 01:11:26.480
Ist nicht passiert, wird auch nie passieren.

01:11:27.140 --> 01:11:28.860
Dass Sachen automatisch parallelisieren geht

01:11:28.860 --> 01:11:30.940
halt nicht. Und das Schlimme

01:11:30.940 --> 01:11:32.440
ist, selbst sowas wie automatisch

01:11:32.440 --> 01:11:33.720
vektorisieren geht halt nicht.

01:11:34.800 --> 01:11:36.800
Weil dummerweise,

01:11:37.000 --> 01:11:38.720
wenn man jetzt in C,

01:11:39.080 --> 01:11:40.740
wenn man sich jetzt mal vorstellt, man schreibt

01:11:40.740 --> 01:11:42.940
eine Vorschleife, die jetzt zwei Vektoren addiert,

01:11:44.180 --> 01:11:45.020
also sagen wir so,

01:11:45.100 --> 01:11:45.840
die macht einfach nur

01:11:45.840 --> 01:11:48.740
C gleich A plus B. Wobei jetzt

01:11:48.740 --> 01:11:50.740
C, A und B sind halt Vektoren

01:11:50.740 --> 01:11:51.220
der gleichen Länge.

01:11:53.040 --> 01:11:54.660
C ist der, der erzeugt wird.

01:11:55.940 --> 01:11:56.820
Und man macht halt

01:11:56.820 --> 01:11:58.700
einfach vor, die das tut, dann denkt man sich

01:11:58.700 --> 01:12:00.800
jetzt, könnte doch eigentlich der Compiler

01:12:00.800 --> 01:12:02.640
hingehen und das irgendwie

01:12:02.640 --> 01:12:04.720
in diese Single Instruction Multiple

01:12:04.720 --> 01:12:06.860
Data Prozessor

01:12:06.860 --> 01:12:08.580
Befehle umwandeln und dann irgendwie

01:12:08.580 --> 01:12:10.680
das deutlich schneller machen, stellt sich

01:12:10.680 --> 01:12:12.640
raus, nein, kann er nicht, weil in C

01:12:12.640 --> 01:12:14.360
ändert das halt die Semantik

01:12:14.360 --> 01:12:16.700
von deinem Programm. Weil

01:12:16.700 --> 01:12:18.980
es könnte ja auch sein, dass dieses C irgendwie

01:12:18.980 --> 01:12:23.040
wieder was mit deinem A und deinem B zu tun hat und

01:12:23.040 --> 01:12:24.800
die Reihenfolge, in der du Sachen addierst,

01:12:25.500 --> 01:12:26.960
sich auf die nächste Addition irgendwie auswirken.

01:12:27.380 --> 01:12:28.880
Sodass halt, wenn du das in der Vorlog machst,

01:12:28.880 --> 01:12:30.740
kommt halt was anderes raus, als wenn du das parallel machst.

01:12:30.800 --> 01:12:32.620
und dann muss der

01:12:32.620 --> 01:12:34.600
Compiler natürlich sagen so, nee, kann ich nicht automatisch

01:12:34.600 --> 01:12:36.620
optimieren, weil weiß er nicht, vielleicht ist

01:12:36.620 --> 01:12:38.640
das irgendwie, ist das die Programmlogik

01:12:38.640 --> 01:12:39.720
dass das so sein muss

01:12:39.720 --> 01:12:42.260
so, das heißt, bei sowas Simples geht's schon nicht

01:12:42.260 --> 01:12:44.100
also man kann natürlich irgendwie dann so

01:12:44.100 --> 01:12:46.600
Hinweise an den Compiler

01:12:46.600 --> 01:12:48.380
dazu schreiben, also man sagt so, hier ist okay

01:12:48.380 --> 01:12:50.240
darfst du schon optimieren, mach da mal

01:12:50.240 --> 01:12:52.460
aber so generell kann

01:12:52.460 --> 01:12:54.520
ein Compiler das nicht machen und damit

01:12:54.520 --> 01:12:56.040
ist es natürlich schon irgendwie, ja

01:12:56.040 --> 01:12:58.500
und das ist einer der Gründe, warum das

01:12:58.500 --> 01:13:00.580
auch in Fortran so viel schöner funktioniert

01:13:00.580 --> 01:13:02.500
ist, da gehen solche Sachen nicht, da kannst du

01:13:02.500 --> 01:13:04.580
nicht, kann nicht das Ergebnis

01:13:04.580 --> 01:13:06.800
einer

01:13:06.800 --> 01:13:08.460
Addition, wenn du

01:13:08.460 --> 01:13:09.960
zwei solche Arrays addierst,

01:13:10.900 --> 01:13:12.720
kann nicht sich auswirken

01:13:12.720 --> 01:13:14.540
auf die nächste, sozusagen. Das C kann

01:13:14.540 --> 01:13:16.200
nicht irgendwie wieder zu A oder zu B gehören,

01:13:17.180 --> 01:13:18.520
sodass, da das ausgeschlossen

01:13:18.520 --> 01:13:20.360
ist, kannst du in Fortran solche

01:13:20.360 --> 01:13:22.500
Operationen halt automatisch vektorisieren. Das ist einer der Gründe,

01:13:22.620 --> 01:13:24.600
warum das halt irgendwann auch alles irgendwie Fortran ist.

01:13:26.100 --> 01:13:26.660
Auf der anderen

01:13:26.660 --> 01:13:28.280
Seite, das müsste nicht unbedingt, du kannst auch ein C machen,

01:13:28.280 --> 01:13:30.080
oder ein C++, wenn du das halt dem Compiler

01:13:30.080 --> 01:13:31.980
entsprechende Hinweise gibst. Aber es ist alles irgendwie

01:13:31.980 --> 01:13:33.120
nicht so ganz einfach.

01:13:37.240 --> 01:13:38.180
Wahrscheinlich will man sich da auch nicht

01:13:38.180 --> 01:13:40.240
mit rumschlagen. Aber wenn man einfach so Panas verwendet,

01:13:40.320 --> 01:13:42.120
dann passiert das ja alles automatisch und man hat nichts damit zu tun.

01:13:42.120 --> 01:13:42.720
Das ist gut.

01:13:47.780 --> 01:13:49.780
Ja, genau.

01:13:51.060 --> 01:13:52.060
Vektorisierung hatten wir dann.

01:13:52.940 --> 01:13:54.240
Genau, was wir vielleicht noch mal

01:13:54.240 --> 01:13:56.020
ein bisschen detaillierter

01:13:56.020 --> 01:13:57.900
ansprechen können, ist irgendwie das Plotting.

01:13:58.280 --> 01:14:06.220
Also es gibt für jedes DataFrame erstmal einen DotPlot und da kann man noch ein paar Parameter angeben und seinen Plot konfigurieren.

01:14:06.620 --> 01:14:09.480
Es gibt auch noch eine Reihe von anderen Funktionen.

01:14:09.480 --> 01:14:18.460
Ich habe die auch nie alle im Kopf, aber da gibt es irgendwie noch Scatter und Box und da hat man dann verschiedene Diagrammtypen auch standardmäßig schon vorimplementiert,

01:14:18.760 --> 01:14:27.640
damit man sich nicht mehr darum kümmern muss, die Plot-Funktion entsprechend durchzukonfigurieren, sondern man bekommt direkt die Plots, die man haben möchte.

01:14:28.280 --> 01:14:37.040
Und eine Sache, die ich ganz schön finde, ist, man kann als Spalten da auch wieder die Spaltennamen angeben.

01:14:37.700 --> 01:14:41.000
Man muss jetzt nicht irgendwelche Koordinaten in dem DataFrame angeben,

01:14:41.000 --> 01:14:49.600
sondern man sagt, plotte bitte Höhe, Breite, Länge gegen Zeitachse und dann passiert das genau so.

01:14:50.800 --> 01:14:57.320
Das ist einfach auch dann deutlich besser lesbarer und wartbarer Code, den man schreibt.

01:14:57.720 --> 01:15:00.680
Ja, ja.

01:15:03.940 --> 01:15:04.420
Welche

01:15:04.420 --> 01:15:06.740
präferiert ihr von diesen Plotting-Bibliotheken?

01:15:06.920 --> 01:15:08.580
Also jetzt irgendwie Matplot mit Seaborn

01:15:08.580 --> 01:15:09.940
oder dann doch Bookie oder?

01:15:12.140 --> 01:15:12.900
Ich verwende

01:15:12.900 --> 01:15:14.200
meistens Seaborn tatsächlich

01:15:14.200 --> 01:15:18.620
in Notebooks, aber

01:15:18.620 --> 01:15:20.640
es kommt halt darauf an,

01:15:20.720 --> 01:15:22.200
auf den Einsatzzweck. Also meistens

01:15:22.200 --> 01:15:24.800
müssen die für mich nicht interaktiv sein

01:15:24.800 --> 01:15:26.700
und dann verwende ich halt Seaborn, weil es einfach

01:15:26.700 --> 01:15:28.720
netter aussieht, als Matplotlib direkt zu verwenden

01:15:28.720 --> 01:15:30.240
und das ist halt auch irgendwie einfacher.

01:15:30.800 --> 01:15:32.620
Es gibt halt manche Plots, das geht auch mit

01:15:32.620 --> 01:15:33.420
Matplotlib, aber

01:15:33.420 --> 01:15:36.660
es ist halt schon so ein bisschen, also ehrlich

01:15:36.660 --> 01:15:38.360
gesagt, ich mache das meistens so,

01:15:38.840 --> 01:15:39.960
dass ich auf Seaborn,

01:15:40.400 --> 01:15:42.480
auf der Seaborn-Dokumentation halt dann so

01:15:42.480 --> 01:15:44.380
angucke, was ich so grob brauche und dann

01:15:44.380 --> 01:15:46.500
scrolle ich halt durch die Beispiele, bis ich irgendwas gefunden habe, dann

01:15:46.500 --> 01:15:48.460
kopiere ich den Aufruf und modifiziere

01:15:48.460 --> 01:15:49.820
den so lange, bis es halt irgendwie funktioniert.

01:15:52.040 --> 01:15:52.660
Wenn man

01:15:52.660 --> 01:15:54.500
jetzt mit Matplotlib hingehen würde und

01:15:54.500 --> 01:15:56.400
das so nachbauen würde, dann

01:15:56.400 --> 01:15:58.200
ist das halt

01:15:58.200 --> 01:16:00.080
deutlich schwieriger und

01:16:00.080 --> 01:16:01.500
es geht natürlich auch, Matplotlib,

01:16:01.720 --> 01:16:04.200
C1 baut darauf auf und Matplotlib ist sehr

01:16:04.200 --> 01:16:06.200
mächtig, aber die API

01:16:06.200 --> 01:16:07.480
ist nicht so ganz einfach und

01:16:07.480 --> 01:16:10.300
eigentlich musste ich da nie, da ich auch nie

01:16:10.300 --> 01:16:12.220
so wirklich komplizierte Visualisierung mache, muss ich da nie

01:16:12.220 --> 01:16:14.060
so tief einsteigen, dass ich das irgendwie

01:16:14.060 --> 01:16:16.180
wirklich gebraucht hätte, sondern für mich reicht C1 meistens

01:16:16.180 --> 01:16:18.200
aus und dann gibt es aber natürlich auch

01:16:18.200 --> 01:16:19.180
noch Fälle, wo man das halt

01:16:19.180 --> 01:16:22.200
so ein bisschen interaktiv braucht,

01:16:22.300 --> 01:16:24.060
wo man da drin zoomen können möchte

01:16:24.060 --> 01:16:25.280
oder man möchte es auf einer Webseite haben

01:16:25.280 --> 01:16:26.720
und dann

01:16:26.720 --> 01:16:30.080
ist eher sowas wie Bokeh oder Plotly

01:16:30.080 --> 01:16:31.860
das, was man da verwenden möchte.

01:16:32.160 --> 01:16:34.160
Also Plotly

01:16:34.160 --> 01:16:35.800
habe ich glaube ich auch schon mal für so

01:16:35.800 --> 01:16:37.560
Dashboards oder so kann man das ganz gut verwenden.

01:16:38.660 --> 01:16:39.360
Man kann tatsächlich

01:16:39.360 --> 01:16:41.720
relativ einfach eben, wenn man jetzt

01:16:41.720 --> 01:16:43.500
eine Datenbank hat oder so, dann zockt man daraus wieder

01:16:43.500 --> 01:16:45.480
Data Frames und

01:16:45.480 --> 01:16:47.680
die kann man dann sehr einfach mit Plotly

01:16:47.680 --> 01:16:49.880
irgendwie auf einer Webseite visualisieren

01:16:49.880 --> 01:16:51.840
und dann können sich die

01:16:51.840 --> 01:16:53.500
Leute, die das angucken, halt auch dann

01:16:53.500 --> 01:16:55.760
den Bereich, der sie interessiert, halt irgendwie

01:16:55.760 --> 01:16:57.860
auswählen und daran zoomen

01:16:57.860 --> 01:16:59.720
und so. Also ich bin auch

01:16:59.720 --> 01:17:01.000
totaler Plotly-Fan.

01:17:02.280 --> 01:17:04.120
Im Wesentlichen, was da rauskommt

01:17:04.120 --> 01:17:06.000
als Graph ist eine

01:17:06.000 --> 01:17:07.880
kleine HTML-Seite oder auch

01:17:07.880 --> 01:17:09.560
nur ein Snippet, das man einbinden kann.

01:17:10.620 --> 01:17:11.880
Und zugrunde liegt

01:17:11.880 --> 01:17:14.220
dem D3JS, das ist eine Visualisierungs

01:17:14.220 --> 01:17:15.360
Library in JavaScript.

01:17:16.300 --> 01:17:17.620
Und das

01:17:17.620 --> 01:17:19.740
hat super viele Funktionen, aber ich

01:17:19.740 --> 01:17:21.620
benutze das hauptsächlich dafür,

01:17:21.880 --> 01:17:23.980
dass man einen Mouse-Hover auf den Datensatz

01:17:23.980 --> 01:17:25.940
hat. Man fährt

01:17:25.940 --> 01:17:27.840
halt über den Graph drüber und man sieht den exakten

01:17:27.840 --> 01:17:29.880
Wert nochmal an der Maus. Das ist

01:17:29.880 --> 01:17:31.880
so die wichtigste

01:17:31.880 --> 01:17:33.860
Funktion, die ich an Plotly immer wieder nutze.

01:17:34.640 --> 01:17:35.680
Das kann man aber auch

01:17:35.680 --> 01:17:37.660
beliebig weiter eskalieren noch. Es gibt jetzt

01:17:37.660 --> 01:17:39.500
neu von Plotly Dash.

01:17:39.740 --> 01:17:41.640
Das ist ein ganzes Dashboard

01:17:41.640 --> 01:17:43.740
mit Plotly-Graphen, geschrieben

01:17:43.740 --> 01:17:44.620
in Flask.

01:17:45.720 --> 01:17:47.720
Und das kriegt man auch super schnell

01:17:47.720 --> 01:17:49.760
hochgefahren. Und es gibt sogar inzwischen

01:17:49.760 --> 01:17:51.620
ein Gitterprojekt, das eine Django

01:17:51.620 --> 01:17:53.500
Anbindung für dieses Plotly

01:17:53.500 --> 01:17:55.500
Dashboard macht. Also

01:17:55.500 --> 01:17:57.700
da kann man dann im Wesentlichen

01:17:57.700 --> 01:18:00.120
eine ganze Website mit Datenvisualisierung

01:18:00.120 --> 01:18:01.840
als Django

01:18:01.840 --> 01:18:03.540
Applikation direkt ausliefern.

01:18:03.960 --> 01:18:05.660
Was auch ziemlich nett ist,

01:18:05.660 --> 01:18:07.380
habe ich aber noch nicht im Detail ausprobiert.

01:18:07.940 --> 01:18:08.780
Gibt es sowas auch für R?

01:18:09.600 --> 01:18:11.480
Ja, ja, ja. Man muss sogar sagen,

01:18:11.800 --> 01:18:13.640
der Dash ist halt so ein Nachbau von etwas,

01:18:13.740 --> 01:18:15.720
was halt in R super populär

01:18:15.720 --> 01:18:17.280
ist. In R heißt das Shiny.

01:18:18.340 --> 01:18:19.420
Ja, genau. Und

01:18:19.420 --> 01:18:22.580
das ist eigentlich immer noch so ein bisschen

01:18:22.580 --> 01:18:24.080
der Goldstandard für diese

01:18:24.080 --> 01:18:26.600
Geschichten, weil, also ich weiß nicht

01:18:26.600 --> 01:18:28.480
wie weit, also ich habe jetzt auch schon

01:18:28.480 --> 01:18:30.480
lange nicht mehr angeguckt, aber wie weit Dash da jetzt

01:18:30.480 --> 01:18:32.500
ist, ob sie das schon

01:18:32.500 --> 01:18:34.440
da dran sind, aber

01:18:34.440 --> 01:18:36.520
man hört immer noch,

01:18:36.700 --> 01:18:38.480
dass viele Leute sagen, ah, aber Shiny

01:18:38.480 --> 01:18:40.500
ist schon irgendwie toller und ich mag das

01:18:40.500 --> 01:18:42.480
lieber als irgendwie, da gibt es noch keine so

01:18:42.480 --> 01:18:43.840
richtige Alternative in der zweiten Welt zu.

01:18:44.520 --> 01:18:46.420
Ich meine, da guckt auch

01:18:46.420 --> 01:18:47.880
jeder vom anderen ab, ehrlicherweise.

01:18:49.300 --> 01:19:13.660
R hat auch irgendwann angefangen mit diesen Notebooks und hat jetzt die Möglichkeit, ganze Berichte in Markdown zu mischen mit ausführbaren Code-Zellen. Also im Prinzip das, was man mit Jupyter Notebooks für Python hat, gibt es auch in R. Also es ist so eine Ko-Evolution der beiden Analyse-Workflows, sage ich mal.

01:19:13.660 --> 01:19:15.660
wobei man sagen muss, dass die ursprüngliche Idee

01:19:15.660 --> 01:19:17.120
für diese Notebook-Geschichte

01:19:17.120 --> 01:19:19.780
die Art, wie wir das, das kommt aus Mathematika

01:19:19.780 --> 01:19:21.700
und

01:19:21.700 --> 01:19:22.820
es gibt schon ganz lang,

01:19:23.600 --> 01:19:25.560
aber es hat sich nie so

01:19:25.560 --> 01:19:27.480
wirklich durchgesetzt, bis dann

01:19:27.480 --> 01:19:28.560
das

01:19:28.560 --> 01:19:31.280
dann jemand als

01:19:31.280 --> 01:19:33.440
eben, bis Leute das dann halt

01:19:33.440 --> 01:19:35.060
dieses Jupyter-Projekt

01:19:35.060 --> 01:19:37.600
aus einem IPython-Interpreter

01:19:37.600 --> 01:19:39.180
halt irgendwie rausgewachsen ist,

01:19:39.700 --> 01:19:40.920
bis das da implementiert wurde.

01:19:41.100 --> 01:19:43.000
Und ich habe jetzt auch letztens gehört, dass jemand

01:19:43.000 --> 01:19:43.860
Und Stephen Wolff.

01:19:43.860 --> 01:19:46.040
also den Mathematiker-Autor

01:19:46.040 --> 01:19:47.260
da irgendwie gefragt hat,

01:19:48.160 --> 01:19:49.820
warum das jetzt, warum das eigentlich

01:19:49.820 --> 01:19:51.720
nicht Open Source wäre, weil das hätte

01:19:51.720 --> 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.720 --> 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.860 --> 01:20:03.360
Stephen Wolfram hatte darauf glaube ich so,

01:20:03.520 --> 01:20:05.800
ja, also ich hätte das ja schon gerne

01:20:05.800 --> 01:20:07.700
als Open Source irgendwie veröffentlicht, aber das ging damals

01:20:07.700 --> 01:20:09.860
nicht, weil es keine Distributionsmöglichkeiten

01:20:09.860 --> 01:20:11.500
dafür gab, das wurde halt alles irgendwie auf

01:20:11.500 --> 01:20:13.940
CDs und DVDs.

01:20:14.400 --> 01:20:14.640
Tja.

01:20:16.540 --> 01:20:17.660
Ja, es ist manchmal

01:20:17.660 --> 01:20:20.060
komisch. Es reicht nicht

01:20:20.060 --> 01:20:21.940
irgendwie, dass eine Idee super ist oder so, sondern

01:20:21.940 --> 01:20:23.960
es müssen mehrere Sachen zusammenkommen, damit irgendwas

01:20:23.960 --> 01:20:25.240
wirklich dann abhebt.

01:20:25.900 --> 01:20:26.280
Und manchmal

01:20:26.280 --> 01:20:30.040
ja, kommt dann

01:20:30.040 --> 01:20:31.820
denken Leute, dass irgendwie eine Idee

01:20:31.820 --> 01:20:33.900
erst kurz gibt oder so. Das gibt es hier schon ganz lange,

01:20:34.000 --> 01:20:35.340
aber die Umstände waren halt nicht

01:20:35.340 --> 01:20:37.680
richtig, sodass sie halt

01:20:37.680 --> 01:20:39.340
vorher halt noch nicht abheben konnte.

01:20:40.040 --> 01:20:41.320
Und bei diesen

01:20:41.320 --> 01:20:43.080
Jupyter-Notebooks ist das halt schon so. Ich denke, das war

01:20:43.080 --> 01:20:45.080
genau der richtige Moment und jetzt ist es halt groß

01:20:45.080 --> 01:20:45.400
geworden.

01:20:47.560 --> 01:20:49.020
Shiny, let's be bad guys.

01:20:49.220 --> 01:20:51.060
Ich meine, gerade im Data-Science-Bereich,

01:20:51.180 --> 01:20:53.080
wo man schnell viele

01:20:53.080 --> 01:20:54.660
Dinge ausprobieren muss, ohne

01:20:54.660 --> 01:20:56.860
Skripte von Anfang neu laufen zu lassen,

01:20:57.540 --> 01:20:58.780
ist natürlich der

01:20:58.780 --> 01:21:01.000
Killer-Anwendungszweck für diese

01:21:01.000 --> 01:21:01.480
Notebooks.

01:21:05.380 --> 01:21:05.820
Ja.

01:21:07.680 --> 01:21:09.200
Ja, haben wir noch was hier für

01:21:09.200 --> 01:21:12.820
Pandas? Ja, also Pandas ist ja nie

01:21:12.820 --> 01:21:15.920
isoliert zu betrachten. Wir haben ja jetzt ganz viel

01:21:15.920 --> 01:21:18.800
schon auch über NumPy gesprochen, über Seaborn und Matplotlib

01:21:18.800 --> 01:21:22.040
und die eine Bibliothek, die ich eingangs

01:21:22.040 --> 01:21:24.380
noch mit erwähnt hatte, war Stats Models

01:21:24.380 --> 01:21:27.960
und die bringt da im Prinzip noch

01:21:27.960 --> 01:21:30.840
eine Funktionalität rein, die ich persönlich auch erstmal nur von

01:21:30.840 --> 01:21:34.360
A kannte und zwar ist das

01:21:34.360 --> 01:21:36.880
Formeln

01:21:36.880 --> 01:21:41.120
anzugeben, auf die man dann Fitting machen kann

01:21:41.120 --> 01:21:44.840
oder die man auch plotten kann. Und diese Formeln,

01:21:45.120 --> 01:21:49.040
das ist vielleicht erstmal ungewohnt, wenn man das noch nie gesehen hat, gibt man

01:21:49.040 --> 01:21:53.180
im Wesentlichen irgendwie an als, sagen wir mal, eine Geradengleichung

01:21:53.180 --> 01:21:57.100
y tilde x. Also eine Variable y,

01:21:57.480 --> 01:22:00.560
die abhängig ist von einer Variable x

01:22:00.560 --> 01:22:03.100
und als lineare Funktion zu verstehen ist.

01:22:03.900 --> 01:22:11.280
Und in diesem Statsmodels gibt es die Funktion OLS,

01:22:11.360 --> 01:22:12.740
um diese Formeln abzubilden.

01:22:13.140 --> 01:22:17.140
Die kann man dann auch mit Pandas DataFrames zusammen benutzen,

01:22:17.140 --> 01:22:18.560
um wieder Plotting zu machen.

01:22:19.340 --> 01:22:21.580
OLS meint du Optimal Linear Squares Modeling?

01:22:23.920 --> 01:22:24.840
Müsste, ja.

01:22:25.480 --> 01:22:30.200
Ordinary Linear Squares oder so was?

01:22:30.500 --> 01:22:31.260
Ich weiß es nicht mehr.

01:22:32.160 --> 01:22:37.520
Also im Wesentlichen irgendwie lineare Gleichungen anzugeben.

01:22:37.780 --> 01:22:39.720
Da gibt es auch noch ganz viele andere Möglichkeiten.

01:22:40.580 --> 01:22:45.140
Das ist nur jetzt der einfachste Fall immer, wo man eine lineare Gleichung angibt.

01:22:46.100 --> 01:22:49.340
Und diese Variablen, die man da angibt,

01:22:52.240 --> 01:22:56.160
die können in meinem Pandas DataFrame zu finden sein.

01:22:57.140 --> 01:23:00.140
Und dann kann ich das Plotting darüber machen.

01:23:00.820 --> 01:23:02.340
Da kann ich einmal die Trendlinie direkt

01:23:02.340 --> 01:23:04.300
plotten, ich kann das Fitting direkt über die Pandas

01:23:04.300 --> 01:23:06.160
Data Frames machen. Also die

01:23:06.160 --> 01:23:08.080
greifen da irgendwie, also alle diese

01:23:08.080 --> 01:23:10.040
Bibliotheken greifen sehr stark ineinander.

01:23:11.180 --> 01:23:12.340
Und da würde es

01:23:12.340 --> 01:23:14.160
auch gar nicht reichen, die 2.900

01:23:14.160 --> 01:23:16.440
Seiten des Pandas Handbuchs komplett zu lesen.

01:23:17.540 --> 01:23:18.300
Man müsste

01:23:18.300 --> 01:23:20.200
halt auch noch das NumPy Handbuch

01:23:20.200 --> 01:23:22.040
komplett lesen und dann vielleicht das

01:23:22.040 --> 01:23:24.000
Matplotlib Handbuch noch komplett lesen.

01:23:26.300 --> 01:23:28.360
Also falls ihr die 2.900 Seiten Handbuch

01:23:28.360 --> 01:23:30.320
gelesen habt, dann sagt mal Bescheid und schreibt uns eine E-Mail.

01:23:30.820 --> 01:23:33.460
Ja, genau.

01:23:35.100 --> 01:23:35.580
Statsmodels

01:23:35.580 --> 01:23:38.420
kenne ich auch so, was Zeitreihenmodellierungs

01:23:38.420 --> 01:23:40.000
Geschichten angeht, aber habe ich

01:23:40.000 --> 01:23:41.280
noch nie so wirklich viel mit

01:23:41.280 --> 01:23:43.100
gemacht.

01:23:44.160 --> 01:23:46.000
Ich bin eher so bei

01:23:46.000 --> 01:23:47.940
Scikit-Learn zu Hause und

01:23:47.940 --> 01:23:50.160
also Maschinen-Learning-Bibliothek

01:23:50.160 --> 01:23:52.280
und auch da ist es so, also meistens

01:23:52.280 --> 01:23:53.480
bevor man halt irgendwelche

01:23:53.480 --> 01:23:55.540
Daten in Modelle kippen kann,

01:23:56.820 --> 01:23:58.080
muss man die halt mit Pandas einmal

01:23:58.080 --> 01:24:00.120
aufräumen und dann war es halt so, früher musste man dann

01:24:00.120 --> 01:24:02.140
immer noch so, okay, ich habe das jetzt in einem

01:24:02.140 --> 01:24:04.080
Data-Frame, wie kriege ich die Daten jetzt

01:24:04.080 --> 01:24:06.300
wie kriege ich die Daten

01:24:06.300 --> 01:24:08.280
jetzt so,

01:24:08.400 --> 01:24:10.140
dass ich die an meine Modelle verfüttern

01:24:10.140 --> 01:24:12.520
kann und das war auch mal so ein bisschen problematisch

01:24:12.520 --> 01:24:14.000
und das ist jetzt aber auch schon

01:24:14.000 --> 01:24:16.320
die letzte oder vorletzte Version

01:24:16.320 --> 01:24:18.260
von Cycle-Learn war auch kein

01:24:18.260 --> 01:24:20.520
Problem mehr, weil man jetzt automatisch

01:24:20.520 --> 01:24:21.900
auch, weil man jetzt auch nicht

01:24:21.900 --> 01:24:23.380
früher brauchten die ganzen

01:24:23.380 --> 01:24:26.200
also in Cycle-Learn heißen die

01:24:26.200 --> 01:24:28.460
Estimators, Estimator API

01:24:28.460 --> 01:24:29.800
die haben halt

01:24:29.800 --> 01:24:31.900
NumPy-Arrays genommen und jetzt

01:24:31.900 --> 01:24:34.040
mittlerweile nehmen die halt auch Pandas DataFrames

01:24:34.040 --> 01:24:36.020
und 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.900
möchte, okay, was ist denn jetzt

01:24:39.900 --> 01:24:41.260
wo gelandet und so und

01:24:41.260 --> 01:24:43.900
dann kann man da auch mit den Spalten

01:24:43.900 --> 01:24:45.800
Namen 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:50.280 --> 01:24:51.720
Also das ist

01:24:51.720 --> 01:24:54.040
ein großes Data-Science-Ökosystem

01:24:54.040 --> 01:24:55.700
mittlerweile und das ist halt schon toll.

01:24:56.880 --> 01:24:57.860
Ah, dazu fällt mir ein, genau,

01:24:58.860 --> 01:25:01.240
Sparse Data ist natürlich

01:25:01.240 --> 01:25:02.820
auch so ein Problem. Da gibt es

01:25:02.820 --> 01:25:05.480
irgendwie einen Sparse-Type

01:25:05.480 --> 01:25:07.020
von SciPy.

01:25:07.200 --> 01:25:08.580
Das hat man früher immer verwendet.

01:25:08.940 --> 01:25:11.220
Es gibt ein paar Modelle, die halt in Scikit-Learn mit Sparsen

01:25:11.220 --> 01:25:13.660
Daten umgehen können. Also Spars

01:25:13.660 --> 01:25:13.980
heißt

01:25:13.980 --> 01:25:17.020
Daten,

01:25:17.280 --> 01:25:18.340
bei denen die meisten Werte

01:25:18.340 --> 01:25:19.600
Null sind.

01:25:21.360 --> 01:25:22.880
Also zum Beispiel, wenn ich jetzt

01:25:22.880 --> 01:25:25.480
eine Menge von Texten

01:25:25.480 --> 01:25:25.940
in

01:25:25.940 --> 01:25:28.840
Vektoren verwandle, dann

01:25:28.840 --> 01:25:31.000
ist jedes Wort eine Dimension sozusagen

01:25:31.000 --> 01:25:32.700
und das heißt, ich habe eine Tabelle mit

01:25:32.700 --> 01:25:34.880
wenn ich einen kompletten

01:25:34.880 --> 01:25:36.440
wenn ich eine Menge von Texten

01:25:36.440 --> 01:25:38.640
in eine Matrix verwandeln

01:25:38.640 --> 01:25:40.360
in so eine Feature-Matrix verwandeln möchte

01:25:40.360 --> 01:25:42.880
und dann ist jedes Dokument ist eine Zeile

01:25:42.880 --> 01:25:44.880
und die Spalten sind

01:25:44.880 --> 01:25:46.340
halt die Worte, die drin vorkommen

01:25:46.340 --> 01:25:48.680
dann sind halt, die kommen halt

01:25:48.680 --> 01:25:50.680
die meisten

01:25:50.680 --> 01:25:52.680
Worte, die es so gibt, in einem Text aber

01:25:52.680 --> 01:25:54.740
nicht vor, das heißt, die allermeisten Werte sind halt null

01:25:54.740 --> 01:25:56.640
und jetzt ist es halt blöd, das

01:25:56.640 --> 01:25:58.760
halt dicht zu speichern, diese ganzen Nullen immer mit zu speichern

01:25:58.760 --> 01:26:26.160
weil eigentlich interessieren die einen ja gar nicht und dafür gibt es dann so Sparse-Formate und dann gibt es dann ja CSA oder CSO-Formate in SciPy, aber das ist halt auch alles ein bisschen unschön und jetzt eben der letzten Release von Pandas war auch ein natives Sparse-Datenformat mit drin, das habe ich mir aber noch nicht angeguckt, aber es sieht auch interessant aus.

01:26:26.160 --> 01:26:38.300
Ich weiß auch nicht, ob man das jetzt in Cyclet Learn schon verwenden kann, aber das ist, genau, das wird halt auch noch mit abgedeckt. Und ja, das ist auch noch so ein nicht uninteressantes Detail.

01:26:39.120 --> 01:26:49.540
Gibt es noch andere Bibliotheken aus den Wetten, Zeit, Learn, Studs, Models, SciPy, die ganzen Visualisierungsgeschichten.

01:26:51.740 --> 01:27:16.840
Oh ja, doch eine Geschichte auch noch wichtig, wenn man jetzt tatsächlich größere Datenmengen hat oder halt auch Operationen, die lange dauern und man hat irgendwie so eine dicke Kiste mit irgendwie, weiß ich nicht, 64 Prozessoren, irgendwie einem halben Terabyte Hauptspeicher oder so was und man ist so ein bisschen angeödet davon, dass das irgendwie immer nur auf einem Prozessor läuft, dann kann man da was tun.

01:27:17.280 --> 01:27:19.640
Da gibt es ein auch sehr schönes Projekt, das nennt sich DAST.

01:27:22.000 --> 01:27:25.020
Und damit kann man das halt so ein bisschen auf mehrere Prozessoren skalieren.

01:27:25.160 --> 01:27:30.140
Also was das letztendlich tut, ist ein Data-Frame halt in viele Kleider zu hacken

01:27:30.140 --> 01:27:35.960
und dann halt die Operationen halt auf Prozessoren zu verteilen

01:27:35.960 --> 01:27:37.760
und dann halt das hinterher wieder zusammenzuführen.

01:27:38.400 --> 01:27:43.920
Aber es kann halt, also ich glaube, mehr oder weniger beliebige Compute-Graphs

01:27:43.920 --> 01:27:44.960
kann man da irgendwie angeben.

01:27:46.020 --> 01:27:49.500
einfache Dinge sind halt einfach

01:27:49.500 --> 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 da auch so ein bisschen nachdenken

01:27:53.540 --> 01:27:54.540
und dann halt eventuell

01:27:54.540 --> 01:27:57.380
sich überlegen, wie man das halt ausgeführt kriegt, aber

01:27:57.380 --> 01:27:59.200
im Grunde

01:27:59.200 --> 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.880
sagt man irgendwie jetzt Collect oder so

01:28:04.880 --> 01:28:05.900
und dann

01:28:05.900 --> 01:28:08.880
ich glaube, ich weiß gar nicht, also

01:28:08.880 --> 01:28:11.400
man ruft halt irgendwie eine Funktion auf, die sagt

01:28:11.400 --> 01:28:13.380
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.260
das alles wieder in einem DataFrame und

01:28:19.260 --> 01:28:21.620
die Geschwindigkeit

01:28:21.620 --> 01:28:23.200
hat sich dann, wenn man Glück gehabt hat,

01:28:23.480 --> 01:28:24.200
irgendwie linear

01:28:24.200 --> 01:28:27.920
skaliert

01:28:27.920 --> 01:28:29.620
und man braucht nur noch ein Sechzigstel der Zeit

01:28:29.620 --> 01:28:30.400
oder so.

01:28:33.120 --> 01:28:33.480
Genau.

01:28:36.120 --> 01:28:37.540
Das ist auf jeden Fall auch ein Ding, was man sich

01:28:37.540 --> 01:28:39.240
auch angucken sollte, also was

01:28:39.240 --> 01:28:41.400
Skalierungsgeschichten angeht. Ja, wenn die Datenmengen

01:28:41.400 --> 01:28:43.540
dann noch viel größer sind oder dass sie halt nicht mehr

01:28:43.540 --> 01:28:45.240
Hauptsprecher auf einer Maschine passen oder so,

01:28:46.480 --> 01:28:47.680
dann muss man sich nochmal

01:28:47.680 --> 01:28:49.160
was anderes überlegen. Dann

01:28:49.160 --> 01:28:51.860
bleibt eigentlich nur, dass man

01:28:51.860 --> 01:28:53.700
irgendwie dann Richtung Spark

01:28:53.700 --> 01:28:55.320
geht oder sowas. Aber

01:28:55.320 --> 01:28:57.500
diesen Fall hat man fast nie, weil

01:28:57.500 --> 01:28:59.700
mittlerweile die Maschinen

01:28:59.700 --> 01:29:01.780
so viele Hauptsprecher haben, dass das irgendwie kaum vorkommt.

01:29:03.300 --> 01:29:03.760
Wenn es nicht mehr

01:29:03.760 --> 01:29:05.640
in den Hauptsprecher passt, Geld dagegen werfen

01:29:05.640 --> 01:29:06.840
und mehr Hauptsprecher besorgen.

01:29:09.400 --> 01:29:11.320
Ja, wenn wir schon beim halben Terabyte angekommen sind,

01:29:11.420 --> 01:29:12.820
da ist ja schon noch ein bisschen Platz.

01:29:13.540 --> 01:29:15.740
Ja, geht eine ganze Menge rein.

01:29:17.240 --> 01:29:17.660
Ja, so

01:29:17.660 --> 01:29:19.160
Skalierung hatten wir jetzt auch so ein bisschen.

01:29:19.640 --> 01:29:20.740
Wir hatten noch, glaube ich, dieses

01:29:20.740 --> 01:29:23.660
Wes McKinney, hast du kurz erwähnt, da hatten wir, glaube ich,

01:29:23.680 --> 01:29:25.640
einmal in unserer Weihnachtsfolge dieses 10 Things I Hate About

01:29:25.640 --> 01:29:27.940
Pandas irgendwie. Ah, ja, ja, ja, genau.

01:29:28.640 --> 01:29:29.600
Ich weiß nicht, ob da noch was

01:29:29.600 --> 01:29:30.300
rauskam.

01:29:31.300 --> 01:29:31.620
Ja, der,

01:29:32.400 --> 01:29:35.660
also er arbeitet halt hauptsächlich

01:29:35.660 --> 01:29:37.380
an dem Arrow-Projekt, da geht es darum,

01:29:37.380 --> 01:29:38.740
eine neue Grundlage zu schaffen

01:29:38.740 --> 01:29:41.140
und zwar nicht nur für Python,

01:29:41.340 --> 01:29:42.780
sondern für

01:29:42.780 --> 01:29:45.160
alle anderen Programmiersprachen

01:29:45.160 --> 01:29:46.880
auch, weil man hat halt das Problem, dass man

01:29:46.880 --> 01:29:49.020
man möchte eigentlich nicht,

01:29:49.220 --> 01:29:50.980
wenn man Daten hat, die groß sind und

01:29:50.980 --> 01:29:53.140
man möchte die nicht mehrfach

01:29:53.140 --> 01:29:55.060
im Hauptspeicher halten, aber momentan kommt man nicht drum rum, wenn man

01:29:55.060 --> 01:29:55.320
jetzt

01:29:55.320 --> 01:29:58.960
beispielsweise in R und

01:29:58.960 --> 01:30:01.000
in Python irgendwie auf Daten

01:30:01.000 --> 01:30:02.860
irgendwas machen möchte, dann muss man die halt

01:30:02.860 --> 01:30:04.960
irgendwie erst, wenn man die jetzt in Python hat,

01:30:05.020 --> 01:30:06.960
serialisieren, irgendwo hin auf die Platte schreiben, dann in R

01:30:06.960 --> 01:30:09.020
wieder einlesen und hat sie dann

01:30:09.020 --> 01:30:10.920
im Endeffekt zweimal im Hauptspeicher, was natürlich irgendwie

01:30:10.920 --> 01:30:13.120
doof ist und das Projekt

01:30:13.120 --> 01:30:13.600
ist sozusagen

01:30:13.600 --> 01:30:16.960
stellt halt

01:30:16.960 --> 01:30:18.960
sozusagen Schnittstellen für alle Programmiersprachen bereit, aber

01:30:18.960 --> 01:30:20.840
die Daten selber werden

01:30:20.840 --> 01:30:22.880
nur im Hauptspeicher an einer

01:30:22.880 --> 01:30:24.740
Stelle gehalten und dann kann man mit allen Sprachen, also

01:30:24.740 --> 01:30:26.480
von Java bis C,

01:30:26.740 --> 01:30:28.460
C++, Rust,

01:30:28.920 --> 01:30:30.680
was auch immer, irgendwelche Leute schreiben gerade eine Query Engine

01:30:30.680 --> 01:30:31.980
für Arrow in Rust,

01:30:32.780 --> 01:30:34.860
Python A, darauf zugreifen

01:30:34.860 --> 01:30:36.560
und da irgendwelche

01:30:36.560 --> 01:30:38.140
Manipulationen drauf machen,

01:30:38.840 --> 01:30:40.440
ohne dass es halt dann

01:30:40.440 --> 01:30:42.820
jedes Mal eine Kopie macht. Und das ist natürlich auch

01:30:42.820 --> 01:30:44.300
eine sehr, sehr interessante Geschichte,

01:30:44.940 --> 01:30:46.400
weil das ist eben,

01:30:46.500 --> 01:30:48.280
davon hatten wir es ja auch schon ein paar Mal

01:30:48.280 --> 01:30:50.660
momentan, wenn man mit so Big Data

01:30:50.660 --> 01:30:52.220
Geschichten, Hadoop-Clustern zu tun hat,

01:30:52.900 --> 01:30:54.800
so ein Problem, dass man da nicht so gut an die Daten

01:30:54.800 --> 01:30:55.340
rankommt.

01:30:57.820 --> 01:30:58.140
Und

01:30:58.140 --> 01:31:00.640
ja, das war auch eines der ersten Geschichten,

01:31:00.720 --> 01:31:01.680
die Arrow gemacht hat, war

01:31:01.680 --> 01:31:05.160
Parquet-File-Parser

01:31:05.160 --> 01:31:07.160
zu implementieren,

01:31:07.500 --> 01:31:09.040
sodass man halt zumindest die Files,

01:31:09.480 --> 01:31:11.260
in denen die Daten liegen, halt irgendwie lesen kann.

01:31:13.340 --> 01:31:13.920
Ja, und

01:31:13.920 --> 01:31:19.260
das ist, glaube ich,

01:31:19.360 --> 01:31:21.140
also mittlerweile funktioniert das

01:31:21.140 --> 01:31:23.160
irgendwie fast allen Sprachen, dass man das

01:31:23.160 --> 01:31:24.560
halt sozusagen als

01:31:24.560 --> 01:31:27.340
Ersatz

01:31:27.340 --> 01:31:28.700
für NumPy auch nehmen kann.

01:31:31.380 --> 01:31:33.160
Also eine Geschichte ist so, dass

01:31:33.160 --> 01:31:35.080
man in Pandas

01:31:35.080 --> 01:31:36.860
das nicht so wirklich schmerzfrei in NumPy

01:31:36.860 --> 01:31:38.100
aushauschen kann, weil das halt

01:31:38.100 --> 01:31:40.400
viele Sachen in Pandas

01:31:40.400 --> 01:31:42.000
beruhen halt darauf, dass ein Handball so ist, wie es ist.

01:31:42.100 --> 01:31:43.920
Das wird halt schwierig. Da gibt es auch

01:31:43.920 --> 01:31:46.100
eine Serie von Artikeln dazu,

01:31:46.160 --> 01:31:47.640
nennt sich Pandas 2.0 irgendwie,

01:31:48.480 --> 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:53.940 --> 01:31:54.460
Dazu hat

01:31:54.460 --> 01:31:56.560
Wes McKinney 2015 ein paar Artikel geschrieben.

01:31:57.500 --> 01:31:58.440
Bisher ist da nicht so viel passiert,

01:31:58.520 --> 01:32:00.280
aber man müsste, wenn man jetzt komplett auf Arrow umsteigen

01:32:00.280 --> 01:32:01.760
wollte und so, dann müsste man da wahrscheinlich

01:32:01.760 --> 01:32:04.160
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 schwierig.

01:32:08.100 --> 01:32:10.480
und

01:32:10.480 --> 01:32:11.520
ist es so, dass

01:32:11.520 --> 01:32:14.120
was auch noch in nächster Zeit bei Arrow

01:32:14.120 --> 01:32:15.920
ansteht, ist, es gibt

01:32:15.920 --> 01:32:17.740
so ein großes

01:32:17.740 --> 01:32:19.880
Kluft zwischen dem, was halt im

01:32:19.880 --> 01:32:21.380
Datenbankenbereich passiert ist

01:32:21.380 --> 01:32:23.980
und dem, was halt im

01:32:23.980 --> 01:32:25.860
Data-Science-Bereich passiert ist und da

01:32:25.860 --> 01:32:27.840
geht es auch darum, das so ein bisschen

01:32:27.840 --> 01:32:29.640
anzugleichen. Also was man zum Beispiel nicht hat, ist eine

01:32:29.640 --> 01:32:30.940
Query-Engine für Arrow, also

01:32:30.940 --> 01:32:32.860
da wird halt gerade geschrieben, also

01:32:32.860 --> 01:32:35.920
ich glaube, das ist das Projekt für die nächsten 2-3 Jahre

01:32:35.920 --> 01:32:37.420
in Arrow, ist halt so

01:32:37.420 --> 01:32:39.940
wäre doch schick, da auch so eine SQL-Engine

01:32:39.940 --> 01:32:41.700
drauf zu haben, sodass man halt

01:32:41.700 --> 01:32:42.320
Error auch als

01:32:42.320 --> 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.360
verwenden könnte.

01:32:49.580 --> 01:32:52.300
Weil das ist im Grunde auch eine SQL-Engine

01:32:52.300 --> 01:32:53.480
in C geschrieben,

01:32:54.140 --> 01:32:54.420
die halt

01:32:54.420 --> 01:32:57.840
auf so einem

01:32:57.840 --> 01:32:58.780
Hadoop-Cluster laufen kann.

01:33:00.660 --> 01:33:01.260
Und dann

01:33:01.260 --> 01:33:03.600
kann das aber viele der Sachen, die man halt

01:33:03.600 --> 01:33:05.380
in Datenbanken hat, auch noch nicht. Also ganzen

01:33:05.380 --> 01:33:07.860
Index-Geschichten und so.

01:33:09.200 --> 01:33:09.460
Und

01:33:09.460 --> 01:33:10.440
ja,

01:33:12.180 --> 01:33:13.860
da läuft

01:33:13.860 --> 01:33:15.460
das aber irgendwie so hin. Also ich meine, wenn man

01:33:15.460 --> 01:33:17.620
sich jetzt so eine ideale Zukunft mal ausmalen

01:33:17.620 --> 01:33:19.160
würde, könnte,

01:33:19.700 --> 01:33:21.360
würde ich sagen, wäre das eigentlich sowas, man hat

01:33:21.360 --> 01:33:23.680
eben so

01:33:23.680 --> 01:33:25.580
einen In-Memory-Storage

01:33:25.580 --> 01:33:27.920
Arrow oder so.

01:33:28.440 --> 01:33:29.860
Man hat irgendwie

01:33:29.860 --> 01:33:31.940
als Frontend etwas Pandas-ähnliches.

01:33:32.840 --> 01:33:33.800
Es gab da auch

01:33:33.800 --> 01:33:35.480
schon einen Ansatz von

01:33:35.480 --> 01:33:37.900
eben auch wieder von Wes McKinney, das ist eine zentrale

01:33:37.900 --> 01:33:39.660
Figur, das nennt sich Ibis,

01:33:39.740 --> 01:33:41.540
das Projekt, wo es darum geht,

01:33:42.360 --> 01:33:44.000
ein Superset

01:33:44.000 --> 01:33:45.740
von SQL zu haben,

01:33:46.200 --> 01:33:47.580
das möglichst pandasähnlich ist,

01:33:49.020 --> 01:33:49.820
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:52.780 --> 01:33:52.880
Und

01:33:52.880 --> 01:33:55.780
ja, das halt auch so eine

01:33:55.780 --> 01:33:57.500
Default-Execution-Geschichte macht,

01:33:57.700 --> 01:33:59.500
dass man halt hinterher nur sagt, irgendwie man

01:33:59.500 --> 01:34:01.700
definiert die ganzen Transformationen, Abfragen,

01:34:01.700 --> 01:34:03.480
wie man da macht und am Schluss sagt man, so und jetzt

01:34:03.480 --> 01:34:05.420
ausführen und dann geht das quasi

01:34:05.420 --> 01:34:07.380
an so einen Cluster raus. Und das

01:34:07.380 --> 01:34:09.280
ist mit SQL auch alles,

01:34:09.380 --> 01:34:10.900
SQL ist sowieso blöd, weil

01:34:10.900 --> 01:34:13.560
ja, diverse Geschichten

01:34:13.560 --> 01:34:15.360
gehen halt mit SQL nicht so richtig gut, also man kann

01:34:15.360 --> 01:34:17.180
auch Tests für SQL schreiben, aber das ist alles ziemlich hässlich

01:34:17.180 --> 01:34:19.400
und man kann auch nicht so wirklich

01:34:19.400 --> 01:34:21.180
Code sharen, also wenn jetzt, es gibt nicht sowas wie

01:34:21.180 --> 01:34:22.620
Funktionen, aber wenn man jetzt

01:34:22.620 --> 01:34:25.560
ähnliche Abfragen macht in unterschiedlichen

01:34:25.560 --> 01:34:27.300
Kontexten, dann kopiert man oft

01:34:27.300 --> 01:34:29.000
die Statements und so, das ist alles

01:34:29.000 --> 01:34:31.200
nicht so schön und das ist halt

01:34:31.200 --> 01:34:32.600
mit so einer Notation wie

01:34:32.600 --> 01:34:33.100
in

01:34:33.100 --> 01:34:36.860
Ibis

01:34:36.860 --> 01:34:38.740
halt deutlich besser, weil da kann man das einfach in Funktionen

01:34:38.740 --> 01:34:40.620
packen und die Funktionen woanders halt verwenden

01:34:40.620 --> 01:34:41.840
und so und das geht halt viel schöner.

01:34:43.360 --> 01:34:44.740
Ja, und das dann halt auch nochmal ändern.

01:34:44.940 --> 01:34:46.720
Bei einem SQL-Statement könntest du das ja auch in eine Funktion packen,

01:34:46.760 --> 01:34:48.520
aber das Problem ist, dann hast du halt genau dieses Statement. Du kannst

01:34:48.520 --> 01:34:50.680
das Statement kaum ändern, außer du nimmst halt

01:34:50.680 --> 01:34:52.520
ein ORM, aber ORM ist dann auch wieder eigene

01:34:52.520 --> 01:34:54.360
Probleme und ja,

01:34:54.840 --> 01:34:56.440
also ich würde mir eine ideale Welt

01:34:56.440 --> 01:34:57.760
würde ich mir so vorstellen,

01:34:58.640 --> 01:35:00.680
also für kleine Datenmengen funktioniert man das ja schon super,

01:35:01.360 --> 01:35:03.240
bis auf diese kleinen Hässlichkeiten

01:35:03.240 --> 01:35:04.900
wie eben None und

01:35:04.900 --> 01:35:07.240
diese Block-Storage-Geschichten, aber das

01:35:07.240 --> 01:35:08.760
kriegt man ja alles in den Griff mit der

01:35:08.760 --> 01:35:09.600
Array-Extension-API.

01:35:10.700 --> 01:35:12.920
Aber für große Datenmengen, dass man dann halt so

01:35:12.920 --> 01:35:14.500
was ähnliches hat wie

01:35:14.500 --> 01:35:16.740
Spark oder

01:35:16.740 --> 01:35:18.660
auch der Doob, man hat einen großen Cluster,

01:35:19.120 --> 01:35:21.000
wo dann in Memory halt die ganzen

01:35:21.000 --> 01:35:23.100
Daten in Apache Arrow quasi

01:35:23.100 --> 01:35:24.820
liegen und man dann

01:35:24.820 --> 01:35:27.300
auf Arrow aufsetzend irgendwelche Query-Execution

01:35:27.300 --> 01:35:29.160
Engines hat, die man

01:35:29.160 --> 01:35:30.840
füttert von einem

01:35:30.840 --> 01:35:32.180
Pandas-ähnlichen Frontend aus,

01:35:33.700 --> 01:35:34.840
wo man dann halt definiert, was man

01:35:34.840 --> 01:35:37.000
gerne hätte und das dann halt irgendwie

01:35:37.000 --> 01:35:38.340
auf den Cluster verteilt wird.

01:35:38.900 --> 01:35:40.740
Also man hat irgendwie so eine Art Array-Datenbank

01:35:40.740 --> 01:35:42.920
verteilte, In-Memory-Array-Datenbank

01:35:42.920 --> 01:35:44.660
mit so einer

01:35:44.660 --> 01:35:46.620
vielleicht

01:35:46.620 --> 01:35:48.660
Intermediate-SQL-ähnlichen Query-Engine hat,

01:35:48.660 --> 01:35:50.660
aber so als Frontend

01:35:50.660 --> 01:35:52.340
sowas wie Pandas, sodass man dann halt auch

01:35:52.340 --> 01:35:54.200
wirklich großen Datenmengen einfach so

01:35:54.200 --> 01:35:57.100
Transformationen

01:35:57.100 --> 01:35:58.220
machen kann wie in Pandas.

01:35:59.160 --> 01:36:00.620
Das wird vielleicht noch ein paar Jahre dauern, aber das wäre

01:36:00.620 --> 01:36:02.560
Also das, was ich mir wünschen würde, was passiert.

01:36:02.760 --> 01:36:04.740
Und dass man vielleicht irgendwann dann tatsächlich Panas 2.0 hat,

01:36:05.060 --> 01:36:11.880
wo man nochmal komplett neu irgendwie diese ganzen Geschichten,

01:36:12.080 --> 01:36:16.580
die in der Kombination mit NumPy halt nicht so toll sind, gelöst werden.

01:36:16.700 --> 01:36:18.120
Aber das kann auch sein, dass das nie passiert,

01:36:18.940 --> 01:36:20.880
weil so viele Leute jetzt Panas verwenden.

01:36:24.880 --> 01:36:28.120
Ich sagte gerade noch, wenn der Jochen heute anfängt,

01:36:28.600 --> 01:36:31.260
dann hören wir jetzt monatelang keinen Python-Podcast mehr,

01:36:31.380 --> 01:36:32.860
aber es hört sich gut an, mach das.

01:36:33.240 --> 01:36:38.220
Nee, ja, das Projekt ist ja schon, da gibt es ja Leute, ja.

01:36:39.260 --> 01:36:41.680
Also ich kann es auch kaum erwarten,

01:36:41.780 --> 01:36:44.000
aber es wird wahrscheinlich noch ein paar Jährchen dauern.

01:36:44.440 --> 01:36:46.140
So schnell ist das nicht umzusetzen.

01:36:46.660 --> 01:36:46.980
Ja, ja.

01:36:48.360 --> 01:36:49.900
Ja, ich weiß nicht, von meiner Seite,

01:36:49.900 --> 01:36:53.120
ich wüsste jetzt spontan nichts mehr.

01:36:53.900 --> 01:36:56.260
Wenn ihr mich jetzt fragen würdet, fragt doch mal,

01:36:56.360 --> 01:36:57.920
was sind so die drei wichtigsten Sachen,

01:36:58.040 --> 01:37:00.100
die ich mit nach Hause nehmen muss, wenn ich mal mit Pandas

01:37:00.100 --> 01:37:01.920
anfangen möchte. Was sind die wichtigsten

01:37:01.920 --> 01:37:03.940
drei Sachen, die du mit nach Hause nehmen musst, lieber Simon, wenn du

01:37:03.940 --> 01:37:05.880
mal mit Pandas anfangen möchtest? Ich würde

01:37:05.880 --> 01:37:07.780
sagen, Describe, Plot und

01:37:07.780 --> 01:37:09.740
Apply sind so die drei ganz

01:37:09.740 --> 01:37:11.460
zentralen Dinge, die man sich

01:37:11.460 --> 01:37:13.380
angucken möchte, weil da kann man

01:37:13.380 --> 01:37:14.860
fast alles schon mitmachen.

01:37:17.700 --> 01:37:18.420
Ja, okay.

01:37:19.880 --> 01:37:21.880
Ja, ich würde sagen, Read CSV sollte man sich auch

01:37:21.880 --> 01:37:23.940
mal angucken. Ja, okay, also

01:37:23.940 --> 01:37:26.080
Datenimport, ja.

01:37:28.040 --> 01:37:29.880
Aber sonst, ja, nee, klar, doch.

01:37:32.380 --> 01:37:33.440
Ja, schön, schön.

01:37:34.440 --> 01:37:34.620
Ja.

01:37:35.740 --> 01:37:37.600
Schöne Strukturierung mit unseren Daten über Pandas.

01:37:37.660 --> 01:37:39.720
Ich finde es hervorragend. Ja, dann würde ich sagen,

01:37:39.760 --> 01:37:41.420
sind wir mit dem Pandas-Thema tatsächlich für heute

01:37:41.420 --> 01:37:43.700
soweit durch. Und vielleicht machen wir noch

01:37:43.700 --> 01:37:45.520
so ein bisschen Abschluss und erzählen noch ein bisschen

01:37:45.520 --> 01:37:47.440
was von euren Lieblingspicks oder sowas

01:37:47.440 --> 01:37:49.620
für, ja.

01:37:51.380 --> 01:37:51.740
Erstmal.

01:37:51.800 --> 01:37:53.520
Sieben, möchtest du anfangen? Irgendwie hast du einen Lieblingspick?

01:37:53.520 --> 01:37:55.520
Irgendein Modul, was du...

01:37:56.380 --> 01:37:57.740
Muss ich kurz einen Moment

01:37:57.740 --> 01:37:59.500
drüber nachdenken. Bitte, dann ist der Jochen zuerst.

01:38:03.140 --> 01:38:03.760
Ja, ich

01:38:03.760 --> 01:38:05.380
überlege gerade, ob ich irgendwas Pandas-mäßiges

01:38:05.380 --> 01:38:06.620
habe, aber

01:38:06.620 --> 01:38:09.220
ich fürchte,

01:38:09.440 --> 01:38:10.140
nee, ich

01:38:10.140 --> 01:38:12.900
was man sich mal

01:38:12.900 --> 01:38:14.900
angucken kann, ist

01:38:14.900 --> 01:38:16.680
eine Bibliothek namens Al-Khali.

01:38:17.940 --> 01:38:19.600
Das ist so ein

01:38:19.600 --> 01:38:20.880
Django-ORM-Style-Ding,

01:38:22.040 --> 01:38:22.860
aber für

01:38:22.860 --> 01:38:25.680
flache

01:38:25.680 --> 01:38:27.080
Files und

01:38:27.080 --> 01:38:29.160
das ist halt auch ganz nett, wenn man jetzt

01:38:29.160 --> 01:38:29.880
irgendwie zum Beispiel

01:38:29.880 --> 01:38:32.720
Django kann zum Beispiel und

01:38:32.720 --> 01:38:35.380
die OEM da schon

01:38:35.380 --> 01:38:37.280
so ein bisschen damit schon so Sachen

01:38:37.280 --> 01:38:39.280
gemacht hat, dann kann man halt auch da

01:38:39.280 --> 01:38:41.300
auf CSVs oder so

01:38:41.300 --> 01:38:43.300
halt Dinge machen, die so ähnlich sind. Also das ist

01:38:43.300 --> 01:38:45.280
quasi so die umgekehrte Richtung. Also wahrscheinlich wäre es

01:38:45.280 --> 01:38:47.060
praktischer, wenn man Pandas kennt, das halt mit Pandas zu machen,

01:38:47.520 --> 01:38:49.240
aber wenn man das nicht kann, dann kann

01:38:49.240 --> 01:38:49.940
man halt auch

01:38:49.940 --> 01:38:53.060
irgendwie, wenn man Daten als

01:38:53.060 --> 01:38:54.620
CSV ausgeschrieben hat oder so, damit

01:38:54.620 --> 01:38:56.700
irgendwie wie auf einer Datenbank arbeiten.

01:38:56.840 --> 01:38:57.940
Das fand ich ganz witzig, die Idee.

01:38:58.820 --> 01:38:59.900
Deswegen würde ich das mal

01:38:59.900 --> 01:39:02.540
picken, aber ja.

01:39:04.100 --> 01:39:04.860
Ich würde tatsächlich

01:39:04.860 --> 01:39:06.380
Pickel nehmen. Ich weiß nicht, hatten wir das schon mal oder so?

01:39:06.440 --> 01:39:08.980
Ich fand das total super, dass man da so Preisenobjekte speichern kann.

01:39:09.120 --> 01:39:10.240
Stimmt, nee, das hatten wir noch nicht.

01:39:10.480 --> 01:39:12.060
Ist auch Teil der Standardbibliothek und

01:39:12.060 --> 01:39:14.400
genau, daher muss man nichts zusätzlich installieren.

01:39:14.480 --> 01:39:14.860
Das ist super.

01:39:16.140 --> 01:39:18.340
Kann man eigentlich auch mit DataFrames machen, oder? Ich weiß jetzt nicht, wie schnell

01:39:18.340 --> 01:39:20.600
sowas geht und ob man das nicht lieber in der Datenbank dann speichert.

01:39:21.360 --> 01:39:22.420
Doch, kann man mit DataFrames

01:39:22.420 --> 01:39:24.360
auch machen. Ist auch tatsächlich ziemlich

01:39:24.360 --> 01:39:26.180
schnell. Ist auch, habe ich oft

01:39:26.180 --> 01:39:28.420
gemacht. Wenn man keine Lust mehr hat

01:39:28.420 --> 01:39:30.280
und wieder anfangen muss, immer an der gleichen Stelle zu debuggen,

01:39:30.320 --> 01:39:32.140
dann lädt man einfach dann irgendwann den Pickel ein oder so.

01:39:32.680 --> 01:39:34.180
Spart sich immer die Zeit vor dem Ausführen.

01:39:35.380 --> 01:39:35.740
Ja.

01:39:36.600 --> 01:39:38.260
Also genau, das

01:39:38.260 --> 01:39:40.180
ist, nee, das ist tatsächlich,

01:39:40.180 --> 01:39:41.640
wenn man, also ich finde,

01:39:42.420 --> 01:39:44.240
Data Frames zu pickeln,

01:39:44.740 --> 01:39:46.120
es funktioniert

01:39:46.120 --> 01:39:48.200
ganz gut. Also man muss vielleicht dazu sagen,

01:39:48.280 --> 01:39:49.820
man muss dem Ganzen vertrauen.

01:39:50.000 --> 01:39:50.240
Also wenn man,

01:39:50.760 --> 01:39:56.740
Wenn einem jemand so ein Pickel-File gibt,

01:39:56.800 --> 01:39:56.960
dann sagst du,

01:39:57.040 --> 01:39:59.680
wie war das bei der Sesamstraße?

01:39:59.920 --> 01:40:01.020
Macht so ein French-Code auf?

01:40:04.020 --> 01:40:05.640
Willst du ein Pickel-File von mir

01:40:05.640 --> 01:40:06.760
deserialisieren?

01:40:07.320 --> 01:40:09.020
Genau. Dann lieber nicht machen, weil

01:40:09.020 --> 01:40:11.620
das führt halt beliebigen Code aus.

01:40:12.800 --> 01:40:13.860
Das ist vielleicht nicht so schön.

01:40:14.140 --> 01:40:15.180
Aber wenn man das selber generiert hat,

01:40:15.180 --> 01:40:16.020
dann ist das vielleicht okay.

01:40:16.860 --> 01:40:18.240
Dann ist es auch sehr schnell.

01:40:20.760 --> 01:40:23.160
da kann man durchaus, also wenn die

01:40:23.160 --> 01:40:25.080
I.O. ist, ich habe das nicht an die

01:40:25.080 --> 01:40:27.040
Grenzen, oder war da, ne, ich glaube, ich habe das

01:40:27.040 --> 01:40:29.220
tatsächlich nicht an die Grenzen

01:40:29.220 --> 01:40:31.080
bringen können, sondern das war immer so

01:40:31.080 --> 01:40:32.920
schnell, wie halt das Plattensystem drunter war.

01:40:33.140 --> 01:40:34.100
Also ich habe damit auch schon,

01:40:35.420 --> 01:40:36.840
da ging halt so Gigabyte pro Sekunde

01:40:36.840 --> 01:40:38.760
durch. Bei CSV ist

01:40:38.760 --> 01:40:40.660
CSV ist richtig langsam. CSV ist halt so

01:40:40.660 --> 01:40:42.940
wenn es schnell ist, ein paar Zehn

01:40:42.940 --> 01:40:44.060
Megabyte pro Sekunde.

01:40:44.940 --> 01:40:47.100
Was halt, wenn du ein paar Gigabyte große Files hast,

01:40:47.140 --> 01:40:47.620
dann dauert das.

01:40:49.300 --> 01:40:50.580
Und Pickle ist halt so,

01:40:50.680 --> 01:40:52.320
selbst wenn die Files Gigabytes groß sind,

01:40:52.400 --> 01:40:54.500
kannst du dann das halt, wenn das IOSystem, das du hast, schnell ist,

01:40:55.540 --> 01:40:56.600
dann dauert das halt, zwei Sekunden

01:40:56.600 --> 01:40:57.840
ist das da. Und

01:40:57.840 --> 01:40:59.980
das ist natürlich schon schön. Es gibt

01:40:59.980 --> 01:41:02.220
andere Formate für, gerade um Daten,

01:41:02.320 --> 01:41:03.100
wie im DataFrame,

01:41:03.780 --> 01:41:06.380
man sehr oft hat, irgendwie zu

01:41:06.380 --> 01:41:08.000
speichern, HDF5 zum Beispiel, oder Feather,

01:41:08.100 --> 01:41:09.840
gibt es da auch eine Library, wo es auch veraltet eigentlich.

01:41:10.520 --> 01:41:11.760
Heute würde man eher dann eben

01:41:11.760 --> 01:41:14.220
Arrow verwenden und dann ein paar K-Files

01:41:14.220 --> 01:41:15.040
lesen und schreiben.

01:41:16.320 --> 01:41:17.400
Das ist auch sehr schnell.

01:41:19.300 --> 01:41:20.860
ähm, HD5 ist,

01:41:21.120 --> 01:41:22.640
geht so, ist ein bisschen,

01:41:23.300 --> 01:41:24.480
ist nicht ganz so schnell, aber

01:41:24.480 --> 01:41:25.860
ja,

01:41:26.920 --> 01:41:28.900
lass mal überlegen, gibt's sonst noch irgendwelche Formate, die

01:41:28.900 --> 01:41:30.920
interessant sind? Es gibt dieses NetCDF4,

01:41:31.040 --> 01:41:33.160
das ist die Weiterentwicklung von HD5

01:41:33.160 --> 01:41:34.720
und, ähm,

01:41:35.520 --> 01:41:37.040
da hat man dann... Hier ist die Weiterentwicklung von

01:41:37.040 --> 01:41:39.040
5? NetCDF4,

01:41:39.340 --> 01:41:40.940
ähm, das ist schon die

01:41:40.940 --> 01:41:42.760
vierte Iteration von NetCDF,

01:41:43.060 --> 01:41:44.880
aber irgendwann sind die wohl aus HDF

01:41:44.880 --> 01:41:46.880
entstanden. Wie das

01:41:46.880 --> 01:41:48.940
genau zustande gekommen ist, weiß ich auch nicht.

01:41:49.300 --> 01:41:54.360
Die haben dann so Späße, wie man kann direkt File Blobs angeben

01:41:54.360 --> 01:41:57.940
und dann über mehrere Files eine Variable öffnen.

01:41:58.540 --> 01:42:03.540
Das ist ganz spannend, wenn man sehr große Datensätze als Chunks

01:42:03.540 --> 01:42:05.260
auf seiner Festplatte hat.

01:42:07.180 --> 01:42:09.700
Aber technische Details dazu weiß ich jetzt auch nicht.

01:42:11.300 --> 01:42:13.740
Tja, Tim, hast du noch ein Lieblingsmodul?

01:42:14.000 --> 01:42:16.820
Ja, ich habe ja eben schon gesagt, ich mag Plotly unheimlich gerne.

01:42:17.220 --> 01:42:20.200
Aber wenn man Plotly-Grafen erstellen möchte,

01:42:20.380 --> 01:42:23.940
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.940 --> 01:42:29.600
Und Matplotlib geht halt schnell.

01:42:30.740 --> 01:42:34.420
Und Plotly hat kürzlich noch ein Tool rausgebracht,

01:42:34.640 --> 01:42:37.220
Matplotlib-to-Plotly-Grafen,

01:42:37.800 --> 01:42:40.720
wo man, das funktioniert noch nicht perfekt,

01:42:41.440 --> 01:42:45.260
aber so die Basis-Grafen wie Boxplots oder Scatterplots

01:42:45.260 --> 01:42:46.980
sowas kriegt man damit

01:42:46.980 --> 01:42:48.880
in Matplotlib ganz schnell

01:42:48.880 --> 01:42:50.860
definiert, irgendwie mit zwei, drei Zeilen

01:42:50.860 --> 01:42:53.000
Code und dann mit einer

01:42:53.000 --> 01:42:54.840
Zeile konvertiert in Plotligrafen

01:42:54.840 --> 01:42:56.680
und dann hat man direkt dieses

01:42:56.680 --> 01:42:58.640
Interaktive, man hat

01:42:58.640 --> 01:43:00.720
Mouse-Hover und man kann zoomen und

01:43:00.720 --> 01:43:02.840
so. Das fand ich ganz schön.

01:43:03.200 --> 01:43:04.000
Ist aber noch

01:43:04.000 --> 01:43:06.760
in den Kinderschuhen.

01:43:07.500 --> 01:43:09.120
Ja, aber schön, das spannend zu verfolgen.

01:43:10.820 --> 01:43:11.300
Cool.

01:43:12.600 --> 01:43:14.460
Habt ihr noch irgendwas, was ihr loswerden wollt?

01:43:14.460 --> 01:43:16.320
irgendwie das zu eurem Modul der Woche oder

01:43:16.320 --> 01:43:17.760
sind wir damit durch und

01:43:17.760 --> 01:43:20.580
Nö, ich glaube damit. Achso, vielleicht

01:43:20.580 --> 01:43:22.660
ja, wollen wir

01:43:22.660 --> 01:43:24.700
genau

01:43:24.700 --> 01:43:26.460
nächste Woche ist vielleicht ganz interessant,

01:43:26.640 --> 01:43:28.300
wenn irgendjemand da ist, der

01:43:28.300 --> 01:43:30.480
zuhört, zufällig, aber ich glaube es ist wahrscheinlich

01:43:30.480 --> 01:43:32.780
eher nicht so eine Podcast-Konferenz

01:43:32.780 --> 01:43:34.080
in Köln. Ja, die Subscribe.

01:43:34.440 --> 01:43:36.540
Bei uns genau um die Ecke ist, dachten wir, gehen wir auch mal hin.

01:43:37.180 --> 01:43:38.240
Genau, da werdet ihr uns finden.

01:43:38.460 --> 01:43:40.620
Genau, da könnte man uns

01:43:40.620 --> 01:43:42.640
treffen, wenn man

01:43:42.640 --> 01:43:44.380
wollte. Also wer möchte, kann einfach

01:43:44.380 --> 01:43:46.400
eine Mail an uns fragen. Das kommt in den

01:43:46.400 --> 01:43:48.240
Veranstaltungen. Genau, aber ihr könnt uns ja gerne treffen.

01:43:48.380 --> 01:43:50.320
Tatsächlich wissen wir noch nicht genau, ob wir Freitag und Samstag

01:43:50.320 --> 01:43:52.000
und Sonntag da sind. Aber

01:43:52.000 --> 01:43:54.300
auf jeden Fall am Samstag und am Sonntag wird ihr uns wahrscheinlich

01:43:54.300 --> 01:43:56.200
da sehen.

01:43:56.500 --> 01:43:58.160
Das besprechen wir noch genauer.

01:43:58.600 --> 01:44:00.440
Am nächsten ist ja

01:44:00.440 --> 01:44:02.060
immer mal wieder Django zur Sprache

01:44:02.060 --> 01:44:04.160
gekommen. Anfang April ist die

01:44:04.160 --> 01:44:05.740
DjangoCon in Kopenhagen.

01:44:06.260 --> 01:44:08.520
Vom 10. bis zum

01:44:08.520 --> 01:44:10.300
14. April ist es, glaube ich.

01:44:12.640 --> 01:44:13.540
Sieht man dich da?

01:44:14.520 --> 01:44:16.560
Mich nur am 9. April.

01:44:17.000 --> 01:44:18.720
Da ist das Django Girls Camp.

01:44:18.840 --> 01:44:19.640
Ein Tag Django

01:44:19.640 --> 01:44:21.900
lernen.

01:44:22.800 --> 01:44:24.440
Da fliege ich kurz hin

01:44:24.440 --> 01:44:26.500
als Mentor. Ich habe leider für die Konferenz selber

01:44:26.500 --> 01:44:28.060
keine Zeit. Ja, okay, super.

01:44:29.360 --> 01:44:30.580
Ja, wolltest du noch was

01:44:30.580 --> 01:44:32.680
zu dem Cast sagen, zum Django-Cast,

01:44:32.780 --> 01:44:34.220
Jochen, oder machen wir das von anders?

01:44:36.640 --> 01:44:38.380
Ja, also da, letztens

01:44:38.380 --> 01:44:40.460
gab es irgendwie so ein Mail von Apple,

01:44:40.460 --> 01:44:41.140
wo sie gesagt haben,

01:44:41.680 --> 01:44:43.560
also wir werden euch jetzt nicht direkt

01:44:43.560 --> 01:44:45.560
auslisten irgendwie, aber

01:44:45.560 --> 01:44:47.560
ihr solltet dann mal vielleicht irgendwie ein paar Sachen an eurem Feed

01:44:47.560 --> 01:44:48.680
ändern, da muss ich jetzt nochmal ran.

01:44:50.320 --> 01:44:51.540
Zum Beispiel sowas wie Episoden,

01:44:51.700 --> 01:44:53.500
Nummern sollten nicht im Titel sein und so.

01:44:54.060 --> 01:44:55.600
Das machen aber alle, ich auch.

01:44:56.200 --> 01:44:57.560
Wir können uns weiter nochmal

01:44:57.560 --> 01:44:59.480
irgendwas dran tun und genau,

01:44:59.700 --> 01:45:01.580
ja, wir machen da auch

01:45:01.580 --> 01:45:02.860
so einen kleinen Workshop

01:45:02.860 --> 01:45:05.360
irgendwie auf der Subscribe und

01:45:05.360 --> 01:45:07.040
da müssen wir auch noch ein bisschen was für tun

01:45:07.040 --> 01:45:09.320
und da wäre es natürlich auch interessant, was dann noch so, also

01:45:09.320 --> 01:45:11.520
was ich jetzt schon implementiert habe, ist, dass man jetzt nicht mehr

01:45:11.520 --> 01:45:13.080
dass ich dann ein JavaScript-Interface brauche,

01:45:13.480 --> 01:45:15.480
um irgendwie Audio-Files hochzuladen.

01:45:17.200 --> 01:45:17.600
Aber

01:45:17.600 --> 01:45:19.540
ja, mal gucken, was da noch so da dazukommt.

01:45:19.820 --> 01:45:21.580
Und dann, was super dringend ist,

01:45:21.580 --> 01:45:23.220
ist irgendwie, dass die Dokumentation

01:45:23.220 --> 01:45:24.480
mal so ein bisschen besser wird und so.

01:45:24.840 --> 01:45:26.260
Mal gucken, ob ich die zwei Zeilen zu schraff.

01:45:27.860 --> 01:45:29.660
Zumindest so in den First Step oder so.

01:45:30.580 --> 01:45:31.660
So in den großen Struggle.

01:45:31.740 --> 01:45:32.940
Ja, wenn ihr irgendwie so Anfänger seid wie ich,

01:45:32.980 --> 01:45:34.200
dann kommt ihr da bestimmt noch irgendwo dran.

01:45:35.120 --> 01:45:37.460
Ja, vielen Dank, dass ihr

01:45:37.460 --> 01:45:39.720
zugehört habt heute wieder, dass ihr eingeschaltet habt.

01:45:39.840 --> 01:45:41.440
Wie auch immer, wann auch immer, wo auch immer.

01:45:41.520 --> 01:45:43.180
lasst uns das übrigens wissen, schreibt

01:45:43.180 --> 01:45:45.040
eure E-Mails, Kommentare an

01:45:45.040 --> 01:45:47.080
hallo-at-python-podcast.de und

01:45:47.080 --> 01:45:48.540
ja, kippt uns

01:45:48.540 --> 01:45:51.260
weiter an alle Leute, die Python interessiert, in eurer Nähe,

01:45:51.460 --> 01:45:52.880
erzählt euren Freunden, Kommoditonen.

01:45:53.920 --> 01:45:55.080
Ja, das kann man vielleicht auch,

01:45:55.200 --> 01:45:57.180
was man auch machen kann, ist auf iTunes

01:45:57.180 --> 01:45:58.220
bewerten, wenn das irgendwie,

01:45:59.200 --> 01:46:00.600
also das hilft natürlich stark,

01:46:01.880 --> 01:46:02.180
aber

01:46:02.180 --> 01:46:05.180
genau, ansonsten, ja.

01:46:05.760 --> 01:46:06.340
Ja, genau.

01:46:07.200 --> 01:46:09.060
Sagst Bescheid, erstmal hört uns gerne,

01:46:09.200 --> 01:46:11.220
vor allen Dingen wieder und so, bleibt uns gewogen,

01:46:11.280 --> 01:46:11.920
wie man so schön sagt.

01:46:12.880 --> 01:46:14.420
Und bis zum nächsten Mal. Bis zum nächsten Mal, tschüss.

01:46:14.440 --> 01:46:15.700
Vielen Dank für die Einladung, tschüss.
