Mittelwert berechnen für Sequenz aus Zahlenreihe

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
chulia
User
Beiträge: 29
Registriert: Mittwoch 17. August 2011, 10:26

Hallöchen,

ich hab ein Problemchen, was sicherlich ganz einfach zu beheben ist, aber ich steh im Moment auf dem Schlauch.
Und zwar habe ich ein Array mit Werten und Nullen bzw. NaNs. Ich möchte nun immer für die Werte in der Mitte stehend (die von NaNs umschlossen sind) jeweils den Mittelwert bestimmen.

So sieht bspw. die Tabelle aus:

Code: Alles auswählen

array([[  0.        ,   0.        ,   0.        ,          nan],
       [  1.        ,   0.        ,   0.        ,          nan],
       [  2.        ,   0.        ,   0.        ,          nan],
       [  9.        ,   0.        ,   0.        ,          nan],
       [ 10.        ,   0.        ,   0.        ,          nan],
       [ 11.        ,   0.        ,   0.        ,          nan],
       [ 12.        ,   0.        ,   0.        ,          nan],
       [ 13.        ,   1.        ,   0.46082949,   0.19753966],
       [ 14.        ,   2.        ,   0.92165899,   0.18474466],
       [ 15.        ,   8.        ,   3.68663594,   0.16519867],
       [ 16.        ,  16.        ,   7.37327189,   0.14298502],
       [ 17.        ,   6.        ,   2.76497696,   0.15898843],
       [ 18.        ,  10.        ,   4.60829493,   0.15939101],
       [ 19.        ,  15.        ,   6.9124424 ,   0.14307084],
       [ 20.        ,   1.        ,   0.46082949,   0.19651221],
       [ 21.        ,   0.        ,   0.        ,          nan],
       [ 22.        ,   0.        ,   0.        ,          nan],
       [ 23.        ,   0.        ,   0.        ,          nan],
       [ 24.        ,   0.        ,   0.        ,          nan],
       [ 25.        ,   0.        ,   0.        ,          nan],
       [ 27.        ,   3.        ,   1.38248848,   0.18489192],
       [ 28.        ,   3.        ,   1.38248848,   0.19017589],
       [ 29.        ,   0.        ,   0.        ,          nan],
       [ 30.        ,   0.        ,   0.        ,          nan],
       [ 31.        ,   0.        ,   0.        ,          nan],
       [ 32.        ,   0.        ,   0.        ,          nan],
       [ 33.        ,  18.        ,   8.29493088,   0.1629946 ]])
       
usw.

ich möchte jetzt immer für die Werte der 3. und 4. Spalte den Mittelwert bilden.

ich hab es schon mit einer komplizierten Aneinandereihung mit
np.isnan und np.where versucht, um die Anfangszeile und Endzeile zu finden, nur leider wird das auf Dauer ganz schön kompliziert.

Gibt es irgende Funktion in Python mit der ich den Mittelwert einer Sequenz berechnen kann?

Ich würde mich über eine kleine Hilfe freuen.
Vielen Dank und liebe Grüße
chulia
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Suchst du das?

Code: Alles auswählen

>>> a[~np.isnan(a).any(1)]
array([[ 13.        ,   1.        ,   0.46082949,   0.19753966],
       [ 14.        ,   2.        ,   0.92165899,   0.18474466],
       [ 15.        ,   8.        ,   3.68663594,   0.16519867],
       [ 16.        ,  16.        ,   7.37327189,   0.14298502],
       [ 17.        ,   6.        ,   2.76497696,   0.15898843],
       [ 18.        ,  10.        ,   4.60829493,   0.15939101],
       [ 19.        ,  15.        ,   6.9124424 ,   0.14307084],
       [ 20.        ,   1.        ,   0.46082949,   0.19651221],
       [ 27.        ,   3.        ,   1.38248848,   0.18489192],
       [ 28.        ,   3.        ,   1.38248848,   0.19017589],
       [ 33.        ,  18.        ,   8.29493088,   0.1629946 ]])
