Hallo.
Folgendes Problem:
Ich habe ein Array. Jede Zeile ist eine Liste mit 16384 Werten. Nun möchte ich gerne die Listen löschen, welche die Zahlen 300.0 und -300.0 enthalten. Ich habe bereits etwas im Internet gefunden, verstehe aber den Algo nicht so wirklich. Hab ihn mal hier rein gestellt:
[codebox=python file=Unbenannt.txt]
for i in test:
if not (300.0 and -300.0 in i):
try:
test1 = np.vstack((test1, i))
except NameError:
test1 = i
test = test1
[/code]
test ist soll hier mein Array sein.
Könnt ihr mir vllt helfen!!??
Listen mit Wert x aus Array löschen
@Ede1994: Der Name `i` geht hier gar nicht. Das ist maximal verwirrend `i` in einer Schleife für etwas anderes als ganze Zahlen zu verwenden.
Die ``if``-Bedingung ist falsch. ``and`` ist kein umgangssprachliches ”und” sondern ein binärer Operator der den Wert links davon mit dem Wert rechts davon verknüpft. Links steht ``300.0`` und das ist *immer wahr*. Und rechst steht ``-300.0 in i`` und das ist wahr wenn -300.0 in `i` vorkommt und unwahr wenn es nicht darin vorkommt. Letztlich steht da effektiv also nur ``if not -300.0 in i:``. Du musst schon beide Bedingungen explizit prüfen.
Immer wieder `np.vstack()` aufzurufen mit immer grösser werdenen Teilergebnissen ist ineffizient weil ja jedes mal die bisherigen Daten plus das neue `i` im Speicher umherkopiert werden müssen.
An der Stelle wäre jetzt interessant wie `test` denn nun tatsächlich aussieht. Ist das eine Liste mit Listen? Oder eine Liste mit Numpy-Arrays? Oder schon komplett ein zweidimensionales Numpy-Array? Das hat Einfluss darauf welche Lösung man hier wählen würde, weil man mit Numpy-Arrays deutlich anders umgeht als mit Python-Listen. Wenn man nämlich Numpy-Arrays verwendet, dann tut man das ja in der Regel wegen der Methoden/Funktionen die Numpy bietet, damit so viel wie möglich damit und nicht in Python-Bytecode passiert.
Edit: Mal als Beispiel wie man das bei einem Numpy-Array lösen könnte:
Die ``if``-Bedingung ist falsch. ``and`` ist kein umgangssprachliches ”und” sondern ein binärer Operator der den Wert links davon mit dem Wert rechts davon verknüpft. Links steht ``300.0`` und das ist *immer wahr*. Und rechst steht ``-300.0 in i`` und das ist wahr wenn -300.0 in `i` vorkommt und unwahr wenn es nicht darin vorkommt. Letztlich steht da effektiv also nur ``if not -300.0 in i:``. Du musst schon beide Bedingungen explizit prüfen.
Immer wieder `np.vstack()` aufzurufen mit immer grösser werdenen Teilergebnissen ist ineffizient weil ja jedes mal die bisherigen Daten plus das neue `i` im Speicher umherkopiert werden müssen.
An der Stelle wäre jetzt interessant wie `test` denn nun tatsächlich aussieht. Ist das eine Liste mit Listen? Oder eine Liste mit Numpy-Arrays? Oder schon komplett ein zweidimensionales Numpy-Array? Das hat Einfluss darauf welche Lösung man hier wählen würde, weil man mit Numpy-Arrays deutlich anders umgeht als mit Python-Listen. Wenn man nämlich Numpy-Arrays verwendet, dann tut man das ja in der Regel wegen der Methoden/Funktionen die Numpy bietet, damit so viel wie möglich damit und nicht in Python-Bytecode passiert.
Edit: Mal als Beispiel wie man das bei einem Numpy-Array lösen könnte:
Code: Alles auswählen
In [24]: A
Out[24]:
array([[ 186, 81, 566],
[ 300, 501, 66],
[ 67, 990, 502],
[ 444, -300, 762],
[ 117, 784, 96],
[ 815, 541, 300]])
In [25]: A[~np.any(np.abs(A) == 300, 1)]
Out[25]:
array([[186, 81, 566],
[ 67, 990, 502],
[117, 784, 96]])
In [26]: np.abs(A)
Out[26]:
array([[186, 81, 566],
[300, 501, 66],
[ 67, 990, 502],
[444, 300, 762],
[117, 784, 96],
[815, 541, 300]])
In [27]: np.abs(A) == 300
Out[27]:
array([[False, False, False],
[ True, False, False],
[False, False, False],
[False, True, False],
[False, False, False],
[False, False, True]], dtype=bool)
In [28]: np.any(np.abs(A) == 300, 1)
Out[28]: array([False, True, False, True, False, True], dtype=bool)
In [29]: ~np.any(np.abs(A) == 300, 1)
Out[29]: array([ True, False, True, False, True, False], dtype=bool)
@Ede1994: Also hast Du gar kein Array sondern eine Liste mit Listen? Diese Unterscheidung sprachlich zu machen ist wichtig, denn mit Listen geht man wie gesagt, deutlich anders um als mit (Numpy-)Arrays. Mit Array meint man in Python meistens Numpy-Arrays. Es gibt aber in der Standardbibliothek auch ein `array`-Modul, und mit dem `ctypes`-Modul kann man Proxy-Objekte für Arrays aus C oder anderen Programmiersprachen erstellen. Darum ist es wichtig Listen nicht als Arrays zu bezeichnen, weil das zu Verwirrung führt.
Du hast jetzt zwei Möglichkeiten: Entweder die Liste mit den Listen in ein Numpy-Array zu wandeln, und dann etwas in der Richtung zu machen was ich in meinem letzten Beitrag gezeigt habe, oder Du erstellst erst einmal eine Liste ohne die mit den bestimmten Werten. Da würde sich eine „list comprehension“ anbieten. Wenn am Ende ein Array heraus kommen soll, würde ich wahrscheinlich gleich in ein Array umwandeln und dann Filtern.
Du hast jetzt zwei Möglichkeiten: Entweder die Liste mit den Listen in ein Numpy-Array zu wandeln, und dann etwas in der Richtung zu machen was ich in meinem letzten Beitrag gezeigt habe, oder Du erstellst erst einmal eine Liste ohne die mit den bestimmten Werten. Da würde sich eine „list comprehension“ anbieten. Wenn am Ende ein Array heraus kommen soll, würde ich wahrscheinlich gleich in ein Array umwandeln und dann Filtern.
Also ich habe test so definiert:
[codebox=python file=Unbenannt.txt]
test = np.zeros((len(combs),16384))
data1 = []
for k in range(len(combs)):
data1 = [data[i-1][2] for i in range(combs[k][0], combs[k][1])]
test[k] = data1
[/code]
Ich dachte dann wäre das ein numpy.array. Vllt hätte ich das von Anfang an so aufführen sollen
[codebox=python file=Unbenannt.txt]
test = np.zeros((len(combs),16384))
data1 = []
for k in range(len(combs)):
data1 = [data[i-1][2] for i in range(combs[k][0], combs[k][1])]
test[k] = data1
[/code]
Ich dachte dann wäre das ein numpy.array. Vllt hätte ich das von Anfang an so aufführen sollen

