Verändlerliche Listen addieren

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.
Benutzeravatar
Ede1994
User
Beiträge: 72
Registriert: Dienstag 2. Mai 2017, 12:41

Mein Problem ist das folgende:
in der for-Schleife rufe ich zwei Funktionen auf, welche jeweils eine Liste mit 16384 float-Zahlen zurückgeben, dabei handelt es sich um Amplitudenwerte einer Hilbert-Transformation. Nun packe ich nach jedem Durchlauf neue Anfangswerten (ein neues Signal) in meine Funktion, d.h. die Liste1 und 2 ändert sich ständig.
ich möchte nun jedes Element mit den darauffolgenden Werten addieren, genau so:
[0,0,0......0,0,0]
+
[1,2,3......3,2,1]
=
[1,2,3......3,2,1]
+
[2,4,6......6,4,2]
usw.

Ich müsste also nach jedem Durchlauf irgendwie die Werte zwischenspeichern und das bekomme ich nicht hin.

Programmskizze:
[codebox=pycon file=Unbenannt.txt]
for i in range(10):
liste1 = def1(signal)
liste2 = def2(signal)
liste1_summe = ?
liste2_summe = ?
[/code]
Ich hoffe ihr könnt mir helfen!!
Benutzeravatar
Ede1994
User
Beiträge: 72
Registriert: Dienstag 2. Mai 2017, 12:41

Das hatte ich natürlich schon so ähnlich probiert, aber meine Listen liste1 und liste2 sind unabhängig voneinander und werden ja immer nach jedem Durchlauf überschrieben.
Vllt sollte ich besser erklären was ich meine:
1. liste1 und liste2 erhalten vom 1. Signal Werte
2. liste1 und liste2 müssen gespeichert werden, in einer separaten liste
3. liste1 und liste2 bekommen nun neue Werte vom 2. Signal, alte Werte werden überschrieben
4. liste1 und liste2 sollen jetzt mit den alten Werten vom 1. Signal addiert werden und das Ergebnis soll in einer Liste zwischengespeichert werden
5. liste1 und liste2 erhalten vom 3. Signal Werte, alte Werte werden überschrieben
6. liste1 und liste2 wieder auf die liste von 4. aufaddieren
usw.
BlackJack

@Ede1994: So geht das aber, und wenn das bei Dir nicht geht, dann müsstest Du mal ein Beispiel zeigen wo man sieht das es bei Dir nicht geht.

Du müsstest mental vielleicht von dem ”veränderliche Listen” und ”da werden Werte überschrieben” weg kommen, denn das passiert nicht, beziehungsweise sollte auch nicht passieren. Wenn man die Listen als unveränderlich behandelt, dann verhalten sie sich wie Zahlen. Rechenoperationen erzeugen neue Werte und verändern nichts bestehendes.
sebastian0202
User
Beiträge: 168
Registriert: Montag 9. Mai 2016, 09:14
Wohnort: Berlin

Etwas unschöner Code, aber hast du dabei an sowas gedacht Ede1994?

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

import random
from operator import add

MENGE = 5
DURCHLAUF = 10

def main():
    sammeln = [[0 for _ in range(MENGE)]]
    for i in range(DURCHLAUF):
        erster_teil = [random.randint(0,9) for _ in range(MENGE)]
        zweiter_teil = [random.randint(0,9) for _ in range(MENGE)]
        summe = [sum(x) for x in zip(erster_teil, zweiter_teil, sammeln[-1])]
        sammeln.append(summe)
        print(summe)

if __name__ == "__main__":
    main()

Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@edel1994: meinst Du das da? Ober wo ist das Problem?

Code: Alles auswählen

liste1_alt = None
liste2_alt = None

for i in range(10):
    liste1 = def1(signal)
    liste2 = def2(signal)

    if liste1_alt and liste2_alt:
        liste1_summe = summiere_listen(liste1_alt,liste1)
        liste2_summe = summiere_listen(liste2_alt,liste2)

    liste1_alt = liste1
    liste2_alt = liste2
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