Das Leben ist wie ein Tennisball.
chulia
User
Beiträge: 29
Registriert: Mittwoch 17. August 2011, 10:26

Das ist schonmal ein Anfang,

aber die NaN gelten als Trennung. Das heißt, ich brauch nicht von allen Werten zusammen den Mittelwert sondern nur von zusammenhängenden.
Also quasi von 13-20; 27-28; 33 usw.
BlackJack

Das ist doch alles ganz einfach. :twisted: Viel Spass beim analysieren des Ausdrucks:

Code: Alles auswählen

import numpy as np

DATA = np.array([[ 0.,   0.,   0.,          np.nan],
                 [ 1.,   0.,   0.,          np.nan],
                 [ 2.,   0.,   0.,          np.nan],
                 [ 9.,   0.,   0.,          np.nan],
                 [10.,   0.,   0.,          np.nan],
                 [11.,   0.,   0.,          np.nan],
                 [12.,   0.,   0.,          np.nan],
                 [13.,   1.,   0.46082949,  0.19753966],
                 [14.,   2.,   0.92165899,  0.18474466],
                 [15.,   8.,   3.68663594,  0.16519867],
                 [16.,  16.,   7.37327189,  0.14298502],
                 [17.,   6.,   2.76497696,  0.15898843],
                 [18.,  10.,   4.60829493,  0.15939101],
                 [19.,  15.,   6.9124424,   0.14307084],
                 [20.,   1.,   0.46082949,  0.19651221],
                 [21.,   0.,   0.,          np.nan],
                 [22.,   0.,   0.,          np.nan],
                 [23.,   0.,   0.,          np.nan],
                 [24.,   0.,   0.,          np.nan],
                 [25.,   0.,   0.,          np.nan],
                 [27.,   3.,   1.38248848,  0.18489192],
                 [28.,   3.,   1.38248848,  0.19017589],
                 [29.,   0.,   0.,          np.nan],
                 [30.,   0.,   0.,          np.nan],
                 [31.,   0.,   0.,          np.nan],
                 [32.,   0.,   0.,          np.nan],
                 [33.,  18.,   8.29493088,  0.1629946]])


def main():
    result = [
        a.mean(0)
        for a in np.split(
            DATA[:, 2:4], np.argwhere(np.diff(np.isnan(DATA[:, 3]))) + 1
        )[1::2]
    ]
    print result


if __name__ == '__main__':
    main()
Nun hoffe ich nur noch, dass das Ergebnis richtig ist:

Code: Alles auswählen

[array([ 3.39861751,  0.16855381]),
 array([ 1.38248848,  0.18753391]),
 array([ 8.29493088,  0.1629946 ])]
chulia
User
Beiträge: 29
Registriert: Mittwoch 17. August 2011, 10:26

Vielen Dank BlackJack.

Ich als blutige Anfängerin versuch mich da mal durchzufitzeln und es zu verstehen ;)
chulia
User
Beiträge: 29
Registriert: Mittwoch 17. August 2011, 10:26

Hallöchen,

ich hatte leider erst heute die Möglichkeit das Skript auszuprobieren.
So ganz hab ich nicht verstanden, was Python da macht. Vor allem mit solchen "def" habe ich vorher noch nie gearbeitet.
Aber es funktioniert ohne Probleme.

Nur kann es sein, dass es dieses "result" sich nicht merkt und als Variable abspeichert?
Denn wenn ich es nachdem das Skript durchgelaufen ist, nochmal result abrufen will, kommt die Meldung, das der Name "result" nicht definiert ist.

Vielen Dank
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

