D3kjd3Di38lk323nnm Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 Inhalt 1 Einleitung 1 .................................................. Wovon handelt dieses Buch? . . . . Warum Python zur Datenanalyse? Essenzielle Python-Bibliotheken . Installation und Einrichtung . . . . Community und Konferenzen . . . Navigation durch dieses Buch . . . Typografische Konventionen . . . Benutzung von Codebeispielen . . Danksagungen . . . . . . . . . . . . . . 2 Einführende Beispiele .................................. 1 .................................. 2 .................................. 4 .................................. 7 .................................. 10 .................................. 10 .................................. 12 .................................. 13 .................................. 13 ......................................... 15 1.USA.gov-Daten von bit.ly . . . . . MovieLens 1M Data Set . . . . . . . . US-Babynamen von 1880 bis 2010 Fazit und der Weg vor Ihnen . . . . ................................. 16 ................................. 25 ................................. 31 ................................. 43 3 IPython: Eine interaktive Rechen- und Entwicklungsumgebung IPython-Grundlagen . . . . . . . . . . . . . . . . . . . . . . . Verwenden der Befehlschronik . . . . . . . . . . . . . . . . Interaktion mit dem Betriebssystem . . . . . . . . . . . . . Werkzeuge zur Softwareentwicklung . . . . . . . . . . . . IPython HTML Notebook . . . . . . . . . . . . . . . . . . . Tipps zur produktiven Codeentwicklung mit IPython Fortgeschrittene Features von IPython . . . . . . . . . . . Danksagung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 ........ .................... 46 .................... 58 .................... 61 .................... 63 .................... 74 .................... 75 .................... 78 .................... 80 | V 4 Grundlagen von NumPy: Arrays und vektorisierte Berechnung Das ndarray von NumPy: ein mehrdimensionales Array-Objekt . . Universelle Funktionen: Schnelle elementweise Array-Funktionen Datenverarbeitung mit Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . Dateiein- und -ausgabe bei Arrays . . . . . . . . . . . . . . . . . . . . . . . Lineare Algebra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Erzeugen von Zufallszahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . Beispiel: Random Walks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Erste Schritte mit pandas ......... 81 ........... 82 ........... 97 ........... 99 ........... 106 ........... 107 ........... 109 ........... 110 ...................................... 115 Einführung in die Datenstrukturen von pandas . . . . . Essenzielle Funktionalität . . . . . . . . . . . . . . . . . . . . . Zusammenfassen und Berechnen deskriptiver Statistik Behandlung fehlender Daten . . . . . . . . . . . . . . . . . . . Hierarchisches Indizieren . . . . . . . . . . . . . . . . . . . . . Weitere Themen in pandas . . . . . . . . . . . . . . . . . . . . ................... 116 ................... 126 ................... 141 ................... 147 ................... 152 ................... 157 6 Laden und Speichern von Daten sowie Dateiformate Lesen und Schreiben von Daten im Textformat Binäre Datenformate . . . . . . . . . . . . . . . . . . . Interagieren mit HTML und Web-APIs . . . . . . Interaktion mit Datenbanken . . . . . . . . . . . . . ................. 161 ........................ 161 ........................ 177 ........................ 179 ........................ 180 7 Datenaufbereitung: Säubern, Transformieren, Verknüpfen und Umformen 183 Kombinieren und Verknüpfen von Datensätzen . Umformen und Transponieren . . . . . . . . . . . . . Transformieren von Daten . . . . . . . . . . . . . . . . Manipulation von Strings . . . . . . . . . . . . . . . . . Fallstudie: Die USDA-Nahrungsmitteldatenbank 8 Plotten und Visualisieren ....................... 183 ....................... 196 ....................... 201 ....................... 213 ....................... 220 ...................................... 227 Kurze Einführung in die matplotlib-API . . . . . . . . . . . . . . . . . . . . . . . . . Plotten von Funktionen in pandas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Karten zeichnen: Visualisieren der Daten aus der Erdbebenkrise auf Haiti Das Ökosystem der Visualisierungstools in Python . . . . . . . . . . . . . . . . . 9 Aggregation von Daten und Gruppenoperationen ..... 228 ..... 241 ..... 252 ..... 258 ................... 261 GroupBy-Mechanismen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 Aggregation von Daten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 Gruppenweise Operationen und Transformationen . . . . . . . . . . . . . . . . . . . . . 275 VI | Inhalt Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 Pivot-Tabellen und Kreuztabellierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 Fallstudie: Die Datenbank des US-Bundeswahlausschusses von 2012 . . . . . . . . . 288 10 Zeitreihen 299 .................................................. Datentypen und Werkzeuge für Datum und Zeit . . . . . . Grundlagen von Zeitreihen . . . . . . . . . . . . . . . . . . . . . . Datumsbereiche, Frequenzen und Verschiebungen . . . . . Berücksichtigung von Zeitzonen . . . . . . . . . . . . . . . . . . Perioden und Arithmetik von Perioden . . . . . . . . . . . . . Resampling und Konvertieren von Frequenzen . . . . . . . . Plotten von Zeitreihen . . . . . . . . . . . . . . . . . . . . . . . . . Funktionen mit gleitenden Fenstern . . . . . . . . . . . . . . . Notizen zu Rechengeschwindigkeit und Speichernutzung ................. 300 ................. 303 ................. 307 ................. 313 ................. 317 ................. 323 ................. 330 ................. 332 ................. 338 11 Anwendungen auf Daten aus Finanzwelt und Ökonomie 341 .............. Themen aus der Datenklempnerei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341 Gruppentransformationen und Analyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353 Weitere Anwendungsbeispiele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358 12 NumPy für Fortgeschrittene 367 .................................... Interna von ndarray-Objekten . . . . . . . . . . . . . . . Fortgeschrittene Manipulation von Arrays . . . . . . Broadcasting . . . . . . . . . . . . . . . . . . . . . . . . . . . Fortgeschrittene Nutzung von ufuncs . . . . . . . . . Strukturierte und Record-Arrays . . . . . . . . . . . . . Mehr zum Thema Sortieren . . . . . . . . . . . . . . . . Die Klasse Matrix in NumPy . . . . . . . . . . . . . . . . Ein- und Ausgabe von Arrays für Fortgeschrittene Tipps für höhere Leistung . . . . . . . . . . . . . . . . . . ...................... 367 ...................... 369 ...................... 377 ...................... 382 ...................... 385 ...................... 387 ...................... 392 ...................... 393 ...................... 395 Anhang: Grundlagen der Programmiersprache Python . . . . . . . . . . . . . . . . . . 399 Index 449 ........................................................ Inhalt | VII KAPITEL 4 Grundlagen von NumPy: Arrays und vektorisierte Berechnung NumPy, die Kurzform von Numerical Python, ist das elementare Paket, das für wissenschaftliches Rechnen mit hoher Leistung und Datenanalyse gebraucht wird. Auf dieser Grundlage bauen so gut wie alle höher entwickelten Werkzeuge in diesem Buch auf. Hier ein paar Dinge, die es zu bieten hat: • ndarray, ein schnelles und platzsparendes mehrdimensionales Array, das neben vektorisierten arithmetischen Operationen über ein ausgeklügeltes Broadcasting verfügt. • Mathematische Standardfunktionen für schnelle Operationen auf ganzen Arrays, ohne Schleifen programmieren zu müssen. • Werkzeuge zum Lesen und Schreiben von Daten auf Festplatte sowie für die Arbeit mit Memory-mapped Dateien. • Lineare Algebra, Erzeugen von Zufallszahlen sowie Fourier-Transformation. • Werkzeuge zur Anbindung von Code, der in C, C++ oder Fortran geschrieben wurde. Aus der Sicht eines Ökosystems ist der letzte Punkt auch einer der wichtigsten. Weil NumPy eine einfach zu verwendende C-API bereitstellt, ist es sehr leicht, Daten an externe, in niederen Sprachen geschriebene Bibliotheken zu übergeben und ebenso die Daten von solchen Bibliotheken wieder als NumPy-Arrays zurückzugeben. Diese Fähigkeit hat Python zur Sprache der Wahl gemacht, um Wrapper für vorhandenen Code in C/C++/Fortran zu erzeugen und ihnen ein dynamisches, leicht zu verwendendes Interface zu geben. Wenn auch NumPy von sich aus nicht viele hoch entwickelte Funktionalitäten zur Datenanalyse besitzt, so hilft ein gutes Grundverständnis von NumPy-Arrays und Arrayorientiertem Rechnen doch erheblich beim Umgang mit Tools wie pandas. Wenn Sie neu in Python sind und erst einmal nur ein Gefühl für die Handhabung von Daten durch pandas bekommen möchten, können Sie dieses Kapitel auch erst mal querlesen. Für die besonderen Eigenschaften von NumPy wie Broadcasting gibt es Kapitel 12. | Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 81 Für die meisten Applikationen zur Datenanalyse sind folgende die Hauptbereiche, mit denen wir es zu tun haben: • Schnelle, vektorisierte Array-Operationen zum Bereinigen von Daten, zum Bilden und Filtern von Teilmengen, zum Umwandeln und für jede Menge anderer Berechnungen. • Verbreitete Array-Algorithmen wie Sortieren, Eindeutigkeit und Mengenoperationen. • Effiziente deskriptive Statistik und Aggregation/Summierung von Daten. • Datenausrichtung und Manipulation relationaler Daten zum Mischen und Verbinden heterogener Datenmengen. • Ausdrücken logischer Bedingungen als Array-Ausdruck anstelle von Schleifen mit if-elif-else-Verzweigungen. • Gruppenweise Datenmanipulation (Aggregation, Transformation, Funktionsanwendung). Viel mehr davon in Kapitel 5. Während NumPy die rechnerische Grundlage für diese Vorgänge bereitstellt, werden Sie wohl doch eher pandas für die meisten Arten der Datenanalyse einsetzen wollen (insbesondere für strukturierte oder tabellarische Daten), da es ein reiches und hoch angesiedeltes Interface zur Verfügung stellt, das die typischen Anwendungen sehr kompakt und einfach macht. pandas bietet obendrein etwas speziellere Funktionalität wie die Manipulation von Zeitreihen, womit NumPy gar nicht aufwarten kann. In diesem Kapitel wie auch im Rest des Buchs setze ich als Konvention stets die Anweisung import numpy as np voraus. Natürlich kann ich Sie nicht daran hindern, from numpy import * in Ihren Code zu schreiben, um dieses ewige np. zu vermeiden, aber ich rate dringend davon ab, dies als schlechte Angewohnheit zu kultivieren. Das ndarray von NumPy: ein mehrdimensionales Array-Objekt Eine der zentralen Eigenschaften von NumPy ist sein N-dimensionales Array-Objekt oder auch ndarray, das einen schnellen, flexiblen Container für große Datensätze in Python bietet. Arrays ermöglichen Ihnen, mathematische Operationen auf ganzen Blöcken von Daten durchzuführen, wobei die Syntax den äquivalenten skalaren Operationen immer noch ähnlich bleibt: In [8]: data Out[8]: array([[ 0.9526, -0.246 , -0.8856], [ 0.5639, 0.2379, 0.9104]]) In [9]: data * 10 Out[9]: 82 | In [10]: data + data Out[10]: Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung array([[ 9.5256, -2.4601, -8.8565], [ 5.6385, 2.3794, 9.104 ]]) array([[ 1.9051, -0.492 , -1.7713], [ 1.1277, 0.4759, 1.8208]]) Ein ndarray ist ein generischer mehrdimensionaler Behälter für homogene Daten; das bedeutet, alle Elemente müssen den gleichen Datentyp aufweisen. Jedes Array hat einen shape, ein Tupel, das die Größe in jeder Dimension angibt, sowie einen dtype, ein Objekt, das den Datentyp des Arrays anzeigt: In [11]: data.shape Out[11]: (2, 3) In [12]: data.dtype Out[12]: dtype('float64') Dieses Kapitel wird Sie in die Grundzüge von Arrays in NumPy einführen und sollte ausreichen, mit dem Rest des Buchs zurechtzukommen. Für viele Anwendungen der Datenanalyse brauchen Sie kein tiefes Verständnis von NumPy. Wenn Sie aber ein wissenschaftlicher Python-Guru werden möchten, ist ein profundes Wissen über Arrayorientiertes Programmieren und entsprechendes Denken eine notwendige Voraussetzung. Wann immer Sie auf ein »Array«, »NumPy-Array« oder »ndarray« im Text stoßen, bezieht sich dies bis auf wenige Ausnahmen immer auf das Gleiche: das ndarray-Objekt. Erzeugen von ndarrays Der einfachste Weg, ein Array zu erzeugen, geht über die Funktion array. Sie akzeptiert jedes Sequenzobjekt (einschließlich anderer Arrays) und produziert ein neues NumPyArray mit den übergebenen Daten. Ein guter Kandidat zur Umwandlung ist beispielsweise eine Liste: In [13]: data1 = [6, 7.5, 8, 0, 1] In [14]: arr1 = np.array(data1) In [15]: arr1 Out[15]: array([ 6. , 7.5, 8. , 0. , 1. ]) Verschachtelte Sequenzen wie etwa eine Liste von Listen gleicher Länge werden in ein mehrdimensionales Array umgeformt: In [16]: data2 = [[1, 2, 3, 4], [5, 6, 7, 8]] In [17]: arr2 = np.array(data2) In [18]: arr2 Out[18]: array([[1, 2, 3, 4], [5, 6, 7, 8]]) In [19]: arr2.ndim Out[19]: 2 Das ndarray von NumPy: ein mehrdimensionales Array-Objekt Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 83 In [20]: arr2.shape Out[20]: (2, 4) Wenn nicht explizit angegeben (später dazu mehr), versucht np.array, einen guten Datentyp für das zu kreierende Array zu finden. Dieser Datentyp wird in einem speziellen dtype-Objekt abgelegt; in den obigen zwei Beispielen haben wir dann: In [21]: arr1.dtype Out[21]: dtype('float64') In [22]: arr2.dtype Out[22]: dtype('int64') Zusätzlich zu np.array gibt es noch einige andere Funktionen, die Arrays produzieren. zeros und ones etwa erzeugen Arrays aus Nullen und Einsen mit angegebener Länge oder Gestalt. empty erzeugt ein Array, ohne den Inhalt mit Werten zu besetzen. Um mit diesen Methoden höherdimensionale Arrays zu erzeugen, geben Sie ein Tupel für die Gestalt an (der erste Parameter heißt shape): In [23]: np.zeros(10) Out[23]: array([ 0., 0., 0., In [24]: Out[24]: array([[ [ [ 0., 0., 0., 0., 0., 0., 0.]) np.zeros((3, 6)) 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], 0.], 0.]]) In [25]: np.empty((2, 3, 2)) Out[25]: array([[[ 4.94065646e-324, 4.94065646e-324], [ 3.87491056e-297, 2.46845796e-130], [ 4.94065646e-324, 4.94065646e-324]], [[ 1.90723115e+083, 5.73293533e-053], [ -2.33568637e+124, -6.70608105e-012], [ 4.42786966e+160, 1.27100354e+025]]]) Es ist unsicher, anzunehmen, dass np.empty ein Array mit lauter Nullen abliefert. Wie oben gesehen, kann auch beliebiger Müll darin stehen. arange ist eine Version der eingebauten Python2-Funktion range für Arrays: In [26]: np.arange(15) Out[26]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) Im vorliegenden Python 3 ist range inzwischen ein Generator geworden. Sie erhalten das zu arange passende Verhalten, wenn Sie range durch list(range) ersetzen. Tabelle 4-1 zeigt eine kurze Übersicht der Funktionen zum Generieren von Arrays. Da NumPy auf numerisches Rechnen fokussiert ist, ist der Datentyp oft float64 (Fließkommazahl, wenn nicht explizit angegeben). 84 | Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung Tabelle 4-1: Array-erzeugende Funktionen Funktion Beschreibung array Konvertiert die angegebenen Daten (Liste, Tupel, Array oder andere Sequenz) in ein ndarray. Der Datentyp wird entweder abgeleitet oder explizit angegeben. Die Daten werden standardmäßig immer kopiert, auch wenn es nicht nötig wäre. asarray Konvertiert die Eingabe in ein ndarray, aber nur, wenn sie nicht bereits ein ndarray ist. arange Wie das eingebaute list(range), ergibt aber ein ndarray statt einer Liste. ones, ones_like Produziert ein Array aus lauter Einsen mit angegebener Gestalt und angegebenem Datentyp. ones_like übernimmt ein anderes Array und setzt bei gleicher Gestalt und gleichem Typ überall Einsen ein. zeros, zeros_like Wie ones und ones_like, aber mit Nullen statt Einsen. empty, empty_like Erzeugt neues Array durch Allozieren neuen Speichers, aber trägt keine Werte ein wie ones und zeros. eye, identity Erzeugt eine quadratische N-x-N-Einheitsmatrix (Einsen auf der Hauptdiagonalen und sonst Nullen). Datentypen für ndarrays Der Datentyp oder dtype ist ein spezielles Objekt mit der Information, die das ndarray braucht, um ein Stück Speicher als einen bestimmten Datentyp zu interpretieren: In [27]: arr1 = np.array([1, 2, 3], dtype=np.float64) In [28]: arr2 = np.array([1, 2, 3], dtype=np.int32) In [29]: arr1.dtype Out[29]: dtype('float64') In [30]: arr2.dtype Out[30]: dtype('int32') Die dtype-Objekte sind ein Teil dessen, was NumPy so mächtig und flexibel macht. In den meisten Fällen entsprechen sie direkt einer zugrunde liegenden Maschinendarstellung, was es leicht macht, binäre Datenströme von und zur Platte zu übertragen sowie Code anzubinden, der in einer primitiven Sprache wie C oder Fortran geschrieben wurde. Die numerischen dtypes sind ähnlich benannt: Ein dtype-Name wie float oder int wird von einer Zahl gefolgt, die die Anzahl der Bits pro Element angibt. Ein normaler Fließkommawert in doppelter Genauigkeit (was Python übrigens auch als float-Objekt benutzt) verbraucht genau 8 Bytes oder 64 Bits. Mithin ist dieser Typ in NumPy als float64 bekannt (siehe Tabelle 4-2 für die Komplettliste der von NumPy unterstützten Datentypen). Versuchen Sie jetzt bitte nicht, sich alle dtypes von NumPy zu merken, insbesondere wenn Sie ein Neueinsteiger sind. Es reicht oft völlig aus, sich mit der generellen Art der Daten auseinanderzusetzen, mit der Sie umgehen, sei es Fließkommazahl, Komplex, Integer, Boolesch, String oder ein allgemeines Python-Objekt. Wenn Sie wirklich mehr Kontrolle über die Ablage im Speicher und auf Platte benötigen, insbesondere bei großen Datenmengen, haben Sie auch die Möglichkeiten dazu. Das ndarray von NumPy: ein mehrdimensionales Array-Objekt Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 85 Tabelle 4-2: Datentypen von NumPy Typ Typencode Beschreibung int8, uint8 i1, u1 8-Bit-(1-Byte-)Integer-Typen mit und ohne Vorzeichen. int16, uint16 i2, u2 16-Bit-Integer-Typen mit und ohne Vorzeichen. int32, uint32 i4, u4 32-Bit-Integer-Typen mit und ohne Vorzeichen. int64, uint64 i8, u8 64-Bit-Integer-Typen mit und ohne Vorzeichen. float16 f2 Fließkommazahlen mit halber Genauigkeit. float32 f4 oder f Fließkommazahlen mit einfacher Genauigkeit, kompatibel mit einem C float. float64 f8 oder d Fließkommazahlen mit einfacher Genauigkeit, kompatibel mit einem C double und dem float-Objekt in Python. float128 f16 oder g Fließkommazahlen mit erweiterter Genauigkeit. complex64, complex128, complex256 c8, c16, c32 Komplexe Zahlen, durch je zwei Fließkommazahlen mit 32, 64 oder 128 Bit dargestellt. bool ? Boolescher Typ, speichert die Werte True und False. object O Typ Python-Objekt. string_ S String-Typ fester Länge, 1 Byte pro Zeichen. Ein String dtype mit 10 Zeichen wäre zum Beispiel 'S10'. unicode_ U Unicode-Typ fester Länge, Anzahl an Bytes ist plattformabhängig. Gleiche semantische Spezifikation wie string_ (z. B. 'U10'). Mithilfe der Methode astype von ndarry können Sie ein Array explizit von einem dtype zu einem anderen umwandeln, auch Casting genannt: In [31]: arr = np.array([1, 2, 3, 4, 5]) In [32]: arr.dtype Out[32]: dtype('int64') In [33]: float_arr = arr.astype(np.float64) In [34]: float_arr.dtype Out[34]: dtype('float64') In diesem Fall wurden Integer zu Fließkommazahlen gecastet. Wenn ich eine Fließkommazahl zu einem Integer caste, wird der Nachkommateil abgeschnitten: In [35]: arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1]) In [36]: arr Out[36]: array([ 3.7, -1.2, -2.6, 0.5, 12.9, 10.1]) In [37]: arr.astype(np.int32) Out[37]: array([ 3, -1, -2, 0, 12, 10], dtype=int32) 86 | Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung Sollten Sie ein Array aus Strings haben, die Zahlen darstellen, können Sie astype benutzen, um diese in eine numerische Form umzuwandeln: In [38]: numeric_strings = np.array(['1.25', '-9.6', '42'], dtype=np.string_) In [39]: numeric_strings.astype(float) Out[39]: array([ 1.25, -9.6 , 42. ]) Wenn das Casting aus irgendeinem Grund fehlschlägt (wie z. B. ein String, der sich nicht in float64 umwandeln lässt), wird ein TypeError ausgelöst. Hier war ich übrigens etwas faul und schrieb einfach float anstelle von np.float64; NumPy ist clever genug, um zu erkennen, dass der Python-Typ hier den dtype anzeigen soll. Sie können ebenfalls das dtype-Attribut eines anderen Arrays benutzen: In [40]: int_array = np.arange(10) In [41]: calibers = np.array([.22, .270, .357, .380, .44, .50], dtype=np.float64) In [42]: int_array.astype(calibers.dtype) Out[42]: array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]) Es gibt ein paar Abkürzungscodes, mit denen Sie sich auch auf bestimmte dtypes beziehen können: In [43]: empty_uint32 = np.empty(8, dtype='u4') In [44]: empty_uint32 Out[44]: array([ 0, 39438163, 0, 65904672, 0], dtype=uint32) 0, 64856792, 0, Der Aufruf von astype kreiert immer ein neues Array (eine Kopie der Daten), auch wenn der neue dtype identisch mit dem alten ist. Man sollte im Kopf behalten, dass Fließkommazahlen, wie die in Arrays des Typs float64 oder float32, nur eine Annäherung von gebrochenen Zahlen speichern können. Bei komplexen Berechnungen kann dadurch einiges an Fließkommafehlern auflaufen, sodass Vergleiche nur bis zu einer begrenzten Anzahl von Dezimalstellen sinnvoll sind. Operationen zwischen Arrays und Skalaren Arrays sind wichtig, weil sie erlauben, viele Operationen auf Daten durchzuführen, ohne eine for-Schleife zu schreiben. Das nennt man oft auch Vektorisierung. Jede arithmetische Operation zwischen gleich großen Arrays führt ihre Arbeit elementweise durch: Das ndarray von NumPy: ein mehrdimensionales Array-Objekt Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 87 In [45]: arr = np.array([[1., 2., 3.], [4., 5., 6.]]) In [46]: arr Out[46]: array([[ 1., [ 4., 2., 3.], 5., 6.]]) In [47]: arr * arr Out[47]: array([[ 1., 4., [ 16., 25., 9.], 36.]]) In [48]: arr - arr Out[48]: array([[ 0., 0., 0.], [ 0., 0., 0.]]) Arithmetische Operationen mit Skalaren propagieren den Skalar zu jedem Element des Arrays, wie Sie es sich vermutlich gewünscht haben: In [49]: 1 / arr Out[49]: array([[ 1. , [ 0.25 , 0.5 0.2 , 0.3333], , 0.1667]]) In [50]: arr ** 0.5 Out[50]: array([[ 1. , 1.4142, 1.7321], [ 2. , 2.2361, 2.4495]]) Operationen zwischen Arrays verschiedener Größe nennt man Broadcasting. Das wird eingehender in Kapitel 12 besprochen. Ein tiefer gehendes Verständnis des Broadcastings ist für einen Großteil dieses Buchs nicht so wichtig. Einfaches Indizieren und Slicing Das Indizieren von Arrays in NumPy ist ein weites Feld, weil es ziemlich viele Wege gibt, wie Sie vielleicht auf Teilmengen oder individuelle Elemente zugreifen möchten. Eindimensionale Arrays sind recht einfach; oberflächlich betrachtet, benehmen sie sich ähnlich wie Python-Listen: In [51]: arr = np.arange(10) In [52]: arr Out[52]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) In [53]: arr[5] Out[53]: 5 In [54]: arr[5:8] Out[54]: array([5, 6, 7]) In [55]: arr[5:8] = 12 In [56]: arr Out[56]: array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9]) Wie Sie sehen können, wird ein skalarer Wert, wenn Sie ihn einem Teilbereich, wie bei arr[5:8] = 12, zuweisen, an alle Positionen propagiert (man sagt dazu auch Broadcasting). Ein wichtiger erster Unterschied gegenüber Listen ist, dass Teilbereiche (Slices) von Arrays sogenannte Views auf das ursprüngliche Array sind. Die Daten werden dabei nicht kopiert, und jede Änderung des Views schlägt sich auch im Array nieder: 88 | Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung In [57]: arr_slice = arr[5:8] In [58]: arr_slice[1] = 12345 In [59]: arr Out[59]: array([ 0, 1, 2, 3, 4, 12, 12345, 12, 8, 9]) In [60]: arr_slice[:] = 64 In [61]: arr Out[61]: array([ 0, 1, 2, 3, 4, 64, 64, 64, 8, 9]) Wenn Sie neu bei NumPy sind, mag Sie das überraschen – vor allem wenn Sie andere Sprachen für Arrays kennen, die eifriger im Kopieren sind. Weil NumPy für große Datenmengen konzipiert wurde, können Sie sich vorstellen, was für Rechenzeit- und Speicherprobleme entstünden, wenn NumPy darauf beharrte, alle naselang etwas kopieren zu müssen. Wenn Sie auf einer echten Kopie eines Slice bestehen, müssen Sie explizit das Array kopieren, zum Beispiel arr[5:8].copy(). Bei höherdimensionalen Arrays haben Sie gleich eine Menge mehr Optionen. Im zweidimensionalen Fall sind die Elemente an jedem Index nicht mehr Skalare, sondern eindimensionale Arrays: In [62]: arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) In [63]: arr2d[2] Out[63]: array([7, 8, 9]) Mithin kann man einzelne Elemente rekursiv ansprechen. Aber das ist etwas viel Aufwand, besser ist es, Sie übergeben eine kommaseparierte Liste von Indizes zum Selektieren einzelner Elemente. Folgendes ist also äquivalent: In [64]: arr2d[0][2] Out[64]: 3 In [65]: arr2d[0, 2] Out[65]: 3 Beachten Sie auch Abbildung 4-1 für eine Illustration der Indizierung bei einem 2D-Array. Das ndarray von NumPy: ein mehrdimensionales Array-Objekt Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 89 axis 1 axis 0 0 1 2 0 0, 0 0, 1 0, 2 1 1, 0 1, 1 1, 2 2 2, 0 2, 1 2, 2 Abbildung 4-1: Elemente in einem NumPy-Array indizieren Wenn Sie bei einem mehrdimensionalen Array spätere Indizes weglassen, entsteht ein niedrigerdimensionales ndarray mit all den Daten entlang den höheren Dimensionen. Sehen wir uns das 2 × 2 × 3-Array arr3d an: In [66]: arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) In [67]: arr3d Out[67]: array([[[ 1, 2, [ 4, 5, [[ 7, 8, [10, 11, 3], 6]], 9], 12]]]) arr3d[0] ist ein 2 × 3-Array: In [68]: arr3d[0] Out[68]: array([[1, 2, 3], [4, 5, 6]]) Sowohl skalare Werte als auch Arrays können arr3d[0] zugewiesen werden: In [69]: old_values = arr3d[0].copy() In [70]: arr3d[0] = 42 In [71]: arr3d Out[71]: array([[[42, 42, [42, 42, [[ 7, 8, [10, 11, 42], 42]], 9], 12]]]) In [72]: arr3d[0] = old_values In [73]: arr3d Out[73]: 90 | Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung array([[[ 1, 2, [ 4, 5, [[ 7, 8, [10, 11, 3], 6]], 9], 12]]]) Analog gibt Ihnen arr3d[1, 0] alle Werte, deren Indizes mit (1, 0) anfangen, also ein eindimensionales Array: In [74]: arr3d[1, 0] Out[74]: array([7, 8, 9]) Beachten Sie, dass in allen Fällen, in denen Unterbereiche von Arrays selektiert wurden, die Ergebnisse Views waren. Indizieren mit Slices Wie eindimensionale Objekte (etwa Listen in Python) können auch ndarrays mit der gewohnten Syntax ausgeschnitten werden: In [75]: arr[1:6] Out[75]: array([ 1, 2, 3, 4, 64]) Höherdimensionale Objekte ergeben mehr Möglichkeiten zum Slicing, da man entlang einer oder mehrerer Achsen schneiden und mit Integern mixen kann. Betrachten wir obiges zweidimensionales Array, arr2d. Das Slicing ist bei diesem Array etwas anders: In [76]: arr2d Out[76]: array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) In [77]: arr2d[:2] Out[77]: array([[1, 2, 3], [4, 5, 6]]) Wie Sie sehen, wurde entlang von Achse 0 geschnitten, der ersten Achse. Ein Slice selektiert somit einen Bereich von Elementen entlang einer Achse. Sie können wie auch bei Indizes mehrere Slices angeben: In [78]: arr2d[:2, 1:] Out[78]: array([[2, 3], [5, 6]]) Wenn Sie in dieser Weise schneiden, bekommen Sie immer Array-Views mit der gleichen Anzahl von Dimensionen. Beim Mischen von Integer-Indizes und Slices bekommen Sie Schnitte mit niedrigerer Dimensionalität: In [79]: arr2d[1, :2] Out[79]: array([4, 5]) In [80]: arr2d[2, :1] Out[80]: array([7]) Dies ist verdeutlicht in Abbildung 4-2. Beachten Sie, dass ein Doppelpunkt allein ohne Grenze die gesamte Achse übernimmt. Somit können Sie nur einen Slice der höherdimensionalen Achse erzeugen mit: In [81]: arr2d[:, :1] Out[81]: array([[1], Das ndarray von NumPy: ein mehrdimensionales Array-Objekt Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 91 [4], [7]]) Das Zuweisen an einen Slice-Ausdruck weist in der Tat die gesamte Selektion zu: In [82]: arr2d[:2, 1:] = 0 Boolesches Indizieren Lassen Sie uns ein Beispiel betrachten, bei dem wir einige Daten in einem Array haben, sowie ein zweites Array mit mehrfach vorhandenen Namen. Ich werde hier die randnFunktion in numpy.random verwenden, um ein paar normalverteilte Daten zu generieren: In [83]: names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe']) In [84]: data = np.random.randn(7, 4) In [85]: names Out[85]: array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype='|S4') In [86]: data Out[86]: array([[-0.048 , [-0.268 , [-0.047 , [ 2.1452, [-1.0023, [ 0.1913, [ 0.5994, 0.5433, 0.5465, -2.026 , 0.8799, -0.1698, 0.4544, 0.8174, -0.2349, 1.2792], 0.0939, -2.0445], 0.7719, 0.3103], -0.0523, 0.0672], 1.1503, 1.7289], 0.4519, 0.5535], -0.9297, -1.2564]]) Expression Shape arr[:2, 1:] (2, 2) arr[2] arr[2, :] arr[2:, :] (3,) (3,) (1, 3) arr[:, :2] (3, 2) arr[1, :2] (2,) arr[1:2, :2] (1, 2) Abbildung 4-2: Zweidimensionales Slicing von Arrays 92 | Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung Angenommen, jeder Name gehörte zu einer Zeile im Array data und wir möchten diejenigen Zeilen mit dem korrespondierenden Namen 'Bob' auswählen. Wie die arithmetischen Operationen sind auch Vergleiche (wie ==) mit Arrays vektorisiert. Das Vergleichen der Namen mit dem String 'Bob' produziert ein boolesches Array: In [87]: names == 'Bob' Out[87]: array([ True, False, False, True, False, False, False], dtype=bool) Dieses boolesche Array kann zum Indizieren verwendet werden: In [88]: data[names == 'Bob'] Out[88]: array([[-0.048 , 0.5433, -0.2349, [ 2.1452, 0.8799, -0.0523, 1.2792], 0.0672]]) Das boolesche Array muss die gleiche Länge aufweisen wie die Achse, die indiziert werden soll. Sie können boolesche Arrays sogar mit Slices und Integern kombinieren (oder ganzen Sequenzen davon, wie wir später sehen werden): In [89]: data[names == 'Bob', 2:] Out[89]: array([[-0.2349, 1.2792], [-0.0523, 0.0672]]) In [90]: data[names == 'Bob', 3] Out[90]: array([ 1.2792, 0.0672]) Um alles zu selektieren außer 'Bob', können Sie entweder != benutzen oder die Bedingung durch - negieren: In [91]: names != 'Bob' Out[91]: array([False, True, True, False, True, True, True], dtype=bool) In [92]: data[-(names == 'Bob')] Out[92]: array([[-0.268 , 0.5465, 0.0939, -2.0445], [-0.047 , -2.026 , 0.7719, 0.3103], [-1.0023, -0.1698, 1.1503, 1.7289], [ 0.1913, 0.4544, 0.4519, 0.5535], [ 0.5994, 0.8174, -0.9297, -1.2564]]) Zum Selektieren zweier der drei Namen kombinieren wir boolesche Operatoren wie & (und) und | (oder): In [93]: mask = (names == 'Bob') | (names == 'Will') In [94]: mask Out[94]: array([True, False, True, True, True, False, False], dtype=bool) In [95]: data[mask] Out[95]: array([[-0.048 , 0.5433, [-0.047 , -2.026 , [ 2.1452, 0.8799, [-1.0023, -0.1698, -0.2349, 0.7719, -0.0523, 1.1503, 1.2792], 0.3103], 0.0672], 1.7289]]) Das ndarray von NumPy: ein mehrdimensionales Array-Objekt Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 93 Das Auswählen von Daten mithilfe von booleschem Indizieren erstellt immer eine Kopie der Daten, auch wenn das Array unverändert bleibt. Die Python-Schlüsselwörter and und or funktionieren nicht mit booleschen Arrays. Das Setzen von Werten mit booleschen Arrays funktioniert nach dem gesunden Menschenverstand. Alle negativen Werte in data auf null zu setzen, ist unglaublich einfach: In [96]: data[data < 0] = 0 In [97]: Out[97]: array([[ [ [ [ [ [ [ data 0. , 0. , 0. , 2.1452, 0. , 0.1913, 0.5994, 0.5433, 0.5465, 0. , 0.8799, 0. , 0.4544, 0.8174, 0. , 0.0939, 0.7719, 0. , 1.1503, 0.4519, 0. , 1.2792], 0. ], 0.3103], 0.0672], 1.7289], 0.5535], 0. ]]) Auch ganze Zeilen oder Spalten durch ein boolesches Array zu setzen, ist sehr einfach: In [98]: data[names != 'Joe'] = 7 In [99]: Out[99]: array([[ [ [ [ [ [ [ data 7. , 0. , 7. , 7. , 7. , 0.1913, 0.5994, 7. , 0.5465, 7. , 7. , 7. , 0.4544, 0.8174, 7. , 0.0939, 7. , 7. , 7. , 0.4519, 0. , 7. ], 0. ], 7. ], 7. ], 7. ], 0.5535], 0. ]]) Fancy Indexing Fancy Indexing (übersetzbar mit »raffiniertes Indizieren«) ist ein durch NumPy adoptierter Begriff für das Indizieren durch Integer-Arrays. Angenommen, wir hätten ein 8 × 4-Array: In [100]: arr = np.empty((8, 4)) In [101]: for i in range(8): .....: arr[i] = i In [102]: arr Out[102]: array([[ 0., [ 1., [ 2., [ 3., [ 4., [ 5., 94 | 0., 1., 2., 3., 4., 5., 0., 1., 2., 3., 4., 5., 0.], 1.], 2.], 3.], 4.], 5.], Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung [ 6., [ 7., 6., 6., 7., 7., 6.], 7.]]) Zum Auswählen einiger Zeilen in einer bestimmten Anordnung übergeben Sie einfach eine Liste oder ein ndarray mit ganzen Zahlen, die die gewünschte Ordnung angeben: In [103]: arr[[4, Out[103]: array([[ 4., 4., [ 3., 3., [ 0., 0., [ 6., 6., 3, 0, 6]] 4., 3., 0., 6., 4.], 3.], 0.], 6.]]) Das war hoffentlich das, was Sie erwartet haben! Mit negativen Indizes selektieren Sie vom Ende: In [104]: arr[[-3, Out[104]: array([[ 5., 5., [ 3., 3., [ 1., 1., -5, -7]] 5., 3., 1., 5.], 3.], 1.]]) Das Angeben von mehreren Index-Arrays tut etwas geringfügig anderes, es selektiert ein eindimensionales Array, das mit jedem Tupel von Indizes korrespondiert: # more on reshape in Chapter 12 In [105]: arr = np.arange(32).reshape((8, 4)) In [106]: arr Out[106]: array([[ 0, 1, [ 4, 5, [ 8, 9, [12, 13, [16, 17, [20, 21, [24, 25, [28, 29, 2, 6, 10, 14, 18, 22, 26, 30, 3], 7], 11], 15], 19], 23], 27], 31]]) In [107]: arr[[1, 5, 7, 2], [0, 3, 1, 2]] Out[107]: array([ 4, 23, 29, 10]) Nehmen Sie sich etwas Zeit, um das genau zu verinnerlichen: Es wurden die Elemente (1, 0), (5, 3), (7, 1) und (2, 2) selektiert. Das Verhalten von Fancy Indexing ist in diesem Fall etwas anders, als man es erwarten könnte (mich selbst eingeschlossen), nämlich ein rechteckiger Bereich gebildet aus einer Teilmenge an Zeilen und Spalten. Um diesen zu bekommen, können Sie so vorgehen: In [108]: arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]] Out[108]: array([[ 4, 7, 5, 6], [20, 23, 21, 22], [28, 31, 29, 30], [ 8, 11, 9, 10]]) Das ndarray von NumPy: ein mehrdimensionales Array-Objekt Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 95 Ein weiterer Ansatz ist es, die Funktion np.ix_ zu verwenden, die zwei eindimensionale Integer-Arrays zu einem Indexer für die quadratische Region umwandelt: In [109]: arr[np.ix_([1, 5, 7, 2], [0, 3, 1, 2])] Out[109]: array([[ 4, 7, 5, 6], [20, 23, 21, 22], [28, 31, 29, 30], [ 8, 11, 9, 10]]) Behalten Sie im Hinterkopf: Fancy Indexing kopiert die Daten im Gegensatz zum Slicing immer in ein neues Array. Arrays transponieren und Achsen vertauschen Transponieren ist eine spezielle Art des Umformens, die einen View ergibt, ohne irgendetwas zu kopieren. Arrays besitzen die Methode transpose und auch das spezielle T-Attribut: In [110]: arr = np.arange(15).reshape((3, 5)) In [111]: arr Out[111]: array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) In [112]: arr.T Out[112]: array([[ 0, 5, [ 1, 6, [ 2, 7, [ 3, 8, [ 4, 9, 10], 11], 12], 13], 14]]) Bei Matrixberechnungen werden Sie dies sehr oft tun, zum Beispiel zum Berechnen des inneren Matrixprodukts XTX mit np.dot: In [113]: arr = np.random.randn(6, 3) In [114]: np.dot(arr.T, arr) Out[114]: array([[ 2.584 , 1.8753, 0.8888], [ 1.8753, 6.6636, 0.3884], [ 0.8888, 0.3884, 3.9781]]) Bei höherdimensionalen Arrays eignet sich die Methode transpose besser, weil sie ein Tupel von zu permutierenden Achsennummern akzeptiert (möge Ihr Gehirn explodieren): In [115]: arr = np.arange(16).reshape((2, 2, 4)) In [116]: arr Out[116]: array([[[ 0, 1, [ 4, 5, [[ 8, 9, [12, 13, 2, 6, 10, 14, 3], 7]], 11], 15]]]) In [117]: arr.transpose((1, 0, 2)) Out[117]: array([[[ 0, 1, 2, 3], [ 8, 9, 10, 11]], 96 | Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung [[ 4, 5, 6, 7], [12, 13, 14, 15]]]) Das einfache Transponieren mit .T ist nur der Spezialfall des Vertauschens zweier Achsen. ndarray hat ferner die Methode swapaxes, die ein Paar von Achsennummern akzeptiert: In [118]: arr Out[118]: array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7]], In [119]: Out[119]: array([[[ [ [ [ [[ 8, 9, 10, 11], [12, 13, 14, 15]]]) arr.swapaxes(1, 2) 0, 1, 2, 3, [[ 8, [ 9, [10, [11, 4], 5], 6], 7]], 12], 13], 14], 15]]]) Auf ähnliche Weise ergibt swapaxes einen View auf die Daten, ohne irgendetwas zu kopieren. Universelle Funktionen: Schnelle elementweise Array-Funktionen Eine universelle Funktion oder auch ufunc ist eine Funktion, die elementweise Operationen auf Daten in ndarrays durchführt. Sie können sich diese vorstellen als schnelle vektorisierte Wrapper für einfache Funktionen, die aus einem oder mehreren Skalaren ein oder mehrere skalare Ergebnisse produzieren. Viele ufuncs sind simple elementweise Transformationen wie etwa sqrt oder exp: In [120]: arr = np.arange(10) In [121]: np.sqrt(arr) Out[121]: array([ 0. , 1. , 1.4142, 1.7321, 2. 2.6458, 2.8284, 3. ]) , 2.2361, In [122]: np.exp(arr) Out[122]: array([ 1. , 2.7183, 7.3891, 20.0855, 148.4132, 403.4288, 1096.6332, 2980.958 , 2.4495, 54.5982, 8103.0839]) Diese werden als unäre ufuncs bezeichnet. Andere wie add oder maximum nehmen zwei Arrays (deshalb binäre ufuncs) und liefern ein einziges Array als Ergebnis: In [123]: x = np.random.randn(8) In [124]: y = np.random.randn(8) In [125]: x Out[125]: array([ 0.0749, 0.0974, 0.2002, -0.2551, 0.4655, 0.9222, 0.446 , Universelle Funktionen: Schnelle elementweise Array-Funktionen Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 97 -0.9337]) In [126]: y Out[126]: array([ 0.267 , -1.1131, -0.3361, -0.7147]) 0.6117, -1.2323, In [127]: np.maximum(x, y) # element-wise maximum Out[127]: array([ 0.267 , 0.0974, 0.2002, 0.6117, 0.4655, -0.7147]) 0.4788, 0.4315, 0.9222, 0.446 , Wenn auch weniger verbreitet, so kann eine ufunc auch mehrere Arrays abliefern. modf ist ein Beispiel dafür, eine vektorisierte Form der eingebauten Python-Funktion divmod: Sie liefert den gebrochenen und den ganzzahligen Teil eines Fließkomma-Arrays: In [128]: arr = np.random.randn(7) * 5 In [129]: np.modf(arr) Out[129]: (array([-0.6808, 0.0636, -0.386 , 0.1393, -0.8806, array([-2., 4., -3., 5., -3., 3., -6.])) 0.9363, -0.883 ]), Die verfügbaren ufuncs sind in Tabelle 4-3 und Tabelle 4-4 aufgeführt. Tabelle 4-3: Unäre ufuncs Funktion Beschreibung abs, fabs Berechnet elementweise den Absolutwert für ganzzahlige, Fließkomma- oder komplexe Werte. Benutzen Sie fabs als eine schnellere Variante für nicht komplexwertige Daten. sqrt Berechnet die Quadratwurzel jedes Elements. Entspricht arr ** 0.5. square Berechnet das Quadrat jedes Elements. Entspricht arr ** 2. exp Berechnet den Exponenten ex jedes Elements. log, log10, log2, log1p Natürlicher Logarithmus (Basis e), log Basis 10, log Basis 2 sowie log(1 + x). sign Berechnet das Signum jedes Elements: 1 (positiv), 0 (zero) oder -1 (negativ). ceil Rundet jedes Elements auf, also die kleinste ganze Zahl, die größer oder gleich dem Element ist. floor Rundet jedes Elements ab, also die größte ganze Zahl, die kleiner oder gleich dem Element ist. rint Rundet Elemente zur nächsten ganzen Zahl mit dem gleichen dtype. modf Gibt den gebrochenen und den ganzzahligen Anteil des Arrays als separate Arrays zurück. isnan Liefert ein boolesches Array, das die Werte anzeigt, die NaN (Not a Number) sind. isfinite, isinf Liefert ein boolesches Array, das die Werte anzeigt, die endlich (nicht-inf, nicht-NaN) bzw. unendlich sind. cos, cosh, sin, sinh, tan, tanh Reguläre und hyperbolische trigonometrische Funktionen. arccos, arccosh, arcsin, arcsinh, arctan, arctanh Inverse trigonometrische Funktionen. logical_not Berechnet elementweise den Wahrheitswert von not x. 98 | Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung Tabelle 4-4: Binäre universelle Funktionen Funktion Beschreibung add Addiert korrespondierende Elemente in Arrays. subtract Subtrahiert Elemente des zweiten Arrays vom ersten Array. multiply Multipliziert Array-Elemente. divide, floor_divide Dividieren oder floor-Dividieren (Abschneiden des Rests). power Nimmt die Elemente im ersten Array zum Exponenten im zweiten Array hoch. maximum, fmax Elementweises Maximum.fmax ignoriert NaN. minimum, fmin Elementweises Minimum.fmin ignoriert NaN. mod Elementweiser Modulus (Rest bei Division). copysign Kopiert die Vorzeichen im zweiten Argument in die Werte des ersten Arguments. greater, greater_equal, less, less_equal, equal, not_equal Führt elementweise Vergleiche durch, ergibt ein boolesches Array. Äquivalent zu diesen Infix-Operatoren: >, >=, <, <=, ==, != logical_and, logical_or, logical_xor Berechnet elementweise Wahrheitswerte der logischen Operationen. Äquivalent zu diesen Infix-Operatoren: & |, ^ Datenverarbeitung mit Arrays Mit NumPy-Arrays können Sie diverse Aufgaben der Datenbearbeitung als prägnante Array-Ausdrücke schreiben, die sonst viele Schleifen erfordern würden. Die Praxis, explizite Schleifen durch Ausdrücke mit Arrays zu ersetzen, nennt man auch Vektorisierung. Im Allgemeinen werden vektorisierte Array-Operationen ein bis zwei Größenordnungen (oder noch mehr) schneller sein als ihr reines Python-Äquivalent, dem weit größten Effekt bei jeder Art von numerischer Berechnung. Später in Kapitel 12 werde ich das Broadcasting erklären, ein mächtiges Hilfsmittel beim Vektorisieren von Berechnungen. Als ein einfaches Beispiel evaluieren wir die Funktion sqrt(x^2 + y^2) über ein reguläres Gitter von Werten. Die Funktion np.meshgrid nimmt zwei eindimensionale Arrays und produziert zwei zweidimensionale Matrizen, die zu allen Paaren von (x, y) in den zwei Arrays korrespondieren: In [130]: points = np.arange(-5, 5, 0.01) # 1000 equally spaced points In [131]: xs, ys = np.meshgrid(points, points) In [132]: ys Out[132]: array([[-5. , [-4.99, [-4.98, ..., [ 4.97, [ 4.98, [ 4.99, -5. , -5. , ..., -5. , -5. , -5. ], -4.99, -4.99, ..., -4.99, -4.99, -4.99], -4.98, -4.98, ..., -4.98, -4.98, -4.98], 4.97, 4.97, ..., 4.98, 4.98, ..., 4.99, 4.99, ..., 4.97, 4.97, 4.97], 4.98, 4.98, 4.98], 4.99, 4.99, 4.99]]) Datenverarbeitung mit Arrays Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 99 Zum Auswerten der Funktion bedarf es nun nichts weiter, als den gleichen Ausdruck zu schreiben, den Sie auch für nur zwei Punkte schreiben würden: In [134]: import matplotlib.pyplot as plt In [135]: z = np.sqrt(xs ** 2 + ys ** 2) In [136]: z Out[136]: array([[ 7.0711, [ 7.064 , [ 7.0569, ..., [ 7.0499, [ 7.0569, [ 7.064 , 7.064 , 7.0569, ..., 7.0569, 7.0499, ..., 7.0499, 7.0428, ..., 7.0499, 7.0569, 7.0428, 7.0499, 7.0357, 7.0428, 7.064 ], 7.0569], 7.0499], 7.0428, 7.0357, ..., 7.0499, 7.0428, ..., 7.0569, 7.0499, ..., 7.0286, 7.0357, 7.0357, 7.0428, 7.0428, 7.0499, 7.0428], 7.0499], 7.0569]]) In [137]: plt.imshow(z, cmap=plt.cm.gray); plt.colorbar() Out[137]: <matplotlib.colorbar.Colorbar instance at 0x4e46d40> In [138]: plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values") Out[138]: <matplotlib.text.Text at 0x4565790> Sehen Sie sich Abbildung 4-3 an. Hier habe ich die Funktion imshow aus matplotlib benutzt, um ein Bild des zweidimensionalen Arrays aus Funktionswerten zu plotten. Abbildung 4-3: Plot der Funktionsauswertung am Grid Konditionale Logik als Array-Operationen Die Funktion numpy.where ist eine vektorisierte Version des ternären Ausdrucks x if condition else y. Angenommen, wir hätten ein boolesches Array und zwei Arrays mit Werten: 100 | Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung In [140]: xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5]) In [141]: yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5]) In [142]: cond = np.array([True, False, True, True, False]) Wir wollen jetzt immer dann einen Wert von xarr nehmen, wenn der korrespondierende Wert in cond True ist, ansonsten den Wert aus yarr. Eine List-Comprehension, die das tut, sähe ungefähr so aus: In [143]: result = [(x if c else y) .....: for x, y, c in zip(xarr, yarr, cond)] In [144]: result Out[144]: [1.1000000000000001, 2.2000000000000002, 1.3, 1.3999999999999999, 2.5] Leider ist dieser Ansatz problematisch. Zunächst wird dies bei großen Arrays nicht sehr schnell sein, weil die ganze Arbeit in reinem Python geschieht. Des Weiteren wird es nicht mit mehrdimensionalen Arrays funktionieren. Mit np.where können Sie das jedoch sehr kurz schreiben: In [145]: result = np.where(cond, xarr, yarr) In [146]: result Out[146]: array([ 1.1, 2.2, 1.3, 1.4, 2.5]) Das zweite und das dritte Argument zu np.where müssen dabei keine Arrays sein, es sind Skalare erlaubt. Eine typische Anwendung von where in der Datenanalyse ist, ein neues Array basierend auf Werten in einem anderen Array zu erzeugen. Stellen Sie sich ein Array mit zufälligen Daten vor. Nun möchten Sie alle positiven Werte durch 2 und alle negativen durch –2 ersetzen. Das lässt sich sehr leicht mit np.where erreichen: In [147]: arr = np.random.randn(4, 4) In [148]: arr Out[148]: array([[ 0.6372, [-1.5926, [-0.1798, [ 0.5857, 2.2043, -1.1536, 0.3299, 0.1619, 1.7904, 0.0752], 0.4413, 0.3483], 0.7827, -0.7585], 1.3583, -1.3865]]) In [149]: np.where(arr > 0, 2, -2) Out[149]: array([[ 2, 2, 2, 2], [-2, -2, 2, 2], [-2, 2, 2, -2], [ 2, 2, 2, -2]]) In [150]: np.where(arr > 0, 2, arr) # set only positive values to 2 Out[150]: array([[ 2. , 2. , 2. , 2. ], [-1.5926, -1.1536, 2. , 2. ], [-0.1798, 2. , 2. , -0.7585], [ 2. , 2. , 2. , -1.3865]]) Datenverarbeitung mit Arrays Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 101 Die an where übergebenen Arrays können mehr sein als nur gleich große Arrays oder Skalare. Mit etwas Cleverness können Sie mit where auch weit komplexere Logik ausdrücken; hier habe ich zwei boolesche Arrays, cond1 und cond2, und möchte für jedes der vier möglichen Paare von booleschen Werten einen unterschiedlichen Wert zuweisen: result = [] for i in range(n): if cond1[i] and cond2[i]: result.append(0) elif cond1[i]: result.append(1) elif cond2[i]: result.append(2) else: result.append(3) Wenn auch nicht direkt offensichtlich, kann diese for-Schleife in einen geschachtelten where-Ausdruck verwandelt werden: np.where(cond1 & cond2, 0, np.where(cond1, 1, np.where(cond2, 2, 3))) In diesem Beispiel können wir obendrein noch einen Vorteil daraus ziehen, dass die booleschen Werte in Berechnungen als 0 oder 1 gehandhabt werden, und das könnte alternativ als eine arithmetische Operation ausgedrückt werden (wenngelich noch ein bisschen kryptischer): result = 1 * (cond1 & -cond2) + 2 * (cond2 & -cond1) + 3 * -(cond1 | cond2) Mathematische und statistische Methoden Eine Anzahl mathematischer Methoden, die Statistik über ein ganzes Array oder über die Daten entlang einer Achse berechnen, sind als Array-Methoden zugreifbar. Aggregationen (oftmals auch Reduktionen genannt) wie die Summe sum, der Mittelwert mean und die Standardabweichung std können entweder als Methoden der Array-Instanz oder auf oberster Ebene als NumPy-Funktion aufgerufen werden: In [151]: arr = np.random.randn(5, 4) # normally-distributed data In [152]: arr.mean() Out[152]: 0.062814911084854597 In [153]: np.mean(arr) Out[153]: 0.062814911084854597 In [154]: arr.sum() Out[154]: 1.2562982216970919 Funktionen wie mean und sum haben einen optionalen axis-Parameter, der es erlaubt, die Statistik entlang einer bestimmten Achse zu rechnen. In jedem Fall ergibt sich ein Array mit einer Dimension weniger: 102 | Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung In [155]: arr.mean(axis=1) Out[155]: array([-1.2833, 0.2844, 0.6574, 0.6743, -0.0187]) In [156]: arr.sum(0) Out[156]: array([-3.1003, -1.6189, 1.4044, 4.5712]) Andere Methoden wie cumsum und cumprod aggregieren nicht, sondern produzieren ein Array mit den Zwischenergebnissen: In [157]: arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) In [158]: arr.cumsum(0) Out[158]: array([[ 0, 1, 2], [ 3, 5, 7], [ 9, 12, 15]]) In [159]: Out[159]: array([[ [ [ arr.cumprod(1) 0, 0, 0], 3, 12, 60], 6, 42, 336]]) Bei Interesse bietet Tabelle 4-5 eine komplette Auflistung. In späteren Kapiteln werden wir noch viele Beispiele für diese Methoden in Aktion sehen. Tabelle 4-5: Elementare statistische Array-Methoden Methode Beschreibung sum Summe aller Elemente im Array oder entlang einer Achse. Arrays mit der Länge null haben die Summe 0. mean Arithmetischer Mittelwert. Arrays der Länge null haben NaN als Mittelwert. std, var Standardabweichung und Varianz mit optionaler Anpassung der Freiheitsgrade (Standardnenner n). min, max Minimum und Maximum. argmin, argmax Indizes der minimalen und maximalen Elemente. cumsum Kumulative Summe der Elemente, beginnend mit 0. cumprod Kumulatives Produkt der Elemente, beginnend mit 1. Methoden für boolesche Arrays Boolesche Werte werden in den obigen Methoden als 1 (True) und 0 (False) behandelt. Daher wird sum oft als eine Möglichkeit genutzt, die True-Werte in einem booleschen Array zu zählen: In [160]: arr = np.random.randn(100) In [161]: (arr > 0).sum() # Number of positive values Out[161]: 44 Zwei weitere Methoden, any und all, sind besonders geeignet für boolesche Arrays. any testet, ob wenigstens einer der Werte in einem Array True ist, während bei all alle Werte True sein müssen: In [162]: bools = np.array([False, False, True, False]) In [163]: bools.any() Out[163]: True Datenverarbeitung mit Arrays Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 103 In [164]: bools.all() Out[164]: False Diese Methoden funktionieren auch mit nicht booleschen Arrays, wobei jeder Wert ungleich 0 als True gezählt wird. Sortieren Wie Pythons eingebauter Listentyp haben auch die NumPy-Arrays eine sort-Methode, die die Werte an Ort und Stelle sortiert: In [165]: arr = np.random.randn(8) In [166]: arr Out[166]: array([ 0.6903, 0.4678, 0.0968, -0.1349, 0.9879, -0.5425]) 0.0185, -1.3147, In [167]: arr.sort() In [168]: arr Out[168]: array([-1.3147, -0.5425, -0.1349, 0.9879]) 0.0185, 0.0968, 0.4678, 0.6903, Bei mehrdimensionalen Arrays kann jeder eindimensionale Bereich an Ort und Stelle durch die Angabe der Achsennummer bei sort sortiert werden: In [169]: arr = np.random.randn(5, 3) In [170]: arr Out[170]: array([[-0.7139, [ 0.8236, [-1.6748, [-0.3161, [ 0.9058, -1.6331, -1.3132, 3.0336, 0.5362, 1.1184, -0.4959], -0.1935], -0.863 ], -2.468 ], -1.0516]]) In [171]: arr.sort(1) In [172]: arr Out[172]: array([[-1.6331, [-1.3132, [-1.6748, [-2.468 , [-1.0516, -0.7139, -0.1935, -0.863 , -0.3161, 0.9058, -0.4959], 0.8236], 3.0336], 0.5362], 1.1184]]) Die Methode np.sort produziert eine sortierte Kopie, anstatt das Array selbst zu ändern. Eine »Hauruckmethode« zum Berechnen der Quantile eines Arrays ist, es zu sortieren und dann die Werte an einem bestimmten Rang auszuwählen: In [173]: large_arr = np.random.randn(1000) In [174]: large_arr.sort() 104 | Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung In [175]: large_arr[int(0.05 * len(large_arr))] # 5% quantile Out[175]: -1.5791023260896004 Weitere Details zur Sortiermethode von NumPy und zu fortgeschritteneren Techniken wie indirekte Sortierung finden Sie in Kapitel 12. Ferner gibt es in pandas jede Menge weiterer Datenmanipulationen, die mit Sortieren zu tun haben (etwa Datentabellen nach einer oder mehreren Spalten zu sortieren). Unique und andere Mengenlogik NumPy besitzt einige elementare Mengenoperationen auf eindimensionalen Arrays. Vermutlich die am meisten verbreitete ist np.unique, die die sortierten eindeutigen Werte als Array zurückgibt: In [176]: names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe']) In [177]: np.unique(names) Out[177]: array(['Bob', 'Joe', 'Will'], dtype='|S4') In [178]: ints = np.array([3, 3, 3, 2, 2, 1, 1, 4, 4]) In [179]: np.unique(ints) Out[179]: array([1, 2, 3, 4]) Stellen Sie einmal np.unique der reinen Python-Alternative gegenüber: In [180]: sorted(set(names)) Out[180]: ['Bob', 'Joe', 'Will'] Eine andere Funktion namens np.in1d prüft das Vorhandensein der Werte des einen Arrays in einem anderen und liefert ein boolesches Array zurück: In [181]: values = np.array([6, 0, 0, 3, 2, 5, 6]) In [182]: np.in1d(values, [2, 3, 6]) Out[182]: array([ True, False, False, True, True, False, True], dtype=bool) In Tabelle 4-6 finden Sie eine Auflistung der Mengenfunktionen in NumPy. Tabelle 4-6: Mengenoperationen bei Arrays Methode Beschreibung unique(x) Berechnet und sortiert die eindeutigen Elemente in x. intersect1d(x, y) Berechnet und sortiert die gemeinsamen Elemente in x und y. union1d(x, y) Berechnet und sortiert die Vereinigung der Elemente. in1d(x, y) Berechnet ein boolesches Array, das für jedes Element vonx das Enthaltensein in y anzeigt. setdiff1d(x, y) Mengendifferenz, Elemente inx und nicht in y. setxor1d(x, y) Symmetrische Mengendifferenz; Elemente, die in einem der Arrays, aber nicht in beiden vorkommen. Datenverarbeitung mit Arrays Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 105 Dateiein- und -ausgabe bei Arrays NumPy ist in der Lage, Daten sowohl in Text- als auch Binärform auf die Platte zu laden und zu speichern. In den nachfolgenden Kapiteln werden Sie auch Werkzeuge zum Lesen tabellarischer Daten in den Speicher kennenlernen. Arrays im binären Format auf der Platte speichern np.save und np.load sind die zwei Arbeitspferde für effizientes Speichern und Laden von Array-Daten auf Platte. Arrays werden normalerweise in einem unkomprimierten rohen Format gespeichert mit der Endung .npy. In [183]: arr = np.arange(10) In [184]: np.save('some_array', arr) Wenn der Dateipfad nicht bereits auf .npy endet, wird diese Erweiterung angehängt. Das Array auf der Platte kann dann mit np.load geladen werden: In [185]: np.load('some_array.npy') Out[185]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) Sie können mit der Funktion np.savez mehrere Arrays in einem Zip-Archiv speichern, wobei Sie die Arrays als Schlüsselwortargumente angeben: In [186]: np.savez('array_archive.npz', a=arr, b=arr) Wenn Sie eine .npz-Datei laden, bekommen Sie ein Dictionary-ähnliches Objekt, das die einzelnen Arrays »lazy« (faul) lädt, also die Daten erst heranholt, wenn darauf zugegriffen wird: In [187]: arch = np.load('array_archive.npz') In [188]: arch['b'] Out[188]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) Speichern und Laden von Textdateien Das Laden von Text ist an sich keine besondere Aufgabe, aber die Fülle der Funktionen zum Lesen und Schreiben von Dateien in Python kann einen Anfänger schon ein wenig erschlagen. Deshalb möchte ich mein Augenmerk im Wesentlichen auf die Funktionen read_csv und read_table in pandas richten. Manchmal kann es von Nutzen sein, mit np.loadtxt oder dem spezialisierteren np.genfromtxt Daten direkt in NumPy-Arrays einzulesen. Diese Funktionen besitzen jede Menge Optionen, um verschiedene Trennzeichen, Umwandlungsfunktionen für verschiedene Spalten, Überspringen von Zeilen und vieles mehr anzugeben. Nehmen Sie einen einfachen Fall einer kommaseparierten Datei (CSV) wie dieser: 106 | Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung In [191]: !cat ch04/array_ex.txt 0.580052,0.186730,1.040717,1.134411 0.194163,-0.636917,-0.938659,0.124094 -0.126410,0.268607,-0.695724,0.047428 -1.484413,0.004176,-0.744203,0.005487 2.302869,0.200131,1.670238,-1.881090 -0.193230,1.047233,0.482803,0.960334 Diese kann folgendermaßen in ein zweidimensionales Array geladen werden: In [192]: arr = np.loadtxt('ch04/array_ex.txt', delimiter=',') In [193]: arr Out[193]: array([[ 0.5801, [ 0.1942, [-0.1264, [-1.4844, [ 2.3029, [-0.1932, 0.1867, -0.6369, 0.2686, 0.0042, 0.2001, 1.0472, 1.0407, 1.1344], -0.9387, 0.1241], -0.6957, 0.0474], -0.7442, 0.0055], 1.6702, -1.8811], 0.4828, 0.9603]]) np.savetxt führt die umgekehrte Operation aus: ein Array in eine begrenzte Textdatei zu schreiben. genfromtxt ist ähnlich wie loadtxt, aber mehr in Richtung strukturierter Daten und Behandlung fehlender Daten hochgezüchtet. In Kapitel 12finden Sie mehr über strukturierte Arrays. Mehr über das Lesen und Schreiben von Dateien, insbesondere tabellarischen oder arbeitsblattähnlichen Daten, finden Sie in späteren Kapiteln, die pandas und DataFrame-Objekte behandeln. Lineare Algebra Lineare Algebra, wie Matrizenmultiplikation, Dekomposition, Determinanten und andere Mathematik mit quadratischen Matrizen, ist ein wichtiger Teil jeder Array-Bibliothek. Anders als bei Sprachen wie MATLAB ist die Multiplikation zweier Matrizen mit * ein elementweises Produkt und kein Skalarprodukt von Matrizen. Dafür gibt es dot, sowohl eine Array-Methode als auch eine Funktion im Namensraum von numpy, für die Multiplikation von Matrizen: In [194]: x = np.array([[1., 2., 3.], [4., 5., 6.]]) In [195]: y = np.array([[6., 23.], [-1, 7], [8, 9]]) In [196]: x Out[196]: array([[ 1., [ 4., 2., 3.], 5., 6.]]) In [197]: y Out[197]: array([[ 6., [ -1., [ 8., 23.], 7.], 9.]]) In [198]: x.dot(y) # equivalently np.dot(x, y) Out[198]: array([[ 28., 64.], [ 67., 181.]]) Lineare Algebra Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 107 Ein Matrixprodukt zwischen einem zweidimensionalen Array und einem eindimensionalen Array passender Größe resultiert in einem eindimensionalen Array: In [199]: np.dot(x, np.ones(3)) Out[199]: array([ 6., 15.]) numpy.linalg besitzt einen Standardsatz an Funktionen zu Matrizenzerlegung, Invertie- rung, Determinanten und weiteren Dingen. Diese sind unter der Oberfläche mit den gleichen Fortran-Bibliotheken des Industriestandard implementiert wie in anderen Sprachen (etwa MATLAB und R). Vertreter sind BLAS, LAPACK oder auch (abhängig davon, wie Ihr NumPy kompiliert wurde) Intel MKL: In [201]: from numpy.linalg import inv, qr In [202]: X = np.random.randn(5, 5) In [203]: mat = X.T.dot(X) In [204]: inv(mat) Out[204]: array([[ 3.0361, -0.1808, [-0.1808, 0.5035, [-0.6878, 0.1215, [-2.8285, 0.6702, [-1.1911, 0.0956, -0.6878, -2.8285, -1.1911], 0.1215, 0.6702, 0.0956], 0.2904, 0.8081, 0.3049], 0.8081, 3.4152, 1.1557], 0.3049, 1.1557, 0.6051]]) In [205]: mat.dot(inv(mat)) Out[205]: array([[ 1., 0., 0., 0., [ 0., 1., -0., 0., [ 0., -0., 1., 0., [ 0., -0., -0., 1., [ 0., 0., 0., 0., -0.], 0.], 0.], -0.], 1.]]) In [206]: q, r = qr(mat) In [207]: r Out[207]: array([[ -6.9271, [ 0. , [ 0. , [ 0. , [ 0. , 7.389 , 6.1227, -7.1163, -3.9735, -0.8671, 2.9747, 0. , -10.2681, 1.8909, 0. , 0. , -1.2996, 0. , 0. , 0. , -4.9215], -5.7402], 1.6079], 3.3577], 0.5571]]) Tabelle 4-7 enthält eine Liste von häufig genutzten Funktionen für lineare Algebra. Die wissenschaftliche Python-Gemeinde hofft noch immer, dass eines Tages ein Infix-Operator für Matrixmultiplikation implementiert wird, sodass es eine syntaktisch schönere Schreibweise gibt als np.dot. Aber bis dahin gibt es nur diesen einen Weg. 108 | Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung Tabelle 4-7: Gebräuchliche Funktionen von numpy.linalg Funktion Beschreibung diag Selektiert die diagonalen (oder dazu versetzten) Elemente einer quadratischen Matrix als eindimensionales Array oder konvertiert ein eindimensionales Array in eine quadratische Matrix durch Füllen mit Nullen neben der Diagonalen. dot Matrixmultiplikation. trace Berechnet die Summe der diagonalen Elemente (die Spur). det Berechnet die Determinante. eig Berechnet die Eigenwerte und Eigenvektoren einer quadratischen Matrix. inv Berechnet die Inverse einer quadratischen Matrix. pinv Berechnet die Moore-Penrose-Pseudo-Inverse einer Matrix. qr Berechnet die QR-Dekomposition. svd Berechnet die Singular Value Dekomposition (SVD). solve Löst das lineare Gleichungssystem Ax = b in x, wobei A eine quadratische Matrix ist. lstsq Berechnet die Lösung der kleinsten Quadrate für Ax = b. Erzeugen von Zufallszahlen Das Modul numpy.random ergänzt das eingebaute Python-Modul random um Funktionen zum effizienten Generieren ganzer Arrays von Zufallszahlen nach einer Vielzahl von Wahrscheinlichkeitsverteilungen. Sie können zum Beispiel ein 4 x 4-Array von Zufallszahlen mit der Standard-Normalverteilung durch normal bekommen: In [208]: samples = np.random.normal(size=(4, 4)) In [209]: samples Out[209]: array([[ 0.1241, 0.3026, [ 1.3438, -0.7135, [-1.8608, -0.8608, [ 0.1198, -1.0635, 0.5238, 0.0009], -0.8312, -2.3702], 0.5601, -1.2659], 0.3329, -2.3594]]) Das in Python eingebaute Modul random hingegen generiert nur eine Stichprobe zur gleichen Zeit. Wie Sie in diesem Benchmark sehen können, ist numpy.random hier locker eine Größenordnung schneller beim Generieren sehr großer Stichproben: In [210]: from random import normalvariate In [211]: N = 1000000 In [212]: %timeit samples = [normalvariate(0, 1) for _ in xrange(N)] 1 loops, best of 3: 1.33 s per loop In [213]: %timeit np.random.normal(size=N) 10 loops, best of 3: 57.7 ms per loop Erzeugen von Zufallszahlen Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 109 In Tabelle 4-8 haben Sie eine unvollständige Liste der in numpy.random verfügbaren Funktionen. Im nächsten Abschnitt gebe ich einige Beispiele dafür, wie man sehr viele Stichproben am Stück generieren kann. Tabelle 4-8: Unvollständige Liste der Funktionen in numpy.random Funktion Beschreibung seed Setzt den Startwert des Zufallsgenerators. permutation Erzeugt eine zufällige Permutation einer Sequenz oder einen permutierten Bereich. shuffle Vermischt eine Sequenz an Ort und Stelle. rand Zieht Stichproben von einer Gleichverteilung. randint Zieht zufällige Ganzzahlen aus einem gegebenen Intervall. randn Zieht Stichproben aus einer Normalverteilung mit Mittelwert 0 und Standardabweichung 1 (Interface wie bei MATLAB). binomial Zieht Stichproben aus einer Binomialverteilung. normal Zieht Stichproben aus einer (Gaußschen) Normalverteilung. beta Zieht Stichproben aus einer Betaverteilung. chisquare Zieht Stichproben aus einer Chi-Quadrat-Verteilung. gamma Zieht Stichproben aus einer Gammaverteilung. uniform Zieht Stichproben aus einer [0, 1) Gleichverteilung. Beispiel: Random Walks Ein anschauliches Beispiel mit Operationen auf ganzen Array ist die Simulation von Random Walks, auch Irrfahrten genannt. Ziehen wir zunächst einen einfachen Random Walk in Betracht, der bei 0 anfängt und bei dem Schritte mit 1 oder 1 die gleiche Wahrscheinlichkeit haben. Ein 1.000 Schritte langer Random Walk in Python allein und mit eingebautem random-Modul sähe ungefähr so aus: import random position = 0 walk = [position] steps = 1000 for i in range(steps): step = 1 if random.randint(0, 1) else -1 position += step walk.append(position) In Abbildung 4-4 sehen Sie ein Plot der ersten 100 Schritte eines dieser Random Walks. 110 | Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung Abbildung 4-4: Eine einfache Irrfahrt Es mag Ihnen aufgefallen sein, dass walk nichts weiter ist als die kumulative Summe der zufälligen Schritte und dass es als Array-Ausdruck berechnet werden könnte. Gut, dann benutze ich jetzt das Modul np.random, um mit einem Schlag 1.000-mal eine Münze zu werfen, setze die Werte entsprechend auf 1 oder –1 und berechne die kumulative Summe: In [215]: nsteps = 1000 In [216]: draws = np.random.randint(0, 2, size=nsteps) In [217]: steps = np.where(draws > 0, 1, -1) In [218]: walk = steps.cumsum() Wir können jetzt anfangen, Statistiken zu berechnen wie das Minimum und Maximum entlang der Bahnkurve: In [219]: walk.min() Out[219]: -3 In [220]: walk.max() Out[220]: 31 Ein wenig komplizierter ist die Statistik der ersten Durchgangszeit, der Anzahl Schritte, bis der Random Walk einen bestimmten Wert erreicht. Hier wollen wir wissen, wie lange es dauert, bis die Irrfahrt wenigstens 10 Schritte vom Ausgangspunkt 0 entfernt ist, egal in welche Richtung. np.abs(walk) >= 10 erzeugt ein boolesches Array, wenn der Walk 10 erreicht oder überschreitet, wir möchten aber gern den Index der ersten 10 oder –10 wissen. Es stellt sich heraus, dass man es mit argmax berechnen kann, das den ersten Index des Maximalwerts im booleschen Array sucht (True ist der Maximalwert): In [221]: (np.abs(walk) >= 10).argmax() Out[221]: 37 Beispiel: Random Walks Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 111 Man beachte, dass argmax wie hier nicht immer die effizienteste Lösung ist, weil das immer ein volles Absuchen des Arrays bedeutet. In diesem speziellen Fall wissen wir ja schon beim ersten True, dass wir das Maximum erreicht haben. Simulation vieler Random Walks gleichzeitig Wäre es Ihr Ziel, viele Random Walks zu simulieren – sagen wir 5.000 Stück –, bräuchten Sie nur wenig zu verändern, um alle Ergebnisse gleichzeitig zu berechnen. Wenn die Funktion numpy.random ein 2er-Tupel für den Parameter size bekommt, generiert sie ein zweidimensionales Array aus Ziehungen, und wir können die kumulative Summe über die Zeilen berechnen, um alle 5.000 Random Walks auf einen Schuss zu bekommen: In [222]: nwalks = 5000 In [223]: nsteps = 1000 In [224]: draws = np.random.randint(0, 2, size=(nwalks, nsteps)) # 0 or 1 In [225]: steps = np.where(draws > 0, 1, -1) In [226]: walks = steps.cumsum(1) In [227]: walks Out[227]: array([[ 1, 0, 1, ..., 8, 7, [ 1, 0, -1, ..., 34, 33, [ 1, 0, -1, ..., 4, 5, ..., [ 1, 2, 1, ..., 24, 25, [ 1, 2, 3, ..., 14, 13, [ -1, -2, -3, ..., -24, -23, 8], 32], 4], 26], 14], -22]]) Wir können nun die maximalen und minimalen Werte über alle diese Walks berechnen: In [228]: walks.max() Out[228]: 138 In [229]: walks.min() Out[229]: -133 Lassen Sie uns nun aus diesen Walks die erste Durchgangszeit für 30 oder –30 berechnen. Das ist ein wenig trickreich, weil nicht alle 5.000 Walks bis zur 30 kommen. Wir können das vorher abprüfen mittels der Methode any: In [230]: hits30 = (np.abs(walks) >= 30).any(1) In [231]: hits30 Out[231]: array([False, True, False, ..., False, True, False], dtype=bool) In [232]: hits30.sum() # Number that hit 30 or -30 Out[232]: 3410 Mit diesem booleschen Array können wir jetzt die Zeilen aus walks nehmen, die tatsächlich den absoluten Abstand von 30 erreichen, um dann mit argmax über Achse 1 die Durchgangszeiten zu erhalten: 112 | Kapitel 4: Grundlagen von NumPy: Arrays und vektorisierte Berechnung In [233]: crossing_times = (np.abs(walks[hits30]) >= 30).argmax(1) In [234]: crossing_times.mean() Out[234]: 498.88973607038122 Probieren Sie ruhig noch ein wenig mit anderen Verteilungen herum als nur mit den gleichverteilten Münzwürfen. Sie brauchen lediglich einen anderen Zufallszahlengenerator, etwas wie die Funktion normal, die Normalverteilungen mit einstellbarem Mittelwert und Standardabweichung erzeugt: In [235]: steps = np.random.normal(loc=0, scale=0.25, .....: size=(nwalks, nsteps)) Beispiel: Random Walks Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 | 113 Index Symbole !-Zeichen 62, 65 != (Operator) 93 !cmd-Befehl 61 # (Nummernzeichen) 402 $PATH-Variable 9 %-Zeichen 412 %A, datetime-Format 303 %a, datetime-Format 303 %alias, magische Funktion 62 %automagic, magische Funktion 55 %b, datetime-Format 303 %B, datetime-Format 303 %bookmark, magische Funktion 61, 63 %c, datetime-Format 303 %cd, magische Funktion 61 %cpaste, magische Funktion 52, 56 %d (Formatierungszeichen) 412 %D, datetime-Format 303 %d, datetime-Format 302 %debug, magische Funktion 54–55, 64 %dhist magische Funktion 61 %dirs, magische Funktion 61 %env, magische Funktion 61 %F, datetime-Format 303 %gui, magische Funktion 58 %H, datetime-Format 302 %hist, magische Funktion 55, 60 %I, datetime-Format 302 %lprun, magische Funktion 71, 73 %M, datetime-Format 302 %m, datetime-Format 302 %magic, magische Funktion 55 %p, datetime-Format 303 %page, magische Funktion 56 %paste, magische Funktion 52, 55 %pdb, magische Funktion 54, 64 %popd, magische Funktion 61 %prun, magische Funktion 56, 72 %pushd, magische Funktion 61 %pwd, magische Funktion 61 %quickref, magische Funktion 55 %reset, magische Funktion 56, 60 %run, magische Funktion 50–51, 56, 400 %s (Formatierungszeichen) 412 %S, datetime-Format 302 %time, magische Funktion 56, 68–69 %timeit, magische Funktion 54, 68–69 %U, datetime-Format 302 %w, datetime-Format 302 %W, datetime-Format 303 %who magische Funktion 56 %who_ls, magische Funktion 56 %whos, magische Funktion 56 %X, datetime-Format 303 %x, datetime-Format 303 %xdel, magische Funktion 56, 60 %xmode, magische Funktion 54 %Y, datetime-Format 302 %y, datetime-Format 302 %z, datetime-Format 303 & (Operator) 93 >>>, Prompt 400 * (Operator) 107 + (Operator) 421, 423 == (Operator) 407 ? (Fragezeichen) 49 [] (Klammern) 422 \ (Backslash) 411 {} (Klammern) 428 | (Operator) 93 _ (Unterstrich) 48, 60 _ _ (zwei Unterstriche) 60 A a (Dateimodus) 446 Abgrenzungsformate 169, 171 abs-Funktion 98 accumulate-Methode 383 | 449 Achsen Beschriftungen für 234–235 Broadcasting über 379, 381 Indizes umbenennen 205 verketten entlang 191, 194 vertauschen in Arrays 96–97 Achsenindizes umbenennen 205 add-Methode 97, 134, 432 add_patch-Methode 238 add_subplot-Methode 229–230 aggfunc-Argument 287 aggregate-Methode 270, 272 Aggregation von Daten 270, 275 Daten in nicht indizierter Schreibweise ausgeben 274–275 mehrere Funktionen verwenden 272, 274 Aggregationen 102 all-Methode 103, 383 alpha-Parameter 243 Analyse von Quantilen 279–280 Analyse von Quartilen 356, 358 Analyse von Signalfronten 358, 360 and, Schlüsselwort 412, 415 Annotation in matplotlib 237, 239 Anonyme Funktionen 439 Anordnung von Arrays im Speicher 371 Anwendungen aus der Finanzwelt Analyse von Signalfronten 358, 360 Datenklempnerei 341, 352 asof-Methode 347–348 Daten kombinieren 349–350 für spezielle Frequenzen 344, 346 zum Ausrichten von Daten 342–343 gruppieren von 353, 358 Analyse von Quartilen 356, 358 Faktorenanalyse mit 355–356 kumulative Rentabilität 351–352 lineare Regression 363, 365 Performanzindizes 351–352 rollieren von Terminkontrakten 361, 363 rollierende Korrelation 363, 365 any-Methode 103, 112, 209 append-Methode 126, 423 apply-Methode 39, 137, 147, 276, 279–280 Apt, Paketverwaltungswerkzeug 8 arange-Funktion 84–85 Arbeitsverzeichnis des gegenwärtigen Systems, Rückgabe 61 wechseln ins übergebene Verzeichnis 61 arccos-Funktion 98 450 | arccosh-Funktion 98 arcsin-Funktion 98 arcsinh-Funktion 98 arctan-Funktion 98 arctanh-Funktion 98 argmax-Methode 103 argmin-Methode 103, 143 argsort-Methode 139, 389 Arithmetik 132, 136 mit Füllwerten 134 Operationen zwischen DataFrame und Series 135–136 Arrays Achsen vertauschen in 96–97 aufspalten 372, 374 boolesche Arrays 103–104 boolesches Indizieren für 92, 94 Dateiein- und -ausgabe bei 106–107 im binären Format auf der Platte speichern 106 Speichern und Laden von Textdateien 106–107 Datentypen für 85, 87 Elemente in einem sortierten Array finden 391–392 Erstellen eines PerioIndex aus 322 erzeugen 83–84 Fancy Indexing 94, 96 in NumPy 369, 376 aufspalten 372, 374 c_-Objekt 373–374 r_-Objekt 373–374 replizieren 374–375 Speicheraufteilung 371 speichern in Dateien 393, 395 umformen 369, 371 Untermengen von 375–376 verketten 372, 374 Indizes für 88, 92 konditionale Logik als Operation 100, 102 Operationen zwischen 87–88 replizieren 374–375 Slicing 88, 92 sortieren 104–105 statistische Methoden für 102–103 strukturierte Arrays 385, 387 manipulieren 387 verschachtelte Datentypen 385–386 Vorteile von 386–387 transponieren 96–97 Index Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 unique-Funktion 105 Werte durch Broadcasting setzen 381 where-Funktion 100, 102 arrow-Funktion 237 as, Schlüsselwort 407 asarray-Funktion 85, 393 asfreq-Methode 318, 329 asof-Methode 347–348 astype-Methode 87 Attribute die mit Unterstrich beginnen 48 in Python 405 Auffüllen von fehlenden Daten 150–151 Ausführungszeit einzelner Anweisungen 56 von Code 56 Ausgabevariablen 59–60 Ausnahmen Behandlung in Python 417–418 Debugger automatisch nach 55 Definition 417 Ausreißer filtern 208, 210 average-Methode 140 ax-Parameter 243 AxesSubplot-Objekt 230 axis-Argument 194 axis-Option 142 B b (Dateimodus) 446 Backslash (\) 411 Balkendiagramme 244, 248 Basemap-Objekt 256 .bash_profile-Datei 8 .bashrc-Datei 9 bbox_inches-Parameter 240 Befehle Chronik bei IPython 58, 61 Ein- und Ausgabevariablen 59–60 Wiederverwenden von Befehlen in der Chronik 59 Debugger 66 Historie in IPython protokollieren von 60–61 suchen nach 53 Befehlsergänzung in IPython 47–48 Beispiel der US-Babynamen von 1880 bis 2010 31, 43 Revolution des letzten Buchstabens 40, 42 Wachstum der Vielfalt messen 37, 40 Bereich (span) 335 beta-Funktion 110 Definition 355 between_time-Methode 348 bfill-Methode 127 Bibliotheken 4, 7 IPython 6 matplotlib 5–6 NumPy 4 pandas 5 SciPy 6–7 Bildschirminhalt, löschen 53 Bildschirminhalt-löschen-Kürzel 53 Binäre Datenformate 177, 179 HDF5 178–179 Microsoft Excel-Dateien 179 Binäre Funktionen mit gleitendem Fenster 336 Binäre universelle Funktionen 99 Binäres Datenformat Arrays speichern auf 106 Binärsuche in Listen 424–425 Binden Variablen 440 Definition 403 binomial-Funktion 110 bisect-Modul 424–425 Boolesch Arrays 103–104 Datentyp 86, 412–413 indizieren von Arrays 92, 94 bottleneck-Bibliothek 334 break, Schlüsselwort 416 Broadcasting 377, 381 Definition 88, 374, 377 über andere Achsen 379, 381 Werte von Arrays setzen durch 381 C c_-Objekt 373–374 calendar-Modul 300 Casting 86 cat-Kommando 163 cat-Methode 220 Categorical-Objekt 206 ceil-Funktion 98 center-Methode 220 Chaco 258 chisquare-Funktion 110 Chronik der Befehle, suchen 53 chunksize-Parameter 166–167 Index | 451 clock-Funktion 68 close-Methode 228, 447 Closures 439, 441 cmd.exe 7 Code unterbrechen 50–51, 53 collections-Modul 430 cols-Argument 287 column_stack-Funktion 373 combine_first-Methode 183, 196 comment-Parameter 166 compile-Methode 216 concat-Funktion 33, 183, 190, 192, 277, 372–373 contains-Methode 220 continue, Schlüsselwort 415 convention-Parameter 324 copy-Argument 188 copy-Methode 122 copysign-Funktion 99 corr-Methode 145 corrwith-Methode 145 cos-Funktion 98 cosh-Funktion 98 count-Methode 143, 214, 220, 271, 422 Counter-Klasse 19 cov-Methode 145 crosstab-Funktion 288 Crowdsourcing 252 CSV-Dateien 169, 171, 252 Ctrl-a, Tastaturkürzel 53 Ctrl-b, Tastaturkürzel 53 Ctrl-c, Tastaturkürzel 53 Ctrl-e, Tastaturkürzel 53 Ctrl-f, Tastaturkürzel 53 Ctrl-k, Tastaturkürzel 53 Ctrl-n, Tastaturkürzel 53 Ctrl-p, Tastaturkürzel 53 Ctrl-r, Tastaturkürzel 53 Ctrl-Shift-v, Tastaturkürzel 53 Ctrl-u, Tastenkürzel 53 cummax-Methode 144 cummin-Methode 144 cumprod-Methode 103, 144 cumsum-Methode 103, 144 Currying 442 Cursor, mit Tastatur bewegen 53 cut-Funktion 206–208, 279, 294 Cython-Projekt 3, 397–398 452 | D DataFrame, Datenstruktur 20, 25, 116, 119, 124 arithmetische Operationen zwischen Series und 135–136 Daten verknüpfen mit 184, 187 Dateiein- und -ausgabe bei Arrays 106–107 im binären Format auf der Platte speichern 106 Speichern und Laden von Textdateien 106–107 binäre Datenformate für 177, 179 HDF5 178–179 Microsoft Excel-Dateien 179 Diagramm in einer Datei abspeichern 239–240 für Arrays HDF5 395 Memory-mapped Dateien 394–395 in Python 445, 447 mit Datenbanken 180 mit Web-APIs 179–180 Textdateien 161, 177 Abgrenzungsformate 169, 171 HTML-Dateien 172, 177 JSON-Daten 171–172 lesen in Stücken 166, 168 lxml-Bibliothek 172, 177 schreiben in 168–169 XML-Dateien 175, 177 Daten ausrichten 342–343 Daten pivotisieren Kreuztabellen 288 pivot_table-Methode 28, 285, 288 Daten transponieren definiert 196 pivot-Methode 198, 200 Daten verknüpfen 183, 196 über Index 188, 190 überlappende Daten zusammenführen 195–196 verketten entlang einer Achse 191, 194 Datenaufbereitung DataFrames verknüpfen 184, 187 Daten verknüpfen 183, 196 DataFrames verknüpfen 184, 187 über Index 188, 190 überlappende Daten zusammenführen 195–196 verketten entlang einer Achse 191, 194 Index Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 Fallstudie USDA-Nahrungsmitteldatenbank 220, 225 Manipulation von Strings 213, 219 Methoden für 213–214 mit regulären Ausdrücken 215, 218 vektorisierte String-Methoden 218–219 Transformieren von Daten 201, 212 Achsenindizes umbenennen 205 Ausreißer filtern 208, 210 Diskretisierung 206, 208 Löschen doppelter Einträge 201–202 Mapping 202–203 Permutation 210 Platzhaltervariablen 211–212 Werte ersetzen 203–204 transponieren 198, 200 umformen 196, 198 Datenausrichtung 132, 136 arithmetische Methoden mit Füllwerten 134 Operationen zwischen DataFrame und Series 135–136 Datenbanken 313 lesen und schreiben einer 180 Datenbeispiel: die Erdbebenkrise auf Haiti 252, 257 Datenklempnerei 341, 352 asof-Methode 347–348 Daten kombinieren 349–350 für spezielle Frequenzen 344, 346 zum Ausrichten von Daten 342–343 Datenstruktur DataFrame hierarchisches Indizieren mit 155–156 Datenstruktur von Indexobjekten 124, 126 Datenstruktur, Series arithmetische Operationen zwischen DataFrame und 135–136 Datenstrukturen von pandas 116, 126 DataFrame 119, 124 Indexobjekte 124, 126 Panel 158–159 Series 116, 119 Datentyp complex128 86 Datentyp complex256 86 Datentyp complex64 86 Datentyp float 85 Datentyp float128 86 Datentyp float16 86 Datentyp float32 86 Datentyp float64 86 Datentyp int 85 Datentyp int16 86 Datentyp int32 86 Datentyp int64 86 Datentyp int8 86 Datentyp uint16 86 Datentyp uint32 86 Datentyp uint64 86 Datentyp uint8 86 Datentypen für Arrays 85, 87 für ndarray 85, 87 für NumPy 367, 369 für Python bool-Datentyp 412–413 Datum und Uhrzeit 414 None-Datentyp 413 numerische Datentypen 409–410 str-Datentyp 410, 412 Typumwandlungen in 413 für Zeitreihen 300, 303 konvertieren von Strings und datetime 301, 303 in NumPy Hierarchie von 368–369 in Python 409, 414 verschachtelte 385–386 Datum für die Woche eines Monats 311 Datum und Uhrzeit (siehe auch Zeitreihen) date_parser-Parameter 166 date_range-Funktion 308 Datentypen für 300 datetime-Typ 301, 303, 409, 414 DatetimeIndex-Objekt 125 dateutil-Paket 301 Datum und Uhrzeit für 414 Datumsbereiche 308–309 Datumsbereiche date_range-Funktion 308 dayfirst-Parameter 166 debug-Funktion 67 Debugger, IPython in IPython 64, 68 def, Schlüsselwort 435 del, Schlüsselwort 60 del-Anweisung 122, 429 delete-Methode 126 describe-Methode 143, 253, 278 Designtipps 76, 78 besiege die Furcht vor langen Dateien 77–78 flach ist besser als verschachtelt 77 Index | 453 relevante Objekte und Daten am Leben erhalten 77 det-Funktion 109 diag-Funktion 109 Dichteplots 248–249 Dictionaries 428, 431 Dict Comprehensions 432, 434 erzeugen 429 gruppieren nach 267–268 Schlüssel von 431 voreingestellte Werte für 430 zurückgeben der Umgebungsvariablen des Systems 61 diff-Methode 126, 144 difference-Methode 432 digitize-Funktion 392 Diskretisierung 206, 208 div-Methode 135 divide-Funktion 99 Doppelpunkte 401 dot-Funktion 107–108, 392 doublequote-Option 171 Downsampling 323 dpi-Parameter (dots per inch) 240 dreload-Funktion 76 drop-Methode 126, 129 drop_duplicates-Methode 201 dropna-Methode 148 dsplit-Funktion 373 dstack-Funktion 373 dtype-Objekt (siehe Datentypen) Duck-Typing in Python 405–406 dumps, Funktion 172 duplicated-Methode 201 Duplikate Einträge löschen 201–202 Indizes 306–307 Dynamisch generierte Funktionen 439 F E Ebenen Definition 152 gruppieren nach 269 sortieren 154–155 zusammenfassende Statistik nach 155 edgecolor-Parameter 240 edit-compile-run-Arbeitsablauf 45 eig-Funktion 109 Eigene Universalfunktionen 384–385 454 Einfügen magischer Befehl zum 56 Tastenkürzel zum 53 Eingabevariablen 59–60 Einrückung in Python 401–402 IndentationError-Event 51 elif-Blöcke (siehe if-Anweisung) else-Block (siehe if-Anweisung) empty-Funktion 84–85 encoding-Parameter 166 endswith-Methode 214, 220 Entwicklungswerkzeuge in IPython 63, 73 Debugger 64, 68 Laufzeitmessung 68–69 Profiling von Code 69, 71 zeilenweises Profiling einer Funktion 71, 73 enumerate-Funktion 426 equal-Funktion 99 Erste Durchgangszeit 111 Erzeugen von Zufallszahlen 109–110 escapechar-Option 171 ewma-Funktion 334 ewmcorr-Funktion 334 ewmcov-Funktion 334 ewmstd-Funktion 334 ewmvar-Funktion 334 ExcelFile-Klasse 179 except-Block 417 execute-explore-Arbeitsablauf 45 exit-Befehl 400 exp-Funktion 98 Exponentiell gewichtete Funktionen 334–335 extend-Methode 423–424 Extensible Markup Language-(XML-)Dateien 175, 177 eye-Funktion 85 | fabs-Funktion 98 facecolor-Parameter 240 Factor-Objekt 279 Faktoren 355 Faktorenanalyse 355–356 Fallstudie: USDA-Nahrungsmitteldatenbank (US Department of Agriculture) 220, 225 Fallstudie: Die Datenbank des US-Bundeswahlausschusses von 2012 288, 297 Spenden der Größe nach klassifizieren 294, 296 Index Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 Spendenstatistik nach Beruf und Arbeitgeber 291, 293 Spendenstatistik nach Bundesstaat 296–297 Fancy Indexing Definition 375 für Arrays 94, 96 Fehlende Daten 147, 151 auffüllen von 150–151, 280–281 ausfiltern 148–149 ffill-Methode 127 figsize-Argument 244 Figure-Objekt 229, 231 fill_method-Parameter 324 fill_value-Argument 287 fillna-Methode 20, 148, 150–151, 203, 280, 328 Filtern Ausreißer 208, 210 fehlende Daten 148–149 in pandas 130, 132 find-Methode 214–215 findall-Methode 173, 216, 218, 220 finditer-Method 218 finditer-Methode 218 first-Methode 140, 271 Flach ist besser als verschachtelt 77 float-Datentyp 368, 409–410, 413 float-Funktion 417 floor-Funktion 98 floor_divide-Funktion 99 flush-Methode 447 Flusskontrolle 415, 420 for-Schleifen 415–416 if-Anweisung 415 pass-Anweisung 416 range-Funktion 418–419 ternäre Ausdrücke 419–420 while-Schleifen 416 fmax-Funktion 99 fmin-Funktion 99 fname-Parameter 240 for-Schleifen 87, 102, 415–416, 432, 434 format-Parameter 240 Fragezeichen (?) 49 Frequenzen 309, 311 Datum für die Woche eines Monats 311 konvertieren 318–319 spezielle Frequenzen 344, 346 from_csv-Methode 169 frompyfunc-Funktion 384 functools-Modul 442 Funktionen 402–403, 434, 445 anonyme Funktionen 439 Closures 439, 441 Currying von 442 erweiterte Syntax von Aufrufen für 441 Gültigkeitsbereich von 435–436 lambda-Funktionen 439 mehrere Rückgabewerte aus 436–437 Namensräume für 435–436 parsen in pandas 161 sind Objekte 437–438 Funktionen für Sequenzen 426, 428 enumerate-Funktion 426 reversed-Funktion 428 sorted-Funktion 427 zip-Funktion 427–428 Funktionen mit gleitenden Fenstern 332, 337 benutzerdefiniert 337 binäre Funktionen mit gleitendem Fenster 336 exponentiell gewichtete Funktionen 334–335 G gamma-Funktion 110 Generatoren 442, 445 Definition 443 Generator-Ausdrücke 444 itertools-Modul für 444–445 Gestapeltes Format 198 get-Methode 173, 179, 220, 430 get_chunk-Methode 168 get_dummies-Funktion 211–212 get_value-Methode 132 get_xlim-Methode 234 getattr-Funktion 405 GIL (Global Interpreter Iock) 4 Globaler Gültigkeitsbereich 435–436 .gov-Domain 16 Grafik Chaco 258 mayavi 259 Granger, Brian 74 greater-Funktion 99 greater_equal-Funktion 99 Grenzen von Klassen 324 grid-Argument 243 groupby-Methode 39, 262, 269, 307, 326, 355–356, 392, 444 auf Spalte 267 Iteration über Gruppen 265–266 Index | 455 mit Dictionaries 267–268 mit Series 267–268 nach Stufen 269 Resampling mit 326–327 verwenden von Funktionen mit 269 Gruppenschlüssel 279 Gruppieren Aggregation von Daten 270, 275 Daten in nicht indizierter Schreibweise ausgeben 274–275 mehrere Funktionen verwenden 272, 274 Analyse von Quantilen mit 279–280 apply-Methode 276, 279 Fallstudie: Die Datenbank des US-Bundeswahlausschusses von 2012 288, 297 Spenden der Größe nach klassifizieren 294, 296 Spendenstatistik nach Beruf und Arbeitgeber 291, 293 Spendenstatistik nach Bundesstaat 296–297 fehlende Daten mit gruppenspezifischen Werten auffüllen 280–281 für Anwendungen aus der Finanzwelt 353, 358 Analyse von Quartilen 356, 358 Faktorenanalyse mit 355–356 gewichteter Mittelwert für Gruppen 283–284 groupby-Methode 262, 269 auf Spalte 267 Iteration über Gruppen 265–266 mit Dictionaries 267–268 mit Series 267–268 nach Stufen 269 verwenden von Funktionen mit 269 lineare Regression für 285 Pivot-Tabellen 285, 288 Kreuztabellen 288 zufällige Stichproben mit 281–282 Gültigkeitsbereich 435–436 H Halb geöffnet 324 hasattr-Funktion 405 hashability 431 HDF5 (hierarchisches Datenformat) 178–179, 395 HDFStore-Klasse 178 header-Parameter 166 heapsort-Sortiermethode 390 456 | Hierarchisches Datenformat (HDF5) 178–179, 395 Hierarchisches Indizieren Daten umformen mit 196, 198 in pandas 152, 156 Ebenen sortieren 154–155 mit Spalten eines DataFrame 155–156 zusammenfassende Statistik nach Ebene 155 hist-Methode 248 Histogramme 248–249 Homogener Datencontainer 385 how-Argument 187 how-Parameter 324, 326 hsplit-Funktion 373 hstack-Funktion 372 HTML Notebook in IPython 74–75 HTML-Dateien 172, 177 Hunter, John D. 5, 227 Hyperbolische trigonometrische Funktionen 98 I icol-Methode 132, 157 IDEs (integrierte Entwicklungsumgebungen) 52 idxmax-Methode 142 idxmin-Methode 142 if-Anweisung 415, 430 iget_value-Methode 157 ignore_index-Argument 195 import-Direktive in Python 406–407 Importanweisung Benutzung der, in diesem Buch 11 imshow-Funktion 100 in, Schlüsselwort 423 In-Place-Sortierung 387 in1d-Methode 105 index-Methode 214–215 index_col-Parameter 166 Indirektes Sortieren 388, 390 Indizes Daten verknüpfen mit 188, 190 Definition 116 für Achse 205 für Arrays 88, 92 für die Klasse TimeSeries 304, 306 hierarchisches Indizieren 152, 156 Daten umformen mit 196, 198 Ebenen sortieren 154–155 Index Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 mit Spalten eines DataFrame 155–156 zusammenfassende Statistik nach Ebene 155 in pandas 140–141 Integer-Indizierung 157 insert-Methode 126, 422–423 insort-Methode 424 int-Datentyp 409, 413 Int64Index-Objekt 125 Integer-Arrays, Indexing (siehe Fancy Indexing) Integer-Indizierung 157 Integrierte Entwicklungsumgebungen (IDEs) 9–10, 52 Interpretierte Sprachen Definition 400 Python-Interpreter 400 intersect1d-Methode 105 intersection-Methode 126, 432 Introspektion 48–49 inv-Funktion 109 Inverse trigonometrische Funktionen 98 .ipynb-Dateien 75 IPython 6 Befehlschronik 58, 61 in Ein- und Ausgabevariablen 59–60 Wiederverwenden von Befehlen in der Chronik 59 Befehlsergänzung in 47–48 Befehlshistorie in protokollieren von 60–61 benötigte Module erneut laden 76 Code aus der Zwischenablage ausführen 51–52 Designtipps 76, 78 besiege die Furcht vor langen Dateien 77–78 flach ist besser als verschachtelt 77 relevante Objekte und Daten am Leben erhalten 77 Entwicklungswerkzeuge 63, 73 Debugger 64, 68 Laufzeitmessung 68–69 Profiling von Code 69, 71 zeilenweises Profiling einer Funktion 71, 73 HTML Notebook in 74–75 Integration mit IDEs und Editoren 52 Integration mit matplotlib 57–58 Introspektion von Objekten in 48–49 korrekte Ausgabe von Klassen 78 Lesezeichen für Verzeichnisse 63 magische Befehle bei 54–55 Profile für 79–80 Qt-Konsole für 56 %run-Befehl in 50–51 Schnellübersicht zu 55 Shell-Befehle in 62–63 Tastaturkürzel in 53 Tracebacks bei 53–54 ipython_config.py-Datei 79 irow-Methode 132, 157 is, Schlüsselwort 407 is_monotonic-Methode 126 is_unique-Methode 126 isdisjoint-Methode 432 isfinite-Funktion 98 isin-Methode 146–147 isinf-Funktion 98 isinstance-Funktion 405 isnull-Methode 98, 118, 148 issubdtype-Funktion 368 issubset-Methode 432 issuperset-Methode 432 iter-Funktion 406 Iteration über Gruppen 265–266 iterator-Parameter 166 Iterator-Protokoll 405, 442 itertools-Modul 444–445 ix_-Funktion 96 J join-Methode 190, 214, 220 JSON (JavaScript Object Notation) 16, 171–172, 221 K KDE-Plots (Kernel Density Estimate) 248 keep_date_col-Parameter 166 Keine Zahl (NaN) 103, 118 Kernels 248 KeyboardInterrupt-Event 50 Keys-Parameter 195 keys-Methode 429 Keyword-Argumente 403, 435 kind-Parameter 243, 324 Klammern ([]) 420, 422 Klammern ({}) 428 Klassifizieren 294, 296 Kleister für Code Python als 3 Index | 457 Kombinieren Datenquellen 349–350 Listen 423–424 Kommentare in Python 402 Konditionale Logik als Array-Operation 100, 102 Konferenzen 10 Kontinuierliche Rentabilität 361 Kontrollfluss Behandlung von Ausnahmen 417–418 Konvertieren von Strings und datetime 301, 303 Zeitstempel zu Perioden 321–322 Koordinierte Weltzeit (UTC) 313 Korrelation 144–145 Kovarianz 144–145 Kumulative Rentabilität 351–352 kurt-Methode 144 Kürzel, Tastatur 53 in IPython 53 zum Löschen von Text 53 L label-Argument 325 label-Parameter 243, 324 lambda-Funktionen 218, 273, 439 Lange Dateien, die Furcht besiegen vor 77–78 Langes Format 198 last-Methode 271 Lästige Spalte 265 Laufzeitmessung 68–69 Leerer Namensraum 50 Leerzeichen, Code strukturieren mit 401–402 left_index-Argument 188 left_on-Argument 187 Legenden in matplotlib 236–237 Leistung von NumPy 395, 398 Cython-Projekt 397–398 zusammenhängender Speicher 396–397 len-Funktion 220, 269 Lesen von Datenbanken 180 von Textdateien in Stücken 166, 168 Lesezeichen für Verzeichnisse in IPython setzen 63 less-Funktion 99 less_equal-Funktion 99 level-Argument 269 458 | Lexikalisches Sortieren Definition 389 lexsort-Methode 389 limit-Parameter 324 linalg-Funktion 108 line_profiler, Erweiterung 72 Lineare Algebra 107–108 Lineare Regression 285, 363, 365 lineterminator-Option 171 Liniendiagramme 241, 244 Linkes Argument 187 Linux, installieren auf 8–9 List Comprehensions 432, 434 verschachtelte 433–434 list-Funktion 422 Listen 422, 426 Binärsuche von 424–425 Einfügen in sortierte 424–425 Elemente aus Listen entfernen 422–423 Elemente hinzufügen zu 422–423 kombinieren 423–424 List Comprehensions 432, 434 Slicing 425–426 sortieren 424 ljust-Methode 215 load-Funktion 106, 393 load-Methode 177 loads-Funktion 16 loffset-Parameter 324, 326 log-Funktion 98 log1p-Funktion 98 log2-Funktion 98 logical_and-Funktion 99 logical_not-Funktion 98 logical_or-Funktion 99 logical_xor-Funktion 99 logy-Parameter 243 Lokaler Gültigkeitsbereich 435 Lokalisieren von Zeitreihen 314, 316 long-Datentyp 409 lower-Methode 215, 220 lstrip-Methode 215, 220 lstsq-Funktion 109 lxml-Bibliothek 172, 177 M mad-Methode 144 Magische Methoden 48, 54–55 main-Funktion 77 Manipulieren von strukturierten Arrays 387 Index Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 map-Methode 137, 202–203, 218, 290, 438 margins 285 Markierungen 147, 165, 233 match-Methode 216, 220 matplotlib 5–6, 228, 241 Achsenbeschriftung in 234–235 Annotation in 237, 239 integrieren mit IPython 57–58 konfigurieren 240–241 Legenden in 236–237 Skalenstriche in 234–235 speichern in Dateien 239–240 Stile für 232–233 Subplots in 229, 232 Titel in 234–235 matplotlibrc-Datei 241 Matrixoperationen in NumPy 392–393 max-Methode 103, 140, 143, 271, 443 maximum-Funktion 97, 99 mayavi 259 mean-Methode 102, 143, 263, 270–271, 275 median-Methode 144, 271 Mehrere Profile 79 memmap-Objekt 394 Memory-mapped Dateien Arrays in einer Datei speichern 394–395 Definition 394 mergesort-Sortiermethode 390 meshgrid-Funktion 99 Methode astype 86 Methoden Definition 403 die mit Unterstrich beginnen 48 für Tupel 422 in Python 402–403 Microsoft Excel-Dateien 179 .mil-Domain 16 min-Methode 103, 140, 143, 271, 443 minimum-Funktion 99 Mittelwert über ein expandierendes Fenster 333 mod-Funktion 99 modf-Funktion 98 Module 406 MovieLens 1M, Datensatzbeispiel 25, 31 mro-Methode 368 mul-Methode 135 MultiIndex-Objekt 125, 152, 154 multiply-Funktion 99 munging 12 N n:1-Verknüpfung 184 n:n-Verknüpfung 185 NA-Datentyp 148 na_values-Parameter 166 Namensgebungstendenzen am Beispiel der US-Babynamen von 1880 bis 2010 36, 43 Jungennamen, die Mädchennamen wurden 42–43 Revolution des letzten Buchstabens 40, 42 Namensräume Definition 435 in Python 435–436 Namenstendenzen am Beispiel der US-Babynamen von 1880 bis 2010 Wachstumssteigerung der Vielfalt messen 37, 40 names-Argument 195 names-Parameter 166 NaN (Not a Number) 103, 118, 147 ncols-Parameter 231 ndarray 82 Achsen vertauschen in 96–97 boolesches Indizieren 92, 94 Datentypen für 85, 87 Erzeugen von Arrays 83–84 Fancy Indexing 94, 96 Indizes für 88, 92 Operationen zwischen Arrays 87–88 Slicing von Arrays 88, 92 transponieren 96–97 New York MTA (Metropolitan Transportation Authority) 175 None-Datentyp 409, 413 normal-Funktion 110, 113 Normalisierte Zeitstempel 309 Not a Number (NaN) 147 not_equal-Funktion 99 NotebookCloud 75 notnull-Methode 118, 148 .npy-Dateien 106 .npz-Dateien 106 nrows-Parameter 166, 231 Numerische Datentypen 409–410 Nummernzeichen (#) 402 NumPy 4 Arrays in 369, 376 Anordnung im Speicher 371 Index | 459 aufspalten 372, 374 c_-Objekt 373–374 r_-Objekt 373–374 replizieren 374–375 speichern in Dateien 393, 395 umformen 369, 371 Untermengen von 375–376 verketten 372, 374 Broadcasting 377, 381 über andere Achsen 379, 381 Werte von Arrays setzen durch 381 Dateiein- und -ausgabe bei Arrays 106–107 im binären Format auf Platte speichern 106 Speichern und Laden von Textdateien 106–107 Datenbearbeitung mit Arrays 99, 105 Arrays sortieren 104–105 konditionale Logik als Array-Operation 100, 102 Methoden für boolesche Arrays 103–104 statistische Methoden 102–103 unique-Funktion 105 where-Funktion 100, 102 Datentypen für 367, 369 Erzeugen von Zufallszahlen 109–110 Leistung von 395, 398 Cython-Projekt 397–398 zusammenhängender Speicher 396–397 lineare Algebra 107–108 Matrixoperationen in 392–393 ndarray-Arrays 82 Achsen vertauschen in 96–97 boolesches Indizieren 92, 94 Datentypen für 85, 87 Erzeugen 83–84 Fancy Indexing 94, 96 Indizes für 88, 92 Operationen zwischen Arrays 87–88 Slicing von Arrays 88, 92 transponieren 96–97 numpy-Diskussion (Mailingliste) 10 Random Walks-Beispiel 110, 113 Sortieren 387, 392 Algorithmen zum 390 Elemente in einem sortierten Array finden 391–392 indirektes 388, 390 460 | strukturierte Arrays in 385, 387 manipulieren 387 verschachtelte Datentypen 385–386 Vorteile von 386–387 universelle Funktionen für 97–98, 382, 385 in pandas 136–137 Instanzmethoden für 382, 384 Nur-Lese-Modus 446 Nur-Schreib-Modus 446 O objectify-Funktion 172, 175 Objektmodell 402 objs-Argument 194 Offsets auf Zeitreihen 312–313 OHLC-(Open-High-Low-Close-)Resampling 326 ols-Funktion 365 on-Argument 187 ones-Funktion 85 open-Funktion 445 Open-High-Low-Close-(OHLC-)Resampling 326 Operatoren in Python 407 or, Schlüsselwort 415 order-Methode 390 OS X, Python installieren auf 8 outer-Methode 383–384 P Paarplots 251 pad-Methode 220 pandas 5 Arithmetik und Datenausrichtung 132, 136 arithmetische Methoden mit Füllwerten 134 Operationen zwischen DataFrame und Series 135–136 Behandlung fehlender Daten 147, 151 auffüllen von 150–151 ausfiltern 148–149 Datenstrukturen von 116, 126 DataFrame 119, 124 Indexobjekte 124, 126 Panel 158–159 Series 116, 119 drop-Funktion 129 filtern in 130, 132 hierarchisches Indizieren in 152, 156 Ebenen sortieren 154–155 Index Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 mit Spalten eines DataFrame 155–156 zusammenfassende Statistik nach Ebene 155 Indizes in 140–141 Integer-Indizierung 157 Optionen beim Indizieren 130, 132 Plotten mit 241 Balkendiagramme 244, 248 Dichteplots 248–249 Histogramme 248–249 Liniendiagramme 241, 244 Scatterplots 250–251 Rangbildung in 138, 140 Reduktionen in 141, 147 reindex-Funktion 126, 129 Selektieren innerhalb von Objekten 130, 132 Sortieren in 138, 140 universelle Funktionen von NumPy mit 136–137 USA.gov-Daten von bit.ly, Beispiel mit 19, 25 zusammenfassende Statistik in isin-Methode 146–147 Korrelation und Kovarianz 144–145 unique-Funktion 146–147 value_counts-Funktion 146–147 Panel, Datenstruktur 158–159, 341 parse-Methode 301 parse_dates-Parameter 166 partial-Funktion 442 Partielles Indizieren 152 pass-Anweisung 416 patches 238 path-Parameter 166 Path-Variable 8 pct_change-Methode 144 pdb, Debugger 63–64 .pdf-Dateien 240 percentileofscore-Funktion 337 Pérez, Fernando 45, 227 Period-Klasse 317 period_range-Funktion 318, 320 Perioden 317, 322 anstelle von Zeitstempeln 346 Definition 299, 317 Erstellen eines PerioIndex aus Arrays 322 quartalsweise Perioden 320 Resampling mit 328, 330 Umwandlung der Frequenzen von 318–319 Zeitstempel konvertieren zu 321–322 PeriodIndex-Objekt 125, 321–322 Permutation 210 pickle, Serialisierung 176 pinv-Funktion 109 pivot_table-Aggregationstyp 286 .pkg-Datei 8 Platzhaltervariablen 211–212 plot-Methode 21, 36, 42, 228, 232–233, 241, 248, 256, 330 Plotten Datenbeispiel: die Erdbebenkrise auf Haiti 252, 257 mit matplotlib 228, 241 Achsenbeschriftung in 234–235 Annotation in 237, 239 konfigurieren 240–241 Legenden in 236–237 Speichern in Dateien 239–240 Stile für 232–233 Subplots in 229, 232 ticks in 234–235 Titel in 234–235 mit pandas 241 Balkendiagramme 244, 248 Dichteplots 248–249 Histogramme 248–249 Liniendiagramme 241, 244 Scatterplots 250–251 Zeitreihen 330, 332 .png-Dateien 240 pop-Methode 423, 429 Positionelle Argumente 403 power-Funktion 99 pprint-Modul 78 pretty printing definiert 47 und seitenweise Darstellung 56 Private Attribute 48 Private Methoden 48 prod-Methode 271 Profile Definition 79 für IPython 79–80 profile_default-Verzeichnis 79 Profiling von Code in IPython 69, 71 Protokollieren der Befehlshistorie in IPython 60–61 Pseudocode 12 put-Funktion 376 put-Methode 376 Index | 461 .py-Dateien 51, 400, 406 .py-Files 406 pydata (Google Group) 10 Pylab-Modus 228 pymongo-Treiber 181 pyplot-Modul 228 pystatsmodels (Mailingliste) 10 Python Dateiein- und -ausgabe in 445, 447 Datentypen 409, 414 bool-Datentyp 412–413 Datum und Uhrzeit 414 None-Datentyp 413 numerische Datentypen 409–410 str-Datentyp 410, 412 Typumwandlungen in 413 Dict Comprehensions in 432, 434 Dictionaries in 428, 431 erzeugen 429 Schlüssel von 431 voreingestellte Werte für 430 Flusskontrolle in 415, 420 for-Schleifen 415–416 if-Anweisung 415 pass-Anweisung 416 range-Funktion 418–419 ternäre Ausdrücke 419–420 while-Schleifen 416 Funktionen für Sequenzen in 426, 428 enumerate-Funktion 426 reversed-Funktion 428 sorted-Funktion 427 zip-Funktion 427–428 Funktionen in 434, 445 anonyme Funktionen 439 Closures 439, 441 Currying von 442 erweiterte Syntax von Aufrufen für 441 Gültigkeitsbereich von 435–436 lambda-Funktionen 439 mehrere Rückgabewerte aus 436–437 Namensräume für 435–436 sind Objekte 437–438 Generatoren in 442, 445 Generator-Ausdrücke 444 itertools-Modul für 444–445 installieren 7, 10 auf Linux 8–9 462 | auf OS X 8 auf Windows 7–8 integrierte Entwicklungsumgebungen für 9–10 Interpreter für 400 Kontrollfluss in Behandlung von Ausnahmen 417–418 List Comprehensions in 432, 434 Listen in 422, 426 Binärsuche von 424–425 einfügen in sortierte 424–425 Elemente aus Listen entfernen 422–423 Elemente zu Listen hinzufügen 422–423 kombinieren 423–424 Slicing 425–426 sortieren 424 notwendige Bibliotheken 4, 7 IPython 6 matplotlib 5–6 NumPy 4 pandas 5 SciPy 6–7 Python 2 vs. Python 3 9 Semantik von 401, 409 Attribute in 405 Duck-Typing 405–406 Einrückung 401–402 Funktionen in 402–403 import-Direktive 406–407 Kommentare in 402 Methoden in 402–403 Objektmodell 402 Operatoren für 407 Referenzen in 403–404 stark typisierte Sprache 404–405 strikte Evaluation 408 Variablen in 403–404 veränderbare Objekte in 408–409 Set Comprehensions in 432, 434 Sets in 431–432 Tupel in 420, 422 entpacken 421–422 Methoden für 422 Vorteile der Nutzung 2, 4 Das »Zwei-Sprachen-Problem« lösen mithilfe von 3 Kleister für Code 3 pytz-Bibliothek 313–314 Index Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 Q qcut-Funktion 207–208, 279–280, 356 qr-Funktion 109 Qt-Konsole für IPython 56 Quartalsweise Perioden 320 Quellen 10 Querschnitt 341 quicksort-Sortiermethode 390 quotechar-Option 171 quoting-Option 171 R r (Dateimodus) 446 r+ (Dateimodus) 446 r_-Objekt 373–374 Ramachandran, Prabhu 259 rand-Funktion 110 randint-Funktion 110, 210 randn-Funktion 92, 110 Random Walks-Beispiel 110, 113 Rangbildung von Daten Definition 139 in pandas 138, 140 range-Funktion 84, 418–419 ravel-Methode 370–371 rc-Methode 240 re-Modul 215 read-Methode 447 read_clipboard-Funktion 161 read_csv-Funktion 106, 161, 167, 169, 272, 445 read_frame-Funktion 181 read_fwf-Funktion 161 read_table-Funktion 106, 161, 164, 169 readline-Funktionalität 59 readlines-Methode 447 readshapefile-Methode 257 recfunctions-Modul 387 Rechengeschwindigkeit und Zeitreihen 338–339 Rechtes Argument 187 reduce-Methode 382, 384 reduceat-Methode 383 Reduktionen (siehe auch Aggregationen) Definition 141 in pandas 141, 147 Referenzen Definition 403–404 in Python 403–404 Referenzübergabe 404 regress-Funktion 285 Reguläre Ausdrücke (regex) definiert 215 Manipulation von Strings mit 215, 218 reindex-Methode 126, 129, 328, 344 reload-Funktion 76 remove-Methode 423, 432 rename-Methode 205 Rentabilität Definition 351 kumulative Rentabilität 351–352 Performanzindizes 351–352 repeat-Methode 220, 374 replace-Methode 203, 214, 220 Resampling 323, 330, 344 Definition 323 mit der groupby-Methode 326–327 mit Perioden 328, 330 OHLC-(Open-High-Low-Close-)Resampling 326 Upsampling 327–328 reset_index-Funktion 156 reshape-Methode 196, 198, 369, 380 return-Befehl 435 reversed-Funktion 428 rfind-Methode 215 right_index-Argument 188 right_on-Argument 188 rint-Funktion 98 rjust-Methode 215 rollback-Methode 313 rollforward-Methode 313 Rollieren 361 Rollieren von Terminkontrakten 361, 363 Rollierende Korrelation 363, 365 rolling_apply-Funktion 334, 337 rolling_corr-Funktion 334, 363 rolling_count-Funktion 334 rolling_cov-Funktion 334 rolling_kurt-Funktion 334 rolling_mean-Funktion 332–334 rolling_median-Funktion 334 rolling_min-Funktion 334 rolling_mint-Funktion 334 rolling_quantile-Funktion 334, 337 rolling_skew-Funktion 334 rolling_std-Funktion 334 rolling_sum-Funktion 334 rolling_var-Funktion 334 rot-Argument 243 row_stack-Funktion 373 Index | 463 rows-Argument 287 rstrip-Methode 215, 220 S save-Funktion 106, 393 save-Methode 177 savefig-Methode 239–240 savez-Funktion 106 scatter-Methode 250 scatter_matrix-Funktion 251 Scatterplots 250–251 Schlüssel von Dictionaries 431 Schlüssel-Wert-Paare 428 Schlüsselwort exec 60 Schreiben in Datenbanken 180 in Textdateien 168–169 SciPy 6–7 scipy-user (Mailingliste) 10 search-Methode 216, 218 searchsorted-Methode 391 seed-Funktion 110 seek-Methode 447 Semantik 401, 409 Attribute in 405 Duck-Typing 405–406 Einrückung 401–402 Funktionen in 402–403 import-Direktive 406–407 Kommentare in 402 Methoden in 402–403 Objektmodell 402 Operatoren für 407 Referenzen in 403–404 stark typisierte Sprache 404–405 strikte Evaluation 408 Variablen in 403–404 veränderbare Objekte in 408–409 Semikola 402 sep-Parameter 166 Series-Datenstruktur 116, 119 gruppieren mit 267–268 Set Comprehensions 432, 434 set-Funktion 431 set_index-Funktion 156 set_index-Methode 156, 200 set_title-Methode 235 set_trace-Funktion 67 set_value-Methode 132 464 | set_xlabel-Methode 235 set_xlim-Methode 234 set_xticklabels-Methode 235 set_xticks-Methode 235 setattr-Funktion 405 setdefault-Methode 430 setdiff1d-Methode 105 Sets/Set Comprehensions 431–432 setxor1d-Methode 105 Shapefiles 256 Shapes 83, 367 sharex-Argument 244 sharex-Parameter 231 sharey-Argument 244 sharey-Parameter 231 Shell-Befehle in IPython 62–63 shuffle-Funktion 110 sign-Funktion 98, 210 sin-unktion 98 sinh-Funktion 98 size-Methode 265 Skalenstriche 234–235 skew-Methode 144 skip_footer-Parameter 166 skipinitialspace-Option 171 skipna-Option 142 skiprows-Parameter 166 Skripte 2 Skriptsprachen 2 slice-Methode 220 Slicing Arrays 88, 92 Listen 425–426 solve-Funktion 109 sort-Argument 188 sort-Methode 104, 387–388, 424, 439 sort_columns-Argument 244 sort_index-Methode 138, 155, 390 sorted-Funktion 427 Sortieralgorithmen 390 Sortieren Arrays 104–105 Ebenen 154–155 Elemente in einem sortierten Array finden 391–392 in NumPy 387, 392 Algorithmen zum 390 Elemente in einem sortierten Array finden 391–392 indirektes Sortieren 388, 390 Index Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 in pandas 138, 140 Listen 424 sortlevel-Funktion 155 Sozialversicherungsverwaltung (Social Security Administration, SSA) 31 Spalten, gruppieren auf 267 Speicher, Anordnung von Arrays im 371 Speichern von Textdateien 106–107 Spendenstatistik nach Beruf und Arbeitgeber 291, 293 nach Bundesstaat 296–297 Spezielle Frequenzen Datenklempnerei für 344, 346 split-apply-combine 262 split-Methode 171, 213, 218, 220, 373 SQL-Datenbanken 181 sql-Modul 181 SQLite-Datenbanken 180 sqrt-Funktion 97–98 square-Funktion 98 squeeze-Parameter 166 SSA (Social Security Administration) 31 Stabiles Sortieren 390 Standardeinstellungen Profile 79 Stark typisierte Sprache 404–405 start-Index 425 startswith-Methode 214, 220 Statistische Methoden 102–103 std-Methode 103, 144, 271 stdout 168 step-Index 425 Stile für matplotlib 232–233 stop-Index 425 strftime-Methode 301, 414 strided View 367 Strikte Evaluation/Sprache 408 Strings Datentypen für 86, 410, 412 konvertieren zu datetime 301, 303 Manipulation 213, 219 Methoden für 213–214 mit regulären Ausdrücken 215, 218 vektorisierte String-Methoden 218–219 strip-Methode 215, 220 strptime-Methode 301, 414 structs 385 Strukturierte Arrays 385, 387 Definition 385 manipulieren 387 verschachtelte Datentypen 385–386 Vorteile von 386–387 style-Parameter 243 sub-Methode 134, 217 subn-Methode 218 subplot_kw-Parameter 231 Subplots 229, 232 subplots-Methode 231 subplots_adjust-Methode 231 subtract-Funktion 99 suffixes-Argument 188 sum-Methode 102, 137, 142–143, 270–271, 342, 443 svd-Funktion 109 swapaxes-Methode 97 swaplevel-Funktion 154 symmetric_difference-Methode 432 Syntaktischer Zucker 12 Systembefehle, Alias definieren für 61 T Tabulatoren, Code strukturieren mit 401–402 take-Methode 210, 376 tan-Funktion 98 tanh-Funktion 98 Tastaturkürzel 53 in IPython 53 zum Löschen von Text 53 tell-Methode 447 Terminkontrakte 361 Terminologie 12–12 Ternäre Ausdrücke 419–420 text_content-Methode 173 Textdateien 161, 177 Abgrenzungsformate 169, 171 HTML-Dateien 172, 177 JSON-Daten 171–172 lesen in Stücken 166, 168 lxml-Bibliothek 172, 177 Schreiben in 168–169 speichern und laden 106–107 XML-Dateien 175, 177 Texteditoren, mit IPython integrieren 52 TextParser-Klasse 166, 168, 174 thousands-Parameter 166 thresh-Parameter 149 tile-Funktion 374–375 Titel in matplotlib 234–235 to_csv-Methode 168–169 to_datetime-Methode 301 Index | 465 to_panel-Methode 159 to_period-Methode 321 top-Methode 277, 293 trace-Funktion 109 Tracebacks 53–54 transform-Methode 275–276 Transformieren von Daten 201, 212 Achsenindizes umbenennen 205 Ausreißer filtern 208, 210 Diskretisierung 206, 208 Löschen doppelter Einträge 201–202 Mapping 202–203 Permutation 210 Platzhaltervariablen 211–212 Werte ersetzen 203–204 transpose-Methode 96 trellis-Paket 258 Trigonometrische Funktionen 98 truncate-Methode 306 try/except-Block 417–418 Tupel 420, 422 entpacken 421–422 Methoden für 422 Typ object 86 Typ Unicode 86 type-Kommando 163 TypeError-Ereignis 87, 417 Typen 402 Typumwandlungen 413 tz_convert-Methode 315 tz_localize-Methode 314–315 U U (Dateimodus) 446 Überperiode 329 Umformen Arrays 369, 371 definiert 196 mit hierarchischer Indizierung 196, 198 Umgebungsvariablen 8, 61 Unäre Funktionen 97 Unicode-Typ 17 uniform-Funktion 110 union-Methode 105, 126, 212, 432 unique-Methode 105, 126, 146–147, 290 Universelle Funktionen 97–98, 382, 385 eigene 384–385 in pandas 136–137 Instanzmethoden für 382, 384 Universeller Zeilenumbruchmodus 446 466 | unstack-Funktion 153 Untermengen von Arrays 375–376 Unterperiode 329 Unterstrich (_) 48, 60 update-Methode 350 upper-Methode 215, 220 Upsampling 323, 327–328 US-Babynamen von 1880 bis 2010, Beispiel Jungennamen, die Mädchennamen wurden 42–43 USA.gov-Daten von bit.ly, Beispiel 16, 25 use_index-Argument 243 UTC (Coordinated Universal Time) 313 V value_counts-Methode 146–147 ValueError-Ereignis 417 values-Methode 429 var-Methode 103, 144, 271 Variablen (siehe auch Umgebungsvariablen) Anzeigen der 56 in Python 403–404 löschen 56 Varoquaux, Gaël 259 vectorize-Funktion 384 Vektorisierte String-Methoden 218–219 Vektorisierung 87 Definition 99 Veränderbare Objekte 408–409 verbose-Parameter 166 Verflachen 370 verify_integrity-Argument 195 Verketten Arrays 372, 374 entlang einer Achse 191, 194 Verschachtelte Datentypen 385–386 Verschachtelte List Comprehensions 433–434 Verschachtelter Code 77 Verschieben von Zeitreihen 311, 313 Verzeichnisse Lesezeichen in IPython 63 wechseln, Befehle für 61 Views 88, 122 Visualisierungstools Chaco 258 mayavi 259 Voreinstellungen Werte für Dictionaries 430 Vorteile von Python 2, 4 Index Wes McKinney, Datenanalyse mit Python, O´Reilly, ISBN 978-3-96009-000-7 Das »Zwei-Sprachen-Problem« lösen mithilfe von 3 Kleister für Code 3 von strukturierten Arrays 386–387 vsplit-Funktion 373 vstack-Funktion 372 W w (Dateimodus) 446 Wattenberg, Laura 40 Web-APIs, Dateiein- und -ausgabe mit 179–180 wenn-Ausdrücke 408 where-Funktion 100, 102, 195 while-Schleifen 416 Wickham, Hadley 262 Williams, Ashley 220 Windows, Python installieren auf 7–8 write-Methode 446 writelines-Methode 446 writer-Methode 171 X xlim-Methode 234 XML-(Extensible Markup Language-)Dateien 175, 177 xs-Methode 132 xticklabels-Methode 234 Y yield, Schlüsselwort 443 ylim-Argument 243 yticks-Argument 243 Z Zeitintervalle 299 Zeitreihen Datentypen für 300, 303 Konvertieren von Strings und datetime 301, 303 Datumsbereiche 308–309 Frequenzen 309, 311 Datum für die Woche eines Monats 311 Funktionen mit gleitenden Fenstern 332, 337 benutzerdefiniert 337 binäre Funktionen mit gleitendem Fenster 336 exponentiell gewichtete Funktionen 334–335 Lokalisieren von Objekten 314, 316 Perioden 317, 322 Erstellen eines PerioIndex aus Arrays 322 quartalsweise Perioden 320 Umwandlung der Frequenzen von 318–319 Zeitstempel konvertieren zu 321–322 plotten 330, 332 Resampling 323, 330 mit der groupby-Methode 326–327 mit Perioden 328, 330 OHLC-(Open-High-Low-Close-)Resampling 326 Upsampling 327–328 TimeSeries-Klasse 303, 307 Auswählen von Daten in 304, 306 doppelte Indizes mit 306–307 Indizes für 304, 306 und Rechengeschwindigkeit 338–339 Verschieben von 311, 313 mit Offsets 312–313 Zeitzonen in 313, 317 Methoden für Objekte mit zugeordneter Zeitzone 316–317 Zeitstempel Definition 299 konvertieren zu Perioden 321–322 Verwenden von Perioden anstelle von 346 zeros-Funktion 85 zip-Funktion 427–428 Zufällige Stichproben mit Gruppierung 281–282 Zusammenfassende Statistik 141 isin-Funktion 146–147 Korrelation und Kovarianz 144–145 nach Ebene 155 unique-Funktion 146–147 value_counts-Funktion 146–147 Zusammenführen Datenquellen, überlappende 195–196 Zusammenhängender Speicher 396–397 »Zwei-Sprachen-Problem« 3 Zwischenablage, Code ausführen aus der 51–52 Zwischenräume um Subplots 231–232 Index | 467