Zuletzt geändert von Anonymous am Montag 15. Mai 2017, 13:51, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
@Ede1994: was ist denn nun combs und data?
Code: Alles auswählen
test = np.array([
data[start-1:ende-1]
for start, ende in combs
])
@Ede1994: Ja, dann ist `test` an ein Numpy-Array gebunden. Dann ist das aber auch nicht von der Form wie Du das beschrieben hast, als [liste 1, liste 2, …], denn es kommen ja keine Listen vor. Wie gesagt, die Unterscheidung ist wichtig.
Und die Frage nach den Typen setzt sich fort, ob nämlich bei dem jetzt gezeigten Code nicht eventuell auch etwas in Python gemacht wird, was man vielleicht eher mit Numpy lösen würde. Selbst in reinem Python ist ``for i in range(len(sequenze)):`` ein „code smell“, weil man direkt über Elemente iterieren kann, ohne den Umweg über einen Index. Falls man den Index *zusätzlich* braucht, gibt es `enumerate()`.
`data1` vor der Schleife an eine leere Liste zu binden macht keinen Sinn. Der Name ist zudem schlecht, und auch überflüssig, weil der nur etwas bringen würde wenn er gut ist. Wenn einem an der Stelle eh nichts gutes einfällt, kann man es sich auch sparen das Zwischenergebnis an einen Wert zu binden.
Von den `combs`-Elementen braucht man das zweite Element nicht, denn da die Länge von `data1` immer 16384 sein *muss*, braucht man für das `range`-Objekt nur einen dieser beiden Werte. Die 16384 würde man dann auch besser als Konstante definieren.
Zwischenstand wäre dann so etwas (ungetestst):
Sollte `data` eine Liste sein, oder etwas anderes das „slicing“ unterstützt, und `i` immer positiv sein, könnte man auch „slicing“ verwenden, statt des `range`-Objektes:
Die Namen sind natürlich alle nicht gut, aber ich weiss ja nicht worum es geht. Und man sollte noch schauen ob sich das mit der Antwort von Sirius3 kombinieren lässt, damit man nicht erst ein Platzhalterarray erzeugt und das füllt, sondern gleich das endgültige Array mit den Werten erstellt.
Und die Frage nach den Typen setzt sich fort, ob nämlich bei dem jetzt gezeigten Code nicht eventuell auch etwas in Python gemacht wird, was man vielleicht eher mit Numpy lösen würde. Selbst in reinem Python ist ``for i in range(len(sequenze)):`` ein „code smell“, weil man direkt über Elemente iterieren kann, ohne den Umweg über einen Index. Falls man den Index *zusätzlich* braucht, gibt es `enumerate()`.
`data1` vor der Schleife an eine leere Liste zu binden macht keinen Sinn. Der Name ist zudem schlecht, und auch überflüssig, weil der nur etwas bringen würde wenn er gut ist. Wenn einem an der Stelle eh nichts gutes einfällt, kann man es sich auch sparen das Zwischenergebnis an einen Wert zu binden.
Von den `combs`-Elementen braucht man das zweite Element nicht, denn da die Länge von `data1` immer 16384 sein *muss*, braucht man für das `range`-Objekt nur einen dieser beiden Werte. Die 16384 würde man dann auch besser als Konstante definieren.
Zwischenstand wäre dann so etwas (ungetestst):
Code: Alles auswählen
ROW_LENGTH = 16384
# ...
test = np.zeros((len(combs), ROW_LENGTH))
for k, comb in enumerate(combs):
start = comb[0] - 1
test[k] = (data[i][2] for i in range(start, start + ROW_LENGTH))
Code: Alles auswählen
test[k] = (xs[2] for xs in data[start:start + ROW_LENGTH])
Ich benutze auch andere Bezeichnungen, darf diese aber nicht öffentlich verbreitern, deswegen diese Alternativen.
Okay. Das lässt sich ändern. Aber zurück zum ursprünglichen Problem..
Könnte ich das Problem jetzt mit:
[codebox=python file=Unbenannt.txt]
test[~np.any(np.abs(A) == 300, 1)]
[/code]
lösen?
Was bedeutet '~' vor np.any?
Okay. Das lässt sich ändern. Aber zurück zum ursprünglichen Problem..
Könnte ich das Problem jetzt mit:
[codebox=python file=Unbenannt.txt]
test[~np.any(np.abs(A) == 300, 1)]
[/code]
lösen?
Was bedeutet '~' vor np.any?
Zuletzt geändert von Anonymous am Montag 15. Mai 2017, 15:38, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
@Ede1994: Ob Du das Problem so lösen könntest, ähm, das hängt davon ab ob das Problem so gelöst werden könnte. 
Der ``~``-Operator ist die bitweise Negation/Invertierung. Als Funktion wäre es `numpy.invert()`.

