Seite 1 von 2

Denk Fehler in list comprehension ?

Verfasst: Donnerstag 4. Juni 2009, 13:42
von feldmaus
Hey Pythoner, :-)

Ich wollte für mein Programm List comprehension nutzen in der folgenden
form, was aber nicht funktioniert,

Code: Alles auswählen

z = np.zeros((3,3))
[(z[0] = i) for i in np.arange(1,600,256)]
  File "<stdin>", line 1
    [(z[0] = i) for i in np.arange(1,600,256)]
           ^
SyntaxError: invalid syntax
Hat Jemand ne Idee was ich falsch mache ?

Grüße Markus

Verfasst: Donnerstag 4. Juni 2009, 14:00
von EyDu

Code: Alles auswählen

[z[0] == i for i in np.arange(1,600,256)]
?

Verfasst: Donnerstag 4. Juni 2009, 14:00
von HerrHagen
Du machst eine Zuweisung innerhalb deiner List Comprehension. Das geht nicht. List comprehensions sind dazu da schnell Listen zu erzeugen. Sie sind im Grunde Abkürzungen für so etwas:

Code: Alles auswählen

l = []
for i in list_to_iterate:
     l.append(XXX)

# ist in etwa equivalent zu:

l = [XXX for i in list_to_iterate]
Ich formulier dein Beispiel also mal ein bisschen um:

Code: Alles auswählen

z = np.zeros((3,3))
l = []
for i in np.arange(1,600,256)]:
    l.append(z[0] = i)
Siehst du jetzt den Fehler?
Entweder wolltest du auf Gleichheit testen, dann müsstest du nur = durch == ersetzen; oder du wolltest bestimmte Elemente in deinem Array z setzten. Dann solltest du auch eine richtige Schleife machen (oder schauen ob numpy schon eine fertige Funktion dafür hat - was meist der Fall ist (dazu müsstest du allerdings sagen was du machen willst)).

MFG HerrHagen

Verfasst: Donnerstag 4. Juni 2009, 14:02
von DasIch
Eine Zuweisung ist keine Expression, außerdem gibt die sowieso nichts zurück womit man eine Liste erstellen könnte.

Verfasst: Donnerstag 4. Juni 2009, 14:30
von feldmaus
HerrHagen hat geschrieben:Dann solltest du auch eine richtige Schleife machen (oder schauen ob numpy schon eine fertige Funktion dafür hat - was meist der Fall ist (dazu müsstest du allerdings sagen was du machen willst)).
Danke für Eure Antworten,

ich wollte eine Zuweisung bzw. vielleicht besser

Code: Alles auswählen

[(z[0] += i) for i in np.arange(1,600,256)]
Welche numpy Funktion gäbe es denn da, ich suche schon seit einiger zeit.

Code: Alles auswählen

[(np.add(z[0],i)) for i in np.arange(1,600,256)]
Käme dem am nächsten, aber dieser arbeitet auch nur mit einer Kopie.

Grüße Markus

Verfasst: Donnerstag 4. Juni 2009, 14:39
von EyDu
Wenn du eine Zuweisung machen möchtest, dann willst du wirklich eine Schleife. Eine LC ist in diesem Fall vollkommen deplatziert. Damit will man Listen erzeugen und nicht for-Schleifen ersetzen.

Ich weiss ja nicht ob es funktioniert, ...:

Code: Alles auswählen

z[0] += sum(np.arange(1,600,256))
Vielleicht bietet sich auch eine geschlossene Form an?

Verfasst: Donnerstag 4. Juni 2009, 22:53
von feldmaus
EyDu hat geschrieben:Ich weiss ja nicht ob es funktioniert, ...:

Code: Alles auswählen

z[0] += sum(np.arange(1,600,256))
Vielleicht bietet sich auch eine geschlossene Form an?
Also np.sum geht nicht, da es Axis weise addiert und nicht Element weise.

Was meinst Du mit einer geschlossenen Form ?

Ich bräuchte was wo ich mehrere Axis Element weise addieren könnte,
also np.add(a,b,c,d,e,f,g) nur das geht nicht weil, die
add funktion nur zwei axis element weise addiert, also z.b. das hier geht:

Code: Alles auswählen

a=np.array([1,2])
b=a
np.add(a,b)
[2 4]
Aber das hier geht nicht np.add(a,b,c,d,e,f,g), weil die
add funktion nur zwei Vektor Achsen element weise addiert, daher geht
das folgende nicht:

Code: Alles auswählen