@ Alfons Mittelmeyer, warum dann nicht gleich so:

Code: Alles auswählen

liste1_summe = [0.0] * 16384
liste2_summe = [0.0] * 16384

for i in range(10):
    liste1_summe = summiere_listen(liste1_summe, def1(signal))
    liste2_summe = summiere_listen(liste2_summe, def2(signal))
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Zizibee hat geschrieben:@ Alfons Mittelmeyer, warum dann nicht gleich so:
Ja wenn es das ist, was edel1994 möchte. Ich bin aus seiner Bechreibung noch nicht ganz schlau geworden. Vielleicht erfahren wir von ihm ja mehr.

@edel1994: Was mir nicht klar ist, Du schriebst etwas von alter Liste zwischenspeichern, um sie jeweils nur mit der neuen Liste zu addieren. Dann klang aber auch etwas von alles zusammen addieren an, also Gesamtsumme.

Was soll es denn sein?
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Ede1994 hat geschrieben:Das hatte ich natürlich schon so ähnlich probiert, aber meine Listen liste1 und liste2 sind unabhängig voneinander und werden ja immer nach jedem Durchlauf überschrieben.
Vllt sollte ich besser erklären was ich meine:
1. liste1 und liste2 erhalten vom 1. Signal Werte
2. liste1 und liste2 müssen gespeichert werden, in einer separaten liste
Wofür liste 1 und liste2 speichern? Für eine Gesamtsumme über die Durchläufe ist das unnötig
Oder benötigst Du am Ende alle Listen nochmals einzeln?
Ede1994 hat geschrieben:3. liste1 und liste2 bekommen nun neue Werte vom 2. Signal, alte Werte werden überschrieben
Nicht ganz richtig: def1 und def2 liefern neue Listen, diese bekommen wieder die Namen liste1 und liste2. Die alten Listen sind dann namenlos und werden vergessen und als Abfall entsorgt.
Ede1994 hat geschrieben:4. liste1 und liste2 sollen jetzt mit den alten Werten vom 1. Signal addiert werden und das Ergebnis soll in einer Liste zwischengespeichert werden
Das ist schlecht beschrieben, denn es handelt sich hier um die Aktualisierung der Summe. Und in 2. war der Startwert für die Summe.

Ist es jetzt das?

Code: Alles auswählen

anfang = True
for i in range(10):

    liste1 = def1(signal)
    liste2 = def1(signal)

    if anfang:
        anfang = False
        summe1 = [0.0] * len(liste1)
        summe2 = [0.0] * len(liste2)

    summe1 = summiere_listen(summe1, liste1)
    summe2 = summiere_listen(summe2, liste2)
Ich benutze hier das Flag anfang, da ich nicht weiß, wieviel Elemente Deine Listen haben. Wenn Du es weißt, brauchst Du dieses Flag nicht, sondern kannst summe1 und summe2 gleich vor der Schleife initialisieren
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: da ist Deine vorherige Lösung ohne explizites Flag noch besser.

Code: Alles auswählen

summe1 = summe2 = None
for i in range(10):
    liste1 = def1(signal)
    liste2 = def2(signal)
 
    if summe1:
        summe1 = summiere_listen(summe1, liste1)
        summe2 = summiere_listen(summe2, liste2)
    else:
        summe1 = liste1
        summe2 = liste2
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Sirius3 hat geschrieben:@Alfons Mittelmeyer: da ist Deine vorherige Lösung ohne explizites Flag noch besser.
Wenn es Dir besser gefällt summe1 als flag zu nehmen, tja warum nicht. Wenn man nicht weiß, was jemand mit liste1 und liste2 anstellt, ob er da noch an Werten etwas nachträglich verändert, ist es besser, Deine Zeilen 10 und 11 so abzuändern:

Code: Alles auswählen