Der ``~``-Operator ist die bitweise Negation/Invertierung. Als Funktion wäre es `numpy.invert()`.
Also ich dachte jetzt hätte ich es verstanden, also habe ich folgendes gemacht:
Danach wende ich eine FFT auf test an und erhalte jetzt folgende Fehlermeldung (vorher ging es) 
Also stimmt etwas mit dem test nicht!? Verstehe ich nicht wirklich...
Anscheinend funktioniert der Befehl auch nicht. Ich benutze Python 2.7.6 und schreibe den Code in KWrite.
Um es besser zu beschreiben setze ich hier mal mein Array test rein:
In iwelchen Zeilen sind nun Werte -300.0 oder 300.0 eingebunden (digitale Grenze) und diese Zeilen will ich löschen, aber die Struktur muss dieselbe bleiben.
Code: Alles auswählen
test = [np.invert(np.any(np.abs(test) == 300, 1))]

Code: Alles auswählen
ValueError: could not broadcast input array from shape (186) into shape (16384)
Anscheinend funktioniert der Befehl
Code: Alles auswählen
np.invert()
Um es besser zu beschreiben setze ich hier mal mein Array test rein:
Code: Alles auswählen
[[-37.8 -36.7 -36.1 ..., 1.5 4.4 2.1]
[-32. -17.3 -30.2 ..., -61.9 -60.7 -59.5]
[-17.3 -15. -15.5 ..., 6.2 -10.3 6.7]
...,
[-22. -20.2 -10.9 ..., -26.1 -28.4 -28.4]
[ -9.1 -14.4 -11.4 ..., -7.3 -6.7 -1.5]
[ 1.5 3.2 9.7 ..., -12. -10.3 -23.8]]
@BlackJack: was hälst du davon:
Habe damit etwas rumprobiert und funktioniert eigentlich so wie ich das will.
Oder ist das immer noch falsch?
Code: Alles auswählen
test = test[np.all(np.abs(test) != 300.0, axis=1)]
Oder ist das immer noch falsch?