a=np.array([1,2])
b=a
c=a
np.add(a,b,c)
[2 4]
Grüße Markus

Verfasst: Donnerstag 4. Juni 2009, 23:38
von BlackJack
@feldmann_markus: Es mag sein, das `np.sum()` nicht geht, das hat EyDu aber auch gar nicht verwendet.

Kannst Du vielleicht mal ein Beispiel zeigen, was Du *wirklich* haben möchtest? Möglichst nicht nur Lösungen die nicht funktionieren, sondern das eigentliche Problem. Am besten mit einer genauen Beschreibung der Eingabe und auch der gewünschten Ausgabe.

Denn was EyDu gezeigt hat, ist eine Lösung für ``[(z[0] += i) for i in np.arange(1,600,256)]``. Wir können ja nichts dafür, dass unsere Lösungen Dich nicht weiterbringen, wenn Du uns das falsche Problem beschreibst. :-)

Verfasst: Freitag 5. Juni 2009, 00:51
von feldmaus
Mein Prof. hatte mal wieder einen extra Wunsch. :(

Ich versuche nur das nötigste zu erklären, sonst bist Du(BlackJack) und
CM wieder die einzigsten die mir helfen. :-)

hier mein Code,
http://pastebin.com/m4c48bf22
In zeile 9+10 sind for Schleifen. die erste Schleife
hat 256 Durchgänge und die zweite Schleife geht wenn z.b. meine
gesamte Messung 8sek hatte --> 8sek/20ms=400 mal.

nun die Erklärung,
es geht um ein Histogramm welches x,y und z werte hat.

Meine schon vorliegenden Daten enthalten xy Paare, also
x für die zeit und y für die Amplitude nur das ich pro x Wert
y1,y2 und y3 habe und nicht nur einen y Wert, also
y1(x),y2(x),y3(x)

Die x-Achse geht von range(1,256+1), also 256 Schritte
und soll ein sich wiederholendes Zeitraster darstellen.
Dafür muss ich mein ursprünglichen Zeitvektor x neu zuordnen.
256 Schritte sind 20ms, wobei sich die 20ms wiederholen bis
zum ende meines Zeitvektors.

Die y-Achse geht vom niedrigsten Wert bis zum höchsten Wert
,in meinen Amplituden Datensätzen, in insgesamt 256 Schritten.

Der Z Wert stellt die Häufigkeit von Werten in meinen Daten dar
und besitzt die Dimension,
np.zeros((256,256))

Da ich in meinen Daten mehrmals die gleiche Amplituden habe, muss
ich die gleich großen Amplituden ZÄHLEN und die Anzahl der
gefunden gleichen Amplituden im entsprechenden Zeitfeld(x) und im
entsprechenden Amplituden Feld(y) in meine z Matrix schreiben.

Mein Zuordnung's Vektor stellt so eine Art Filter dar, der mir die richtigen
Amplituden wieder gibt, also eine Maske. Es sind ja schließlich nicht in alle
meiner 20ms Raster Amplituden vorhanden.

So ich hoffe es sind alle verwirrt. :-)
Hier ein Beispiel wie x,y und z ausehen würden:
http://pastebin.com/m198f3fe1

Mit den x,y,z Daten plotte ich eine Graphic die dann etwa so aussehen soll,
http://matplotlib.sourceforge.net/examp ... _demo.html

Hier noch ein Hand Skizze wie ich mir das vorstelle,
http://img38.imageshack.us/img38/448/histogram.jpg
bzw. falls das nicht funktioniert,
http://www.instantgallery.de/galerie/23 ... 18377.html

Ich hoffe ich habe nix vergessen.

Wichtig ist halt das ich die Anzahl der gleich großen Amplituden
zählen muss, und das geht so weit ich das sehen kann nur durch
...keine Ahnung ?

Grüße Markus

Verfasst: Freitag 5. Juni 2009, 09:39
von feldmaus
Ich stelle hier noch mal die nötigen variablen dar, die man braucht um meine
Funktion zu testen:
http://pastebin.com/m3fdadb08

Grüße Markus

Verfasst: Freitag 5. Juni 2009, 12:20
von feldmaus
So habe nun doch noch einen neuen Algoritmus hinbekommen, der
wesentlich schneller ist, dieser versucht zu jeder Zeit in meinem Zeitvektor
eine Zurdnung zu machen.
http://pastebin.com/m5e9619b6

Grüße Markus

