Zweidimensionale Liste / Rechnen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
reddy
User
Beiträge: 21
Registriert: Donnerstag 17. März 2016, 23:29

Hallo,
ich habe leider im Internet nichts passendes gefunden.
Es geht um das Rechnen mit Zwei(Mehr-)-Dimensionalen Listen.
Z.B. bei eindimensionaler Liste ist klar:

Code: Alles auswählen

import statistics
liste = [1.85, 1.90, 1.86, 1.69, 1.78, 1.79]
Durchschnitt = statistics.mean(liste)
print(round(Durchschnitt, 2))
Bei zweidimensionalen Liste ist es bei mir schwieriger. Um damit zu rechnen, mache ich zuerst wieder eindimensionale Liste daraus:

Code: Alles auswählen

liste = [["Alex", 1.85], ["Conrad", 1.90], ["Sven", 1.86], ["Peter", 1.69], ["Martin", 1.78], ["Frank", 1.79]]
liste_nur_groesse = []
for n in range(len(liste)):
    liste_nur_groesse.append(liste[n][1])

Durchschnitt = statistics.mean(liste_nur_groesse)
print(round(Durchschnitt, 2))
Gibt es eventuell eine einfachere Lösung?
Zuletzt geändert von Anonymous am Mittwoch 10. Mai 2017, 19:25, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17759
Registriert: Sonntag 21. Oktober 2012, 17:20

@reddy: in Python iteriert man nicht über einen Index, sondern über die Elemente der Liste direkt:

Code: Alles auswählen

liste = [["Alex", 1.85], ["Conrad", 1.90], ["Sven", 1.86], ["Peter", 1.69], ["Martin", 1.78], ["Frank", 1.79]]
liste_nur_groesse = []
for name, groesse in liste:
    liste_nur_groesse.append(groesse)
das kann man durch eine List-Comprehension kürzer schreiben:

Code: Alles auswählen

liste_nur_groesse = [groesse for name, groesse in liste]
oder direkt als Generatorausdruck für mean:

Code: Alles auswählen

durchschnitt = statistics.mean(groesse for name, groesse in liste)
print("{:.2f}".format(durchschnitt))
BlackJack

Noch eine Variante mit `map()` und `operator.itemgetter()`:

Code: Alles auswählen

In [20]: liste
Out[20]: 
[['Alex', 1.85],
 ['Conrad', 1.9],
 ['Sven', 1.86],
 ['Peter', 1.69],
 ['Martin', 1.78],
 ['Frank', 1.79]]

In [21]: list(map(operator.itemgetter(1), liste))
Out[21]: [1.85, 1.9, 1.86, 1.69, 1.78, 1.79]

In [22]: statistics.mean(map(operator.itemgetter(1), liste))
Out[22]: 1.8116666666666668
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Das Python-Modul Numpy hat multidimensionale Array-Klassen. Damit kannst Du sowohl auf Zeilen als auch auf Spalten von 2D-Arrays zugreifen. Operationen wie Mittelwert-Berechnung von einer Spalte werden damit zum Einzeiler.
Allerdings sollten alle Spalten den gleichen Datentyp haben.
a fool with a tool is still a fool, www.magben.de, YouTube
BlackJack

Man kann bei Numpy auch pro Spalte einen Datentyp angeben. Oder man setzt gleich auf Pandas und dessen `DataFrame`\s.

Numpy:

Code: Alles auswählen

In [16]: liste
Out[16]: 
[['Alex', 1.85],
 ['Conrad', 1.9],
 ['Sven', 1.86],
 ['Peter', 1.69],
 ['Martin', 1.78],
 ['Frank', 1.79]]

In [17]: A = np.array(map(tuple, liste), dtype=[('name', object), ('score', float)])

In [18]: A['score'].copy()
Out[18]: array([ 1.85,  1.9 ,  1.86,  1.69,  1.78,  1.79])

In [19]: A['score'].copy().mean()
Out[19]: 1.8116666666666668
Pandas:

Code: Alles auswählen

In [30]: df = pd.DataFrame(liste, columns=['name', 'score'])

In [31]: df
Out[31]: 
     name  score
0    Alex   1.85
1  Conrad   1.90
2    Sven   1.86
3   Peter   1.69
4  Martin   1.78
5   Frank   1.79

In [32]: df.score
Out[32]: 
0    1.85
1    1.90
2    1.86
3    1.69
4    1.78
5    1.79
Name: score, dtype: float64

In [33]: df.score.mean()
Out[33]: 1.8116666666666668
reddy
User
Beiträge: 21
Registriert: Donnerstag 17. März 2016, 23:29

Danke schön an alle!

Mit Pandas und Numpy werde ich mich später beschäftigen.
Es sind einfach mächtige Werkzeuge. Da muss man ja gar nichts mehr programmieren. :-)
operator.itemgetter() habe ich bis jetzt nur zum Sortieren von Listen benutzt. map() ist mir vollkommen unbekannt.

Von List-Comprehension höre ich immer wieder. Zur Zeit ist es interessanteste Lösung.
Ich hätte da noch eine Frage...:-)
Ich arbeite manchmal mit Tabellen, bei denen Datensätze unvollständig sind.
Kann man bei List-Comprehension auch logische Funktionen einsetzen?
Z.B. mein (schrecklicher) Code wäre dann:

Code: Alles auswählen

liste = [["Alex", 1.85], ["Conrad", 1.90], ["Sven", 1.86], ["Peter", 1.69], ["Martin", 1.78], ["Frank", 1.79],
         ["Mark", "kA"]]
# "kA" = keine Angabe
liste_nur_groesse = []
for n in range(len(liste)):
    if liste[n][1] == "kA":
        continue
    else:
        liste_nur_groesse.append(liste[n][1])

Durchschnitt = statistics.mean(liste_nur_groesse)
print(round(Durchschnitt, 2))
Wie kann man List-Comprehension nutzen und dabei fehlende Eingaben ignorieren?
Zuletzt geändert von Anonymous am Donnerstag 11. Mai 2017, 18:35, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@reddy: Iii, unnötige Indexzugriffe und ``continue``. Dreh die Bedingung um und mach den ``else``-Zweig zum ``if``-Zweig, und der Indexzugriff geht ja mal gar nicht (ungetestet):

Code: Alles auswählen

liste_nur_groesse = list()
for _, height in liste:
    if height != 'kA':
        liste_nur_groesse.append(height)

# <->

liste_nur_groesse = [height for _, height in liste if height != 'kA']
Antworten