@Ede1994: Schau Dir doch mal an was Du da an `test` bindest. Das ist nicht das was Du willst, aber das ist auch nicht das was ich geschrieben habe. Da fehlt etwas.
Edit: Das bezog sich auf den vorhergehenden Beitrag von Dir. So wie im letzten geht es auch. Schau Dir trotzdem mal an was Du im vorhergehenden Beitrag falsch/nicht gemacht hast.
Edit: Das bezog sich auf den vorhergehenden Beitrag von Dir. So wie im letzten geht es auch. Schau Dir trotzdem mal an was Du im vorhergehenden Beitrag falsch/nicht gemacht hast.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Das macht doch keinen Sinn, Du hast wahrscheinlich eine Liste und jede Zeile ist ein Array mit 16384 Werten, oder?Ede1994 hat geschrieben:Hallo.
Folgendes Problem:
Ich habe ein Array. Jede Zeile ist eine Liste mit 16384 Werten.
Ach so, beim numpy array geht auch array mit jeder Zeile ein Array.
Zuletzt geändert von Alfons Mittelmeyer am Dienstag 16. Mai 2017, 11:23, insgesamt 1-mal geändert.
@Alfons Mittelmeyer: Nein, Ausgangslage ist ein zweidimensionales Array. Das hatten wir weiter oben schon geklärt wo Ede1994 den Code gezeigt hat der das erzeugt.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
@Ede1994:
Was wichtig ist, daß du den index nicht zerstörst,deshalb: von hinten beginnen
Hier ein Beispiel mit einer Liste von arrays. Mußt eben in numpy array abwandeln:
Was wichtig ist, daß du den index nicht zerstörst,deshalb: von hinten beginnen
Hier ein Beispiel mit einer Liste von arrays. Mußt eben in numpy array abwandeln:
Code: Alles auswählen
from array import array
value_list = [ array('i',[ 186, 81, 566]),
array('i',[ 300, 501, 66]),
array('i',[ 67, 990, 502]),
array('i',[ 444, -300, 762]),
array('i',[ 117, 784, 96]),
array('i',[ 815, 541, 300])
]
x1 = 81
x2 = 300
for row_nr in range(len(value_list)-1,-1,-1):
if x1 in value_list[row_nr] or x2 in value_list[row_nr]:
value_list.pop(row_nr)
print(value_list)
@Alfons Mittelmeyer: Och bitte, jetzt fängst Du schon wieder an unnötig komplizierten Code zu schreiben den man so in Python einfach nicht schreiben würde. Der mit Numpy-Arrays auch gar nicht geht, weil die eine feste Grösse haben. Das Problem ist ausserdem schon gelöst. Mit Numpy-Mitteln.