Verfasst: Freitag 5. Juni 2009, 12:22
von BlackJack
Ich habe bis jetzt erst kurz (über die vorherige Lösung) drübergeschaut und mir ist das hier aufgefallen: ``a[np.logical_and(zuordnung==i,zuordnung==i)]``. Das scheint mir eine recht komplizierte Art zu sein ``a[zuordnung == i]`` zu schreiben. Denn ``x == x & x`` gilt bei ganzen Zahlen und Wahrheitswerten immer.

Verfasst: Freitag 5. Juni 2009, 12:48
von feldmaus
BlackJack hat geschrieben:...Das scheint mir eine recht komplizierte Art zu sein ``a[zuordnung == i]`` zu schreiben. Denn ``x == x & x`` gilt bei ganzen Zahlen und Wahrheitswerten immer.
Ja das hatte mich auf genervt, aber np.logical_and benötigt 2 Argumente nicht mehr und nicht weniger. :-(
Mein jetziger Algorithmus ist bei weitem schneller, allerdings ist die
Zuordnung von x, y in Bezug auf z verdreht, also ich bekomme in meiner Grafik:
X
|
|
|
|
|
o------------------Y
Aber ich hätte lieber
Y
|
|
|
|
|
o------------------X

Kann ich meine z Matrix irgendwie tauschen, also aus,
[[1,2,3],
[7,0,0],
[3,0,4]]

mache dies,
[[4,0,3],
[0,0,2],
[3,7,1]]
??

Grüße Markus

Verfasst: Freitag 5. Juni 2009, 13:51
von feldmaus
Hmm ich dachte zwar ich müsste mein z über die Nebendiagonale klappen,
aber anscheinend musste ich es doch über die Hauptdiagonale klappen.

Also,
np.transpose(z)
hat es gebracht.

Grüße Markus

Verfasst: Freitag 5. Juni 2009, 14:32
von feldmaus
Mist, bei 83 Tausend scheint er schon viel zu stark überlastet zu sein.
Sieht da Jemand noch eine Möglichkeit meinen code zu optimieren ?

Ich habe ja noch eine Schleife drinne,

Code: Alles auswählen

for j in np.arange(len(self.daten[0])):
            i = int(256*math.modf(self.daten[0][j]/self.rastertime)[0])
            z[i] += np.histogram([vektor[j] for vektor in np.abs(self.daten[2])]
                                ,bins=256,range=(u,o))[0]

Verfasst: Freitag 5. Juni 2009, 14:46
von feldmaus
Gibt es denn sowas wie,

Code: Alles auswählen

y1 = np.arange(256)
y2=y1
z = np.zeros((256,256))
z[0:2] = [y1,y2]
Sodass ich keine Schleife brauche um y1, y2 nacheinander zu z zu addieren.

Verfasst: Freitag 5. Juni 2009, 14:48
von EyDu

Code: Alles auswählen

abs_data = np.abs(self.daten[2])
for j, data in enumerate(self.daten[0]):
    i = int(256*math.modf(data/self.rastertime)[0])
    z[i] += np.histogram([vektor[j] for vektor in abs_data] ,bins=256,range=(u,o))[0]
Vielleicht könnte man die LC auch durch einen Generator ersetzen, ich habe mir die Schnittstelle nicht angeschaut.

Verfasst: Freitag 5. Juni 2009, 15:41
von feldmaus
Die np.abs() Funktion scheint unmengen Resourcen zu verschleudern, aber
irgendwie brauche ich die...

Performance geht vor, hatte mein Prof. gesagt !
Wie muss man komplexe Zahlen in np.histogram() verstehen ?

Verfasst: Freitag 5. Juni 2009, 16:16
von BlackJack
@feldmann_markus: Kannst Du vielleicht mal ein kleines, in sich geschlossenes Beispiel mit Eingabedaten zeigen und Ausgabedaten die irgendwie was enthalten, so dass man auch nachvollziehen kann, ob man bei Veränderungen am Quelltext auch wirklich immer noch das gleiche Ergebnis bekommt?

Dein letztes Beispiel mit den Daten musste man nämlich noch ein wenig ändern, dass man es wirklich laufen lassen konnte und das Ergebnis von `z` sah ziemlich eintönig aus:

Code: Alles auswählen

array([[ 2.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       ...,
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.]]

Verfasst: Freitag 5. Juni 2009, 16:59
von feldmaus
Danke BlackJack,

hier mal ein minimal Beispiel,
http://pastebin.com/m29810f5b

In meinem Programm hatte er die komplexen Variablen o,u akzeptiert,
nur in diesem Beispiel macht es mir ärger. Den Fehler konnte ich nicht
finden.

Danke und Grüße Markus