chulia hat geschrieben: So ganz hab ich nicht verstanden, was Python da macht. Vor allem mit solchen "def" habe ich vorher noch nie gearbeitet.
Dann solltest Du Dich dringend tiefer mit Python befassen - sofern Du es denn weiterhin benötigst. ``def`` ist lediglich das Schlüsselwort für die Definition einer Funktion. Und Funktionen gehören sicherlich zu den "Building Blocks" der Sprache Python - Du hast ja mit diversen Aufrufen davon auch logischerweise schon gearbeitet ;-)
chulia hat geschrieben: Nur kann es sein, dass es dieses "result" sich nicht merkt und als Variable abspeichert?
Denn wenn ich es nachdem das Skript durchgelaufen ist, nochmal result abrufen will, kommt die Meldung, das der Name "result" nicht definiert ist.
Natürlich *bindet* er das Ergebnis der Berechnung in der ``main``-Funktion in Zeile 33 an den Namen ``result``! In Zeile 39 wird ja über den Namen auf das daran gebundene Objekt zugegriffen und dieses ausgegeben ;-)

Unmittelbar nach Verlassen der ``main``-Funktion, ist der Name ``result`` nicht mehr gültig. Man verlässt den Gültigkeitsbereich ("Skope") der Variablen und damit ist diese quasi "verloren".

So richtig habe ich leider nicht verstanden, wie Du "danach" noch einmal auf ``result`` zugreifen willst? Das solltest Du ggf. noch einmal erklären.

Insgesamt habe ich nach Deinem letzten Beitrag das Gefühl, dass Du massive Lücken und den Grundkenntnissen von Python hast. Wenn Python für Dich wichtig ist, solltest Du Dich dringend mal an das offizielle Tutorial setzen und das durcharbeiten. Je nach Kenntnisstand in Sachen Programmieren ggf. auch ergänzend "Learn Python the hard way" als Tutorial in Betracht ziehen.

Was Du hier nicht verstehst, sind die absoluten Basics! Der wirklich harte Teil steht in Zeile 36 ;-) Alles andere ist - mit Verlaub - trivial!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@chulia: diese "def" sind Funktionen, alle Variablen, die innerhalb von Funktionen benutzt werden, sind lokal, das heißt, wenn die Funktion fertig ist, dann sind die Variablen wieder weg. Um mit result weiterzuarbeiten, musst Du die Berechnung in eine eigene Funktion auslagern und das Ergebnis per return zurückgeben.

Code: Alles auswählen

def calculate_mean(data):
    result = [
        a.mean(0)
        for a in np.split(
            data[:, 2:4], np.argwhere(np.diff(np.isnan(data[:, 3]))) + 1
        )[1::2]
    ]
    return result
Dann kannst Du interaktiv auch damit weiterarbeiten:

Code: Alles auswählen

>>> mean_values = calculate_mean(DATA)
>>> print mean_values
[array([ 3.39861751,  0.16855381]),
 array([ 1.38248848,  0.18753391]),
 array([ 8.29493088,  0.1629946 ])]
chulia
User
Beiträge: 29
Registriert: Mittwoch 17. August 2011, 10:26

@ Sirius3: vielen Dank, dass hat mir sehr weitergeholfen.
chulia
User
Beiträge: 29
Registriert: Mittwoch 17. August 2011, 10:26

Und mir ist nochmal eine Kleinigkeit aufgefallen.
Das Skript funktioniert nur, wenn in der ersten Zeile ein NaN steht, ist dort schon ein Wert, wird das Skript nicht richtig ausgeführt.

Ich denke, das liegt an der Zeile 36 wo in den Daten nach NaNs angefragt wird.

Kennt da einer noch eine Lösung?

Ich hab es jetzt damit überbückt, einfach oben eine neue Zeile mit nan einzufügen. Dann funktioniert es wieder.
Aber gibts da nicht in der Funktion noch eine Möglichkeit?
BlackJack

Ungetestet:

Code: Alles auswählen

def calculate_mean(data):
    last_column = data[:, 3]
    result = [
        a.mean(0)
        for a in np.split(
            data[:, 2:4], np.argwhere(np.diff(np.isnan(last_column))) + 1
        )[int(np.isnan(last_column[0]))::2]
    ]
    return result
Antworten