Datenanalyse I

Python hat u.a. einen sehr guten Ruf als Programmiersprache für die Datenanalyse. Das liegt unter anderem an diesen Bibliotheken:

  • ipython
  • numpy
  • pandas
  • scipy
  • scikit.learn
  • matlpotlib

Wir werden uns dieser Sitzung vor allem numpy ansehen und in den nachfolgenden Sitzungen die anderen Bibliotheken.

ipython

Sie benutzen ja schon ipython notebooks. ipython ist außerdem eine sehr viel komfortablere shell als idle. Schon allein das tab-completion (erste Buchstaben des Kommandos eingeben, dann auf Tab) ist sehr nützlich.

Nützliche Kommandos:
%hist - Zeigt die history an, also alle bisher eingegebenen Befehle. Mit %hist -g "dir" suchen Sie nach allen Befehlszeilen, die den String dir enthalten.
%cd dir - wechselt ins Directory dir

numpy

numpy ist ein Modul, dass vor allem eine sehr effiziente und schnelle Datenstruktur zur Verfügung stellt sowie eine ganze Reihe von Funktionen, um die Daten zu bearbeiten oder auszuwerten. Die Datenstruktur, die im Zentrum steht, ist ein Array, also eine Art Liste. In der einfachsten Form können wir Arrays so ähnlich wie Python-Listen verwenden:


In [1]:
#übliche Art und Weise numpy zu importieren
import numpy as np
a = np.array([1,2,3,4,5])
a


Out[1]:
array([1, 2, 3, 4, 5])

Auch bei arrays greifen wir über den Index auf die Elemente zu:


In [2]:
a[3]


Out[2]:
4