summe1 = summe2 = None
for i in range(10):
    liste1 = def1(signal)
    liste2 = def2(signal)
 
    if summe1:
        summe1 = summiere_listen(summe1, liste1)
        summe2 = summiere_listen(summe2, liste2)
    else:
        summe1 = list(liste1)
        summe2 = list(liste2)
Benutzeravatar
Ede1994
User
Beiträge: 72
Registriert: Dienstag 2. Mai 2017, 12:41

Also erstmal Entschuldigung für die nicht ganz eindeutige Formulierung der Problemstellung und danke für die Ideen und Lösungsvorschläge. Beschäftige mich erst seit ein paar Monaten mit Python. Letztlich habe ich das Problem wie folgt gelöst:
[codebox=python file=Unbenannt.txt]
n = 16384
list1_sum = n*[0]
list2_sum = n*[0]
for i in xrange(10):
list1 = def1()
list2 = def2()
for j in xrange(n):
list1_sum[j] += list1[j]
list2_sum[j] += list2[j]
[/code]

Vllt nicht ideal, aber es macht was es soll.
Zuletzt geändert von Anonymous am Mittwoch 3. Mai 2017, 10:31, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Ede1994: Dann wäre das wohl ideal?

Code: Alles auswählen

n = 16384
list1_sum = n*[0]
list2_sum = n*[0]
for i in xrange(10):
  list1 = def1()
  list2 = def2()
  list1_sum = [a + b for a, b in zip(list1_sum, list1)]
  list2_sum = [a + b for a, b in zip(list2_sum, list2)]
Schneller ist es sicher!
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Oder mit numpy :D :

Code: Alles auswählen

import numpy as np

n = 16384
list1_sum = np.array(n*[0])
list2_sum = np.array(n*[0])

for i in xrange(10):
    list1_sum += def1()
    list2_sum += def2()
BlackJack

@Zizibee: Ich würde ja `numpy.zeros` verwenden, dann spart man sich die Listen mit den 16K Nullen als Zwischenschritt. :-)
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@BlackJack; ich würde ja 0 nehmen, dann spart man sich die Gedanken darüber, wie groß denn nun das Array tatsächlich sein muß.
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

BlackJack hat geschrieben:@Zizibee: Ich würde ja `numpy.zeros` verwenden, dann spart man sich die Listen mit den 16K Nullen als Zwischenschritt. :-)
Das kannst ich noch nicht, danke. Aber wie kann ich damit den Zwischenschritt sparen?
Macht numpy.zeros(5) nicht das gleiche wie numpy.array(5*[0])?
Sirius3 hat geschrieben:ich würde ja 0 nehmen, dann spart man sich die Gedanken darüber, wie groß denn nun das Array tatsächlich sein muß.
Würdest du das evtl. noch etwas genauer erklären? Muss ich die Größe des Arrays nicht immer definieren, damit es anschließend mit der Addition funktioniert?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Zizibee hat geschrieben:Muss ich die Größe des Arrays nicht immer definieren, damit es anschließend mit der Addition funktioniert?
Am besten einfach ausprobieren.
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

@Sirius3:
Das hatte ich natürlich vorher ausprobiert, bekam aber immer einen Fehler in der Art:
Traceback (most recent call last):
File "python", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (5,) (0,)

Jetzt hat es aber "plötzlich" doch geklappt, danke. :oops:
BlackJack

@Zizibee: Bei ``array(5*[0])`` wird zuerst eine Python-Liste mit 5 Python-`int`-Werten erstellt. Diese Liste wird `array()` als Argument übergeben. Das schaut sich jedes Element der Liste an welchen Typ das hat um den `dtype` für das `array` zu ermitteln. Dann schaut es sich die Länge der Liste an um den Speicher für die Daten zu belegen. Dann wird wieder die Liste durchgegangen und jeder Wert wird in den `dtype` des Arrays umgewandelt und in dem Array gespeichert.

Bei `zeros(5)` wird Speicher für 5 Elemente vom `dtype` `float` belegt. Und dieser Speicher wird mit 5 Nullwerten initialisiert.
Antworten