Seite 1 von 1

Aufeinanderfolgende Listenelemente vergleichen

Verfasst: Dienstag 6. August 2019, 10:15
von Ede1994
Hallo..ich mal wieder :D
Ich möchte in einer Liste Sublisten erstellen und zwar ganz systematisch. Bisher mache ich folgendes:

Code: Alles auswählen

data=[0,0,0,0,0.2,0.3,1,1,1,1,0,0,0]
Max_data=max(data)
result = [list(value) for _, value in groupby(data, lambda value, c=count(): value >= Max_data/2.)]
Das funktioniert auch. Jetzt möchte ich aber aufeinanderfolgende Elemente vergleichen. Das Ergebnissen sollen dann Sublisten sein, welche alle Elemente enthalten bis eine Schranke überschritten wurde und dann soll die nächste Subliste anfangen.
Zum Bsp. mit einer Schranke von 0.5:

Code: Alles auswählen

data=[0,0,0,0,0.2,0.3,1,1,1,1,0,0,0]
result=[[0,0,0,0,0.2,0.3],[1,1,1,1],[0,0,0]]
In dem Code-Beispiel oben müsste also noch irgndwie eine +1 rein, damit er Value mit der nächsten Zahl vergleicht...

Re: Aufeinanderfolgende Listenelemente vergleichen

Verfasst: Dienstag 6. August 2019, 10:57
von __blackjack__

Code: Alles auswählen

from itertools import count, groupby
from operator import itemgetter

def split(data, threshold):
    
    def stamp():
        counter = count()
        previous = data[0]
        group_index = next(counter)
        for value in data:
            if abs(value - previous) >= threshold:
                group_index = next(counter)
            yield (group_index, value)
            previous = value
    
    return (
        list(map(itemgetter(1), group))
        for _, group in groupby(stamp(), itemgetter(0))
    )


def main():
    data = [0, 0, 0, 0, 0.2, 0.3, 1, 1, 1, 1, 0, 0, 0]
    print(list(split(data, 0.5)))

Re: Aufeinanderfolgende Listenelemente vergleichen

Verfasst: Dienstag 6. August 2019, 11:30
von Ede1994
Super. Danke! Funktioniert. Der Verwendung von YIELD ist mir so noch nicht bekannt, aber das werde ich mir gleich mal angucken.

Re: Aufeinanderfolgende Listenelemente vergleichen

Verfasst: Mittwoch 4. September 2019, 10:08
von Ede1994
Eine weiterführende Frage: Ich habe jetzt als Ergebnis des o.g. Codes folgendes :[[0, 0, 0, 0, 0.2, 0.3, 0.3, 0.4], [0.9, 0.9, 0.9, 0.5, 0.5, 0.5, 0.5]]. Nun möchte ich diese Listen neu aufteilen und zwar wie folgt:

Code: Alles auswählen

	result =  [[0, 0, 0, 0, 0.2, 0.3, 0.3, 0.4], [0.9, 0.9, 0.9, 0.5, 0.5, 0.5, 0.5]]
	def stamp2(lists):
		counter = count()
		group_index = next(counter)
		for i in range(len(lists)):
			m = min(lists[i])
			M = max(lists[i])
			previous = lists[i][0]
			for value in lists[i]:
				if abs(value - previous) >= (M-m)/2.:
					group_index = next(counter)
				yield (group_index, value)
				previous = value
	
	result2 = [list(map(itemgetter(1), group)) for _, group in groupby(stamp2(result), itemgetter(0))]
	print 'realignment:', result2
In Worten: sollte innerhalb einer Subliste die Grenze überschritten werden soll eine Unterteilung erfolgen.
Das Ergebnis meines Codes ist: [[0, 0, 0, 0], [0.2, 0.3, 0.3, 0.4, 0.9, 0.9, 0.9], [0.5, 0.5, 0.5, 0.5]] ABER ich will es so: [[0, 0, 0, 0], [0.2, 0.3, 0.3, 0.4], [ 0.9, 0.9, 0.9], [0.5, 0.5, 0.5, 0.5]]
Was fehlt in meinem Code bzw. was mache ich falsch?

Re: Aufeinanderfolgende Listenelemente vergleichen

Verfasst: Mittwoch 4. September 2019, 10:31
von sparrow
Dann macht es ja keinen Sinn die vorher zu unterteilen, weil man sie hier - um das effizient zu tun - eh wieder ohne die Sublisten arbeiten muss.

Re: Aufeinanderfolgende Listenelemente vergleichen

Verfasst: Mittwoch 4. September 2019, 10:39
von Sirius3
Willst Du nun Listen zusammenfassen, oder nur trennen?
Beispiel: [[0,0.2,0.8],[0.8,0.5]] -> [0,0.2], [0.8,0.8], [0.5], wobei sich hier natürlich die Frage stellt, unter welcher Bedingung Listen zusammengefasst werden sollen?

Sonst mischst Du hier zwei Probleme.
1. Gehe eine Liste von Listen durch.
2. Spalte diese Liste auf
3. Fasse alle Ergebnislisten wieder zu einer Liste von Listen zusammen.

Zum Code allgemein:
Eingerückt wird immer mit 4 Leerzeichen pro Ebene, keine Tabs.
Variablennamen sollten aussagekräftig sein, ein kleines und ein großes M sind es nicht und unterscheiden sich auch nicht gut genug, als dass man da durcheinander kommen könnte.
Schleifen über einen Index macht man nicht, weil man in Python auch direkt über die Elemente iterieren kann.

Ohne was am verhalten zu ändern, könnte die Funktion so aussehen:

Code: Alles auswählen

def stamp2(lists):
    group_index = 0
    for values in lists:
        threshold = (max(values) - min(values)) * 0.5
        previous = values[0]
        for value in values:
            if abs(value - previous) >= threshold:
                group_index += 1
            yield (group_index, value)
            previous = value

Re: Aufeinanderfolgende Listenelemente vergleichen

Verfasst: Mittwoch 4. September 2019, 10:47
von Ede1994
Danke für die Tips bzgl. des Codes! Das mit den TABS werde ich wahrscheinlich nie ändern, bin das einfach so gewohnt bzw. mir wurde das eben so beigebracht :D

Zum Problem:
Ich möchte die Listen im Prinzip nochmal trennen, so wie du das auch in deinem Beispiel aufgeschrieben hast.

Re: Aufeinanderfolgende Listenelemente vergleichen

Verfasst: Mittwoch 4. September 2019, 10:54
von Sirius3
Mein Beispiel faßt zwei Listen zusammen.

Wenn Du nur Listen trennen willst, mußt Du im Prinzip nur eine Zeile verschieben.

Re: Aufeinanderfolgende Listenelemente vergleichen

Verfasst: Mittwoch 4. September 2019, 11:36
von Ede1994
[[0, 0, 0, 0, 0.2, 0.3, 0.3, 0.4], [0.9, 0.9, 0.9, 0.5, 0.5, 0.5, 0.5]] --> [[0, 0, 0, 0], [0.2, 0.3, 0.3, 0.4], [ 0.9, 0.9, 0.9], [0.5, 0.5, 0.5, 0.5]]
sorry für die Unklarheiten! Was ich meine ist Listen trennen, also am Beispiel: in der 2. Subliste ändert sich der Wert von 0.9 auf 0.5 und an dieser Stelle soll die Liste aufgespalten werden.

Was meinst Du mit 'eine Zeile verschieben'?