numpy-arrays unterscheiden sich in einigen Punkten sehr deutlich von Pythons eingebauter Liste:

  • numpy Arrays haben bei der Erzeugung eine festgelegte Größe. Verändert man das Array wird eine neue Kopie angelegt und die alte verworfen.
  • Alle Elemente des Arrays müssen denselben Datentyp haben.
  • numpy Arrays sind dazu ausgelegt, mehrdimensional verwendet zu werden:
  • 
    
    In [3]:
    type(a)
    
    
    
    
    Out[3]:
    numpy.ndarray

    nd steht für n-dimensional

    
    
    In [4]:
    #wir erzeugen einen zweidimensionalen Array
    b = np.array([[1,2,3],[4,5,6]])
    b
    
    
    
    
    Out[4]:
    array([[1, 2, 3],
           [4, 5, 6]])

    Im folgenden werde ich anstatt von 1-dimensionalen Arrays auch von Vektoren sprechen und einen mehrdimensionalen Array als Matrix bezeichnen. Das sind mathematische Konzepte, die später noch ausführlicher erläutert werden.

    Erzeugen von numpy-Arrays

    Es gibt mehrere Wege, wie man numpy-Arrays erzeugen kann:

    1) Aus einer Python-Datenstruktur, z.B. einer Liste (wie oben) oder einem Tuple:

    
    
    In [5]:
    x = np.array((1, 3, 6, 7.1, 8.55, 2.94))
    x
    
    
    
    
    Out[5]:
    array([ 1.  ,  3.  ,  6.  ,  7.1 ,  8.55,  2.94])

    2) Von einer Datei lesen, z.B. im HDF5 or FITS-format oder von csv-Dateien, deren Lesen von Pythons Standardbibliothek unterstützt wird,

    
    
    In [6]:
    #schauen wir uns die Datei einmal mit Python's Bordmitteln an:
    import csv
    with open('inutzung.csv') as f:
        reader = csv.reader(f)
        for l in reader:
            print(l)
    
    
    
    
    ['Alter', '2008', '2010', '2011', '2012', '2013']
    ['10-15', '93', '96', '96', '97', '98']
    ['16-24', '96', '98', '99', '99', '99']
    ['25-44', '90', '95', '96', '98', '98']
    ['45-64', '67', '71', '75', '82', '84']
    ['65+', '14', '23', '22', '26', '32']
    
    
    
    In [7]:
    #und so laden wir sie in numpy:
    data = np.genfromtxt("inutzung.csv", delimiter=",", skiprows=1, usecols=(range(1,6)))
    data
    
    
    
    
    Out[7]:
    array([[ 93.,  96.,  96.,  97.,  98.],
           [ 96.,  98.,  99.,  99.,  99.],
           [ 90.,  95.,  96.,  98.,  98.],
           [ 67.,  71.,  75.,  82.,  84.],
           [ 14.,  23.,  22.,  26.,  32.]])

    Die Parameter:
    delimiter - Welches Zeichen trennt die Felder einer Reihe in der csv-Datei
    skiprows - Welche Zeilen übersprungen werden sollen, falls die Datei wie hier Kolumnentitel enthält
    usecols - Welche Spalten sollen verwendet werden. Kann man weglassen, wenn alles geladen werden soll. Hier können wir die erste nicht gebrauchen.

    Gestalt eines Arrays

    Ein Array hat soviele Achsen wie er Dimensionen hat. Bei manchen Operationen werden wir die Information, welche Achse nun behandelt werden soll, angeben müssen. Hier das Beispiel eines zweidimensionalen Arrays:

    Unter 'Form' der Matrix versteht man die Anzahl der Zellen in die jeweilige Richtung der Achse. Die Form kann man mit dem Befehl shape abfragen:

    
    
    In [89]:
    a
    
    
    
    
    Out[89]:
    [6, 6, 6, 6]
    
    
    In [93]:
    np.shape(a)
    
    
    
    
    Out[93]:
    (4,)
    
    
    In [108]:
    b = np.array([[38,19,35,32, 41], [39,22,22,33,34], [28,34,28,17,45], [12,23,49,13,22]])
    
    
    
    In [109]:
    b
    
    
    
    
    Out[109]:
    array([[38, 19, 35, 32, 41],
           [39, 22, 22, 33, 34],
           [28, 34, 28, 17, 45],
           [12, 23, 49, 13, 22]])
    
    
    In [94]:
    np.shape(b)
    
    
    
    
    Out[94]:
    (4, 5)

    Bei einem Vektor erhalten wir nur eine Zahl, die die Länge des Vektors anzeigt. Im Fall einer Matrix erhalten wir n Zahlen, wobei n der Anzahl der Dimensionen der Matrix entspricht.

    Aufgaben

    1) Erzeugen Sie einen Vektor mit den Zahlen von 0-5 und fragen Sie seine Form ab.
    2) Erzeugen Sie einen numpy-Array, der mit den Zahlen von 1-12 gefüllt ist und die Form 4x3 hat.

    Indexing und Slicing

    Wir können jedes Element eines numpy-Arrays ebenso adressieren wie bei einer python-Liste:

    
    
    In [8]:
    a = np.array([1,2,3,4,5,6,7,8,9])
    a[0]
    
    
    
    
    Out[8]:
    1

    Oder auch slicen: array[start:stop:step]

    
    
    In [9]:
    a[:3]
    
    
    
    
    Out[9]:
    array([1, 2, 3])
    
    
    In [10]:
    a[1:7:2]
    
    
    
    
    Out[10]:
    array([2, 4, 6])

    Im Fall von zweidimensionalen Arrays funktioniert das ganz genau so: array[start:stop:step,start:stop:step]

    
    
    In [72]:
    b = np.array([[38,19,35,32, 41], [39,22,22,33,34], [28,34,28,17,45], [12,23,49,13,22]])
    b
    
    
    
    
    Out[72]:
    array([[38, 19, 35, 32, 41],
           [39, 22, 22, 33, 34],
           [28, 34, 28, 17, 45],
           [12, 23, 49, 13, 22]])

    Wir können Zeilen und Spalten aus einem Array herausschneiden. Hier die 2. Reihe:

    
    
    In [84]:
    #hier kann man den Doppelpunkt auch weglassen
    b[1,:]
    
    
    
    
    Out[84]:
    array([39, 22, 22, 33, 34])

    Im folgenden Beispiel schneiden wir die 3. Spalte heraus

    
    
    In [78]:
    #der Doppelpunkt ist notwendig - wir wollen ja alle Werte über die Reihen
    b[:,2]
    
    
    
    
    Out[78]:
    array([35, 22, 28, 49])

    Wir können auf diese Weise offensichtlich auch Reihen und Spalten angeben, um einzelne Werte oder Wertgruppen herauszuschneiden. Im folgenden Beispiel schneiden wir den Wert heraus, der in der Zelle liegt, die durch die 2. Reihe und die 2. Spalte indexiert ist:

    
    
    In [80]:
    b[2,2]
    
    
    
    
    Out[80]:
    28

    Aufgaben

    1) Schneiden Sie die erste Reihe heraus
    2) Schneiden Sie die letzte Spalte heraus (wie kann man das machen, wenn man die Anzahl der Spalten nicht kennt?
    3) Schneiden Sie die Gruppe 17,45,13,22 heraus

    Exkurs: Arange und reshape

    Mit dem Befehl np.arange(n) können wir einen Vektor erzeugen, der mit 0 bis n gefüllt wird (Die Befehl funktioniert ähnlich wie range, d.h. man kann Anfangswerte setzen oder auch Schrittweiten.

    
    
    In [18]:
    c = np.arange(2,22,2)
    c
    
    
    
    
    Out[18]:
    array([ 2,  4,  6,  8, 10, 12, 14, 16, 18, 20])

    Mit der Funktion reshape() können wir einen Vektor oder eine Matrix umformen:

    
    
    In [19]:
    c.reshape(2,5)
    
    
    
    
    Out[19]:
    array([[ 2,  4,  6,  8, 10],
           [12, 14, 16, 18, 20]])
    
    
    In [20]:
    b
    
    
    
    
    Out[20]:
    array([[ 1,  2,  3,  4],
           [ 5,  6,  7,  8],
           [ 9, 10, 11, 12]])
    
    
    In [21]:
    b.reshape(4,3)
    
    
    
    
    Out[21]:
    array([[ 1,  2,  3],
           [ 4,  5,  6],
           [ 7,  8,  9],
           [10, 11, 12]])

    Das funktioniert nur, wenn die Gesamtlänge der alten Matrix auch genau die neue Matrix ausfüllt - sonst wird eine Exception geworfen.

    Aufgabe

    1) Legen Sie mit np.arange(start, stop[, step]) ein 1-dimensionales Array mit den Zahlen von 200 bis 1000 an.
    2)Verfünffachen Sie alle Werte des Arrays.
    3) Erzeugen Sie einen Vektor mit der Größe 100, der ungerade Zahlen beginnend bei 11 enthält.
    4) Geben Sie die letzte Zahl des Vektors aus.
    5) Erzeugen Sie eine Matrix der Form 40x 25 mit den Zahlen von 0-999 als Inhalt.
    6) Lassen Sie sich die erste Zeile der Matrix anzeigen.
    7) Geben die drei Spalten aus, die die Zahlen 150,151,152 enthalten - von Anfang an.

    Broadcasting

    Ein weiterer Unterschied zwischen Python-Listen und numpy Arrays besteht darin, dass Arrays - im Gegensatz zu Python Listen - Vektorisierung und Broadcasting unterstützen. Will man z.B. zwei Python-Listen einfach multiplizieren, so könnte man versucht sein, folgendes zu schreiben:

    
    
    In [111]:
    a = [1,2,3]
    b = [4,5,6]
    #a * b
    

    Genau das aber kann man mit numpy Arrays machen:

    
    
    In [23]:
    a = np.array([1,2,3])
    b = np.array([4,5,6])
    a * b
    
    
    
    
    Out[23]:
    array([ 4, 10, 18])

    Die Arrays werden elementweise multipliziert. Arrays verhalten sich also wie mathematische Vektoren.

    Wir können in Python zwar eine Liste mit einer Zahl multiplizieren, aber was dann passiert, ist folgendes: die Liste wird entsprechend oft wiederholt

    
    
    In [24]:
    c = 3
    a * c
    
    
    
    
    Out[24]:
    array([3, 6, 9])

    Multipliziert man einen Vektor mit einem Skalar (also einer einzelnen Zahl), dann wird jeder Wert des Vektors multipliziert:

    
    
    In [25]:
    b = np.array([3])
    a * b
    
    
    
    
    Out[25]:
    array([3, 6, 9])

    Unter Broadcasting versteht man generell das Verhalten aller Operationen, die stets elementweise angewandt werden.

    
    
    In [26]:
    #wir erzeugen eine Matrix
    d = np.arange(0,21).reshape(7,3)
    d
    
    
    
    
    Out[26]:
    array([[ 0,  1,  2],
           [ 3,  4,  5],
           [ 6,  7,  8],
           [ 9, 10, 11],
           [12, 13, 14],
           [15, 16, 17],
           [18, 19, 20]])
    
    
    In [27]:
    #wir können nun mit einem Befehl alle Elemente der Matrix verändern, z.B.:
    d * 5
    
    
    
    
    Out[27]:
    array([[  0,   5,  10],
           [ 15,  20,  25],
           [ 30,  35,  40],
           [ 45,  50,  55],
           [ 60,  65,  70],
           [ 75,  80,  85],
           [ 90,  95, 100]])
    
    
    In [28]:
    #führen wir noch eine einfache Funktion ein:
    d.sum()
    
    
    
    
    Out[28]:
    210

    Wenn man Rohwerte einer Erhebung in einer Tabelle hat, dann besteht der erste Schritt oft darin, diese zu normalisieren. Nehmen wir an, die Werte oben stellen insgesamt die Anzahl der Worte in einem Text dar, dann würden wir die Werte so normalisieren, dass wir ausrechnen, wieviel Prozent Anteil das jeweilige Wort an der Gesamtheit hat.

    
    
    In [29]:
    dsum = d / d.sum()
    #test! :-)
    dsum.sum()
    
    
    
    
    Out[29]:
    1.0

    Man kann auch zwei Matrizen broadcasten, z.B.:

    
    
    In [30]:
    a = np.array([[1,2,3],[4,5,6]])
    b = np.array([7,8,9])
    a * b
    
    
    
    
    Out[30]:
    array([[ 7, 16, 27],
           [28, 40, 54]])

    Dabei muss man allerdings beachten, dass die Länge der Dimension, immer gleich sind oder 1. Wenn eine der Dimensionen die Länge 1 hat und sie trifft auf eine längere, dann wird sie auf deren Länge erweitert.

    
    
    In [31]:
    a = np.array([[1,2,3],[4,5,6]])
    b = np.array([7,8,9,10])
    
    
    
    In [32]:
    #erzeugt einen Fehler
    #a * b
    
    
    
    
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    <ipython-input-32-f39f92199807> in <module>()
          1 #erzeugt einen Fehler
    ----> 2 a * b
    
    ValueError: operands could not be broadcast together with shapes (2,3) (4,) 
    
    
    In [33]:
    b = np.arange(3).reshape(1, 3)
    b
    
    
    
    
    Out[33]:
    array([[0, 1, 2]])
    
    
    In [34]:
    a * b
    
    
    
    
    Out[34]:
    array([[ 0,  2,  6],
           [ 0,  5, 12]])

    Das ist alles andere als einfach zu verstehen. Siehe "General Broadcasting Rules" im numpy-Handbuch.

    Aufgaben

    1) Erzeugen Sie einen Array mit der Form 4 x 5, der mit den Zahlen der 4er Reihe (4,8,12 usw.) gefüllt ist. Normalisieren Sie die Daten, indem Sie sie durch die Summe teilen.
    2) Finden Sie den höchsten Wert der Matrix und jeder Reihe.

    Datentypen in Numpy Arrays

    Numpy Arrays bestehen, wie oben erwähnt, aus Daten mit dem gleichen Datentypen. Arrays mit mehreren Datentypen nennt man strukturierte Arrays oder Records (s.u.). Man kann den Datentypen auch explizit angeben, (mit den bekannten Nebeneffekten):

    
    
    In [35]:
    c = np.array([1.2,2.3,3.4], dtype=int)
    
    
    
    In [36]:
    c
    
    
    
    
    Out[36]:
    array([1, 2, 3])
    
    
    In [37]:
    c.dtype
    
    
    
    
    Out[37]:
    dtype('int32')
    
    
    In [38]:
    c = np.array([1.2,2.3,3.4])
    c.dtype
    
    
    
    
    Out[38]:
    dtype('float64')

    Außerdem gibt es noch: bool (für Wahrheitswerte), complex (für komplexe Zahlen) u.a.m.

    3) Legen Sie ein Array mit den graden Zahlen von 1-10 an. Teilen Sie alle Werte durch 3 und legen das Ergebnis in einem neuen Array an

    Structured Arrays / Records

    Numpy unterstützt auch strukturierte Arrays, die es erlauben Spalten- und Zeilentitel zu behalten. Wir werden für diese Daten vor allem pandas verwenden.

    NA

    Wirkliche Daten sind oft schmutzig und nicht durchgehend einheitlich.

    Der Inhalt der Datei missing.csv sieht so aus:

    12 3 10 6

    10 n/a 12 8

    7 10 9

    11 9 12 4 </table> In der zweitn Zeile ist anstelle eines Wertes n/a notiert; in der dritten Zeile fehlt der erste Wert ganz. Wenn man solche Dateien einfach so importiert, wird der fehlende und der falsche Wert als nan (not a number) notiert. (Wenn überhaupt kein Wert in der Datei steht, also auch keine leeren Anführungszeichen, dann wirft die Funktion übrigens eine Exception):

    
    
    In [40]:
    data = np.genfromtxt("missing.csv")
    
    
    
    In [41]:
    data
    
    
    
    
    Out[41]:
    array([[ 12.,   3.,  10.,   6.],
           [ 10.,  nan,  12.,   8.],
           [ nan,   7.,  10.,   9.],
           [ 11.,   9.,  12.,   4.]])
    
    
    In [113]:
    data = np.genfromtxt("missing.csv", filling_values=0)
    data
    
    
    
    
    Out[113]:
    array([[ 12.,   3.,  10.,   6.],
           [ 10.,  nan,  12.,   8.],
           [ nan,   7.,  10.,   9.],
           [ 11.,   9.,  12.,   4.]])

    Arrays mit nan oder anderen ungültigen Werten verhalten sich nicht wie gewohnt:

    
    
    In [44]:
    data.sum()
    
    
    
    
    Out[44]:
    nan
    
    
    In [45]:
    for i in data:
        print(i.sum())
    
    
    
    
    31.0
    nan
    nan
    36.0
    

    Um mit solchen Daten umzugehen, muss man ein Array maskieren. Das Bild entsteht daruch, dass man über alle Werte eine Maske legt, die an einigen Stellen die (unbrauchbaren) Werte so einkleidet, dass man trotzdem mit dem Array insgesamt rechnen kann:

    
    
    In [46]:
    import numpy.ma as ma
    masked_data = ma.fix_invalid(data)
    masked_data
    
    
    
    
    Out[46]:
    masked_array(data =
     [[12.0 3.0 10.0 6.0]
     [10.0 -- 12.0 8.0]
     [-- 7.0 10.0 9.0]
     [11.0 9.0 12.0 4.0]],
                 mask =
     [[False False False False]
     [False  True False False]
     [ True False False False]
     [False False False False]],
           fill_value = 1e+20)

    Die Maske hat an den Stellen den Wahrheitswert True, wo der darunterliegende Wert die normalen Array-Operationen stören würde. Man kann übrigens, wenn man will, selbst entscheiden, wie die Maske aussieht. Siehe im numpy-Handbuch den Abschnitt 3.19 masked array operations.

    
    
    In [47]:
    masked_data.sum()
    
    
    
    
    Out[47]:
    123.0
    
    
    In [48]:
    for i in masked_data:
        print(i.sum())
    
    
    
    
    31.0
    30.0
    26.0
    36.0
    

    Aufgabe

    1) Laden Sie die Daten aus der Datei missing.csv, maskieren Sie ungültige Werte und berechnen Sie die Summe der Zeilen.

    Funktionales Programmieren mit Arrays

    numpy bietet eine große Menge an Funktionen, die man mittels broadcasting auf Arrays anwenden lassen kann. Man kann aber auch in vergleichbarer Weise bzw. in einer Art, die an die Verwendung von map im funktionalen Programmieren erinnert, jede selbstgeschriebene Funktion auf numpy-Arrays anwenden. Dazu dient die Funktion np.apply_along_axis().
    np.apply_along_axis(func1d, axis, arr, *args)
    Diese Funktion verarbeitet eine Matrix in der Weise, dass in der angegebenen Achse jeweils ein Vektor, also ein 1-dimensionaler Array, herausgeschnitten wird und mit der Funktion verarbeitet wird, d.h. die Funktion sollte als Input einen Vektor erwarten.

    
    
    In [55]:
    def simple_mean(a):
        return a.sum() /len(a)
    
    a = np.array([[1,4,2,7,5], [3,1,4,6,3], [6,1,4,2,4]])
    print(a)
    np.apply_along_axis( simple_mean,axis=0,arr=a)  #axis u arr kann man natürlich weglassen, hier zur Erläuterung
    
    
    
    
    [[1 4 2 7 5]
     [3 1 4 6 3]
     [6 1 4 2 4]]
    
    Out[55]:
    array([ 3.33333333,  2.        ,  3.33333333,  5.        ,  4.        ])
    
    
    In [56]:
    #Im folgenden Beispiel wird die Axis auf 1 gesetzt:
    np.apply_along_axis( simple_mean,axis=1,arr=a)
    
    
    
    
    Out[56]:
    array([ 3.8,  3.4,  3.4])
    
    
    In [96]:
    #wir können so auch numpy Funktionen auf Arrays anwenden
    g = np.array([2,12,5,2,4,9])
    print(np.max(g))
    print(np.max(a))
    np.apply_along_axis(np.max,axis=0,arr=g)
    
    
    
    
    12
    6
    
    Out[96]:
    array(12)

    Deskriptive Statistik

    numpy bringt auch von Haus aus eine Reihe von Funktionen für die deskriptive Statistik mit. Ich gehe davon aus, dass die grundlegenden Konzepte noch aus der Schule bekannt sind (sonst bitte: Wikipedia!).

    Mittelwert (mean)
    Der Mittelwert ist ein Zentralitätsmaß und soll einen Eindruck vermitteln, wo der Mittelpunkt der Datenreihe ist. In der Praxis wichtiger ist der Mittelwert allerdings als Faktor in anderen Maßen, z.B. in der Standardabweichung, oder als Information im Rahmen eines Boxplots. Berechnet wird der Mittelwert folgendermaßen: $$ \mu = \sum_{i=0}^n \frac {x_i} {n} $$ Wobei:
    i - der Indexwert des Datenpunkts ist, x0 ist also der Wert des ersten Datenpunkts usw.
    n - die Anzahl der Datenpunkte

    
    
    In [63]:
    data = np.array([34, 12, 77, 90, 34, 67, 52])
    np.mean(data)
    
    
    
    
    Out[63]:
    52.285714285714285

    Varianz
    Varianz ist ein Streumaß, das uns eine Einschätzung erlaubt, wie sehr die Daten vom Mittelwert abweichen. Offensichtlich haben die Datenreihen [6,6,6,6] und [1,11,2,10] den gleichen Mittelwert, aber eine ganz unterschiedliche Varianz. Berechnet wird die Varianz einer Population folgendermaßen: $$ v = \sum_{i=0}^n \frac {(\mu - x_i)^2} {n} $$ Die Quadrierung der Werte ist notwendig, um zu vermeiden, dass sich positive und negative Werte gegenseitig aufwiegen. Allerdings erschwert die Quadrierung die Interpretation einer Varianz (Wenn wir die Varianz der Körpergröße gemessen in cm anschauen, dann haben wir einen Wert in Quadratzentimeter vor uns...), außerdem sind die Werte recht groß.

    
    
    In [105]:
    np.var(data)
    
    
    
    
    Out[105]:
    648.7755102040818
    
    
    In [106]:
    a = [6,6,6,6] 
    b = [1,11,2,10]
    print("Mittelwert a: ", np.mean(a))
    print("Mittelwert b: ", np.mean(b))
    print("Varianz a: ", np.var(a))
    print("Varianz b: ", np.var(b))
    
    
    
    
    Mittelwert a:  6.0
    Mittelwert b:  6.0
    Varianz a:  0.0
    Varianz b:  20.5
    

    Standardabweichung (standard deviation)
    Die Standardabweichung ist die Wurzel aus der Varianz, hat also den Vorteil, dass ihre Einheit und Größenverhältnisse intuitiv einsichtig interpretierbar sind. $$ \sigma = \sqrt{\sum_{i=0}^n \frac {(\mu - x_i)^2} {n}} $$

    
    
    In [99]:
    np.std(data)
    
    
    
    
    Out[99]:
    25.471072026989397
    
    
    In [71]:
    print("Mittelwert a und b: ", np.mean(a))
    print("Standardabweichung a: ", np.std(a))
    print("Standardabweichung b: ", np.std(b))
    
    
    
    
    Mittelwert a und b:  6.0
    Standardabweichung a:  0.0
    Standardabweichung b:  4.52769256907
    

    Highlights, die wir nicht behandelt haben: Finanzfunktionen, Lineare Algebra, Diskrete Fourier Transformationen u.a.m.

    Aufgaben

    1) Gegeben ist der Array [[38,19,35,32, 41], [39,22,22,33,34], [28,34,28,17,45], [12,23,49,13,22]]. Berechnen Sie den Mittelwert aller Zahlen sowie der Spalten und der Zeilen.

    Hausaufgaben

    1) Erzeugen Sie eine Worthäufigkeitsmatrix für die 30 häufigsten Worte aus Goethes Wahlverwandtschaften, Fontanes Effi Briest, Raabes Stopfkuchen und Kafkas Der Prozeß (alle Texte finden Sie auf Textgrid - textgridrep.de). Normalisieren Sie die Matrix. Berechnen Sie den Mittelwert für jedes Wort.

    Weiterführende Literatur

    
    
    In [ ]: