laden von Werten aus binären Dateien schneller machen

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.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

Hi mal wieder, :shock:

ja soll ich die Geschichte bei jedem Thread wieder erzählen ?
Na gut ich mache es. :lol:

Also ich habe 6 binäre Dateien, 3 der binären Daten enthalten 8bit Werte
00000000 ODER 00000001
und die anderen 3 binären Dateien enthalten 32 bit float Werte
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx (Real Teil)
UND
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx (Imag Teil)
(Jedes x ist 0 oder 1)

Also gut, mein Code Schnippsel sieht so aus:
http://nopaste.debianforum.de/21649

Im Prinzip suche ich nach binären 1 in a_p_1, a_p_2 und a_p_3
und falls ich welche finde, dann wird der zeitstempel die vorkommenden
binären 1 und die float Werte in a_pv_1,a_pv_2 und a_pv_3 gespeichert.

Hat jemand einen Verbesserungsvorschlag um Speed zu bekommen ?

Grüße Markus[/url]
Zuletzt geändert von feldmaus am Dienstag 26. Mai 2009, 18:49, insgesamt 1-mal geändert.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Erstmal solltest du deinen Code zusammenfassen ;-)
Dann machst du aus der while-Schleife eine for-Schleife über die Elemente (schau dir mal die zip- und enumerate-Funktion an). Außerdem beachtest du nicht, dass zu wenige Elemente vorhanden sein könnten.
Die Bedingung deines ifs macht sicher nicht das was du erwartest. Du möchtest wohl:

Code: Alles auswählen

if a_p_1[i]==1 or a_p_2[i]==1 or a_p_3[i] == 1:
In diesem Fall sollte es keinen Unterschied machen, dein letztes "==1" ist dann allerdings überflüssig.

Zur Geschwindigkeit: Versuche zunächst einige (oder wenn möglich alle) Einträge zu sammeln und dann in einem Rutsch zu schreiben.
Das Leben ist wie ein Tennisball.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Du kannst sogar die komplette Schleife sparen:

Code: Alles auswählen

from numpy import array
a = array([0, 1, 0, 1, 1])
b = array([0, 0, 1, 1, 1])
criterion = (a == 1) | (b == 1)
a[criterion] # ist array([1, 0, 1, 1])
criterion = (a == 1) & (b == 1)
a[criterion] # ist array([1, 1])
Im Übrigen würde ich wirklich erst empfehlen die Anleitung zu Numpy zu lesen. Kostet erst mal Zeit, spart aber auch viel Zeit.

Tipp: Überdenke noch Deine Datenstruktur: Willst Du wirklich komplexe Zahlen in zwei versch. Arrays handhaben?

HTH
Christian

edit: PS noch ein Tipp: Schau mal numpy.where() an.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Und noch was: Irgendwie liegen Fouriertransformationen in der Luft - auch dafür gibt es Funktionalität in numpy. Aber um zu sagen, wie man das hier anwenden sollte, müsste mich erst einmal Deine Datenstruktur klar werden - und das ist immer noch nicht der Fall, um ehrlich zu sein.

edit: Mir fällt gerade auf, dass 'endtime' gar nicht genutzt wird. Damit wir jetzt nicht jeden Punkt durchgehen, lege ich Dir nochpylint ans Herz.
BlackJack

@feldmann_markus: Ich würde auch versuchen die Operationen von Numpy-Arrays auch auszunutzen, nämlich das man schnell eine Operation auf viele Werte anwenden kann. Statt in einer Python-Schleife über alles drüber zu gehen.

Pickle-Dateien muss man übrigens auch als Binärdateien öffnen, sonst funktionieren die nicht plattformübergreifend.

Die Indexgeschichte bei den Fliesskomma-Arrays brauchst Du auch nicht machen, denn man kann die Form des Arrays nach dem Einlesen verändern, oder als Datentyp gleich zwei float32 angeben.

Die Dateinamen sind übrigens irreführend. Da befinden sich ja keine "hex"-Werte sondern Binärdaten, wobei hier mit Binäre nicht die Zahlendarstellung gemeint ist. Bei '.hex' würde man eher ASCII-Dateien mit einem Hexdump als Inhalt erwarten.

Ich glaube, dass man Dateien mit `open()` und nicht mit `file` öffnen sollte, hatte schon mal jemand gesagt. Ausserdem sollte man Dateien auch explizit wieder schliessen, wenn man mit ihnen fertig ist.

Ungetestet (`itemgetter` aus `operator` und `izip` aus `itertools`):

Code: Alles auswählen

        def read_arrays(filename_template, count, dtype):
            result = list()
            for i in xrange(count):
                with open(filename_template % (i + 1), 'rb') as data_file:
                    result.append(numpy.fromfile, data_file, dtype=dtype)
            return result
        
        time = numpy.arange(start_time, end_time, time_scale)
        a_p = read_arrays('peakdetektor%d.hex', 3, numpy.bool8)
        index = numpy.bitwise_or.reduce(a_p)
        a_pv = read_arrays('peakband%d.hex', 3, [numpy.float32, numpy.float32])
        columns = map(itemgetter(index), [time] + a_p + a_pv)
        for row in izip(*columns):
            print row
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

habe gerade ein anderen Fehler entdeckt der gravierender ist, als diese
Optimierungsgeschichte. cPickle.dump() speichert nur den ersten Eintrag.

Die While Schleife funktioniert und bringt folgendes:

Code: Alles auswählen

Daten sind :  [(1242657470.414943, 1, 1, 1, -0,00018711668, 6,7369081e-05, 0,00015192243, 0,00012836898, 3,5197041e-05, -0,00019567659)]
Daten sind :  [(1242657470.4151578, 0, 0, 1, 0,25889605, 0,23445347, -0,39730105, 0,22318748, 0,046001431, 0,75723344)]
Daten sind :  [(1242657470.4203348, 0, 1, 0, -0,33512717, 0,11990041, -0,70395935, 0,052347224, -0,063446313, 0,6892103)]
Daten sind :  [(1242657470.427618, 0, 1, 0, -0,68027335, -0,2890864, 0,72815531, -0,2082255, -0,29058355, 0,71790695)]
Daten sind :  [(1242657470.4434226, 0, 0, 1, -0,04802268, -0,41406035, 0,36278704, 0,26671827, -0,47323576, 0,2542651)]
Daten sind :  [(1242657470.4500611, 0, 1, 0, -0,10881038, -0,14034382, -0,20965751, 0,43210343, 0,22364943, 0,49613705)]
. . . 
Allerdings ist in der Datei 'f_output' anschließend nur der Eintrag:

Code: Alles auswählen

(1242657470.414943, 1, 1, 1, -0,00018711668, 6,7369081e-05, 0,00015192243, 0,00012836898, 3,5197041e-05, -0,00019567659)
Hat dazu Jemand ne Idee was an meinem cPickle falsch sein könnte ?
Grüße und danke für eure Antworten Markus

p.s.:ich werde versuchen das eine oder
andere Eurer Ideen bis Heute Abend noch um zu setzen
BlackJack

Du schreibst schon alles in die Datei. Das sollte an der Dateigrösse erkennbar sein. Aber wenn Du x-mal was in die gleiche Datei "dump"st, dann musst Du natürlich auch x-mal die `load()`-Methode aufrufen.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Mal geraten: du rufst "load" nur einmal auf, das musst du allerdings für jeden mit "dump" gespeicherten Eintrag wiederholen.
Das Leben ist wie ein Tennisball.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

EyDu hat geschrieben:Mal geraten: du rufst "load" nur einmal auf, das musst du allerdings für jeden mit "dump" gespeicherten Eintrag wiederholen.
Shit.
Ich habe Test weise mal folgendes gemacht:

Code: Alles auswählen

        self.a_dat = (cPickle.load(f_dat))
        print "a_dat[0] ist ",self.a_dat[0]
        self.a_dat = (cPickle.load(f_dat))
        print "a_dat[1] ist ",self.a_dat[1]
        self.a_dat = (cPickle.load(f_dat))
        print "a_dat[2] ist ",self.a_dat[2]
Nur den ersten Datensatz zeigt er mir an, wie oben gepostet:

Code: Alles auswählen

(1242657470.414943, 1, 1, 1, -0,00018711668, 6,7369081e-05, 0,00015192243, 0,00012836898, 3,5197041e-05, -0,00019567659)
Die Datei hat eine Größe von 252285 Bytes. Hier ein Auschnitt des
Anfangs dieser Datei:
http://nopaste.debianforum.de/21474
Dort kann man meine Zeitstempel sehen und zwar mehrere:
also
muss das speichern geglückt sein.
Also kann es nur am laden liegen ?!

Code: Alles auswählen

(F1242657470.414943
...
(F1242657470.4151578
...
(F1242657470.4203348
cnumpy.core.multiarray
Dort steht aber auch was von cnumpy.core.multiarray,
muss ich mir dabei was denken ?

Grüße Markus
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Code: Alles auswählen

dat = cPickle.load(f_dat)
print "dat ist ",self.a_dat[0]
dat = cPickle.load(f_dat)
print "dat ist ",self.a_dat[0]
dat = cPickle.load(f_dat)
print "dat ist ",self.a_dat[0]
?
Das Leben ist wie ein Tennisball.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

EyDu hat geschrieben:

Code: Alles auswählen

dat = cPickle.load(f_dat)
print "dat ist ",self.a_dat[0]
dat = cPickle.load(f_dat)
print "dat ist ",self.a_dat[0]
dat = cPickle.load(f_dat)
print "dat ist ",self.a_dat[0]
?
Genau, genau, genau das brachte die Idee und die Lösung. :-)

Ich werde an dieser Stelle die Klasse posten, wo ich die Daten(1'en,0'en
,32bit float Zahlen) benötige.

http://nopaste.debianforum.de/21655

Funktioniert leider zur zeit noch nicht, da für a,b und c erst die 1'en und
0'en zuordnen muss. :shock:
Zuletzt geändert von feldmaus am Dienstag 26. Mai 2009, 18:56, insgesamt 1-mal geändert.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Du solltest beim "except" noch explizit angeben, welche Fehler behandelt werden sollen, sonst werden wirklich ALLE Fehler abgefangen und unter Umständen Fehlermeldungen verschluckt, welche dich interessieren.
Das Leben ist wie ein Tennisball.
BlackJack

Und schon wieder `file` statt `open`. Ausserdem solltest Du mal über das Speicherformat nachdenken. Ich würde ja die Daten in einer Klasse kapseln und nicht "Zeilenweise" speichern, sondern die Spalten als einzelne Arrays belassen, denn später brauchst Du sie ja anscheinend auch wieder in dem Format. So hast Du wieder "langsame" Python-Schleifen beim speichern und einlesen. Ach ja: Pickle Dateien sind Binärdaten, auch wenn man sie halbwegs lesen kann. Habe ich aber auch schon erwähnt.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

BlackJack hat geschrieben:Und schon wieder `file` statt `open`. Ausserdem solltest Du mal über das Speicherformat nachdenken. Ich würde ja die Daten in einer Klasse kapseln und nicht "Zeilenweise" speichern, sondern die Spalten als einzelne Arrays belassen, denn später brauchst Du sie ja anscheinend auch wieder in dem Format. So hast Du wieder "langsame" Python-Schleifen beim speichern und einlesen. Ach ja: Pickle Dateien sind Binärdaten, auch wenn man sie halbwegs lesen kann. Habe ich aber auch schon erwähnt.
+open statt file verwenden(erledigt)
+Speicherformat(erledigt)
+Nicht Zeilenweise speichern(erledigt)
+Schleife beim einlesen beseitigen(erledigt)

Hier meine veränderter Code:
http://nopaste.debianforum.de/21650

Ich bin allerdings mit der Methode 'extrahierePeaks()' noch nicht
ganz zu frieden, da diese nicht komplett mit numpy arbeitet. Ich
habe das append bei numpy.array's nicht hinbekommen, vielleicht ist
es aber auch schon zu spät für mich. :-)
http://nopaste.debianforum.de/21652

Vielleicht könnte mir Jemand mit numpy.append() ein kleines beispiel
posten ?

Grüße und danke für die Hilfe Markus
Zuletzt geändert von feldmaus am Dienstag 26. Mai 2009, 18:51, insgesamt 1-mal geändert.
BlackJack

@feldmann_markus: Das ``count=-1`` bei `numpy.fromfile()` ist die Vorgabe, das braucht man also nicht explizit hinschreiben. Andererseits könntest Du an der Stelle vielleicht auch die Dateigrösse bzw. wieviele Elemente in der Datei sind feststellen und dann das Minimum davon und 1000 nehmen und gleich nur maximal 1000 Werte pro Datei einlesen, statt alles in den Speicher zu laden und erst danach alles über 1000 wieder weg zu werfen.

Wozu brauchst Du ein `append()` bei den `numpy.array`\s? Sowohl CM als auch ich haben Quelltext gezeigt, der ein Boolean-Array als Index verwendet um alle Zeilen auszuwählen, bei denen `True` steht. Und die Oder-Verknüpfung, die Du in einer Schleife mit jeder Zeile einzeln machst, kann man als bitweises Oder direkt auf einem ganzen Array durchführen.

Code: Alles auswählen

In [225]: a
Out[225]: array([ True, False, False], dtype=bool)

In [226]: b
Out[226]: array([ True, False,  True], dtype=bool)

In [227]: a | b
Out[227]: array([ True, False,  True], dtype=bool)

In [228]: numpy.bitwise_or.reduce([a, b])
Out[228]: array([ True, False,  True], dtype=bool)

In [229]: c
Out[229]:
array([[ 0.,  1.],
       [ 2.,  3.],
       [ 4.,  5.]], dtype=float32)

In [230]: c[a | b]
Out[230]:
array([[ 0.,  1.],
       [ 4.,  5.]], dtype=float32)
Dazu müssten die "Band"-Daten natürlich so vorliegen, dass nicht zwei aufeinanderfolgende Elemente zusammengehören, sondern das die Indices in das Array, zu denen in den "Peak"-Daten passen. Drei Möglichkeiten das zu erreichen:

• Nach dem Einlesen die Form des Arrays ändern, so dass ein zweidimensionales draus wird, wie in den Beispielen oben,

• als Typ *zwei* 32-Bit-Floats angeben,

• oder ein 64-Bit-Complex.

Code: Alles auswählen

In [252]: s
Out[252]: '\x00\x00\x00\x00\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@\x00
\x00\xa0@'

In [253]: numpy.fromstring?
Type:           builtin_function_or_method
Base Class:     <type 'builtin_function_or_method'>
String Form:    <built-in function fromstring>
Namespace:      Interactive
Docstring:
    fromstring(string, dtype=float, count=-1, sep='')

    Return a new 1d array initialized from the raw binary data in string.

    If count is positive, the new array will have count elements, otherwise its
    size is determined by the size of string.  If sep is not empty then the
    string is interpreted in ASCII mode and converted to the desired number type
    using sep as the separator between elements (extra whitespace is ignored).


In [254]: x = numpy.fromstring(s, dtype=numpy.float32)

In [255]: x
Out[255]: array([ 0.,  1.,  2.,  3.,  4.,  5.], dtype=float32)

In [256]: x.shape = (len(x) // 2, 2)

In [257]: x
Out[257]:
array([[ 0.,  1.],
       [ 2.,  3.],
       [ 4.,  5.]], dtype=float32)

In [258]: x = numpy.fromstring(s, dtype='f4,f4')

In [259]: x
Out[259]:
array([(0.0, 1.0), (2.0, 3.0), (4.0, 5.0)],
      dtype=[('f0', '<f4'), ('f1', '<f4')])

In [260]: x = numpy.fromstring(s, dtype=numpy.complex64)

In [261]: x
Out[261]: array([ 0.+1.j,  2.+3.j,  4.+5.j], dtype=complex64)
`a_time` würde ich nicht mitspeichern, wenn man das aus den anderen Daten wieder rekonstruieren kann. Scheint ja nur von der Länge abzuhängen.

Und auch wenn man mehrere Objekte hintereinander "picklen" kann, würde ich trotzdem nur eines "picklen", sprich alles zu einem Tupel zusammenfassen und das dann in die Datei schreiben.

Oder noch besser: die Daten in einer eigenen Klasse kapseln, dann verschwindet auch ein Teil Geschäftslogik aus den GUI-Klassen.

Bei Dateien ist ein `flush()` übrigens in einem `close()` enthalten.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

  • 1.)count-1 entfernt, da eh default(erledigt)
  • 2.)nur bestimmte Anzahl oder bestimmte Menge an Daten
    einlesen<gute Idee>.(offen)
  • 3.)logische numpy.verknüpfungen benutzen statt list.append,
    dafür versuche ich die Band-Daten als 64bit complex Werte
    einzulesen.(offen)
  • 4.)Nur einmal pickle.dump und einmal pickle.load anwenden.(offen)
  • 5.)flush() entfernen (erledigt)
  • 6.) a_time kann nicht entfernt werde, da es nicht mehr rekonstruiert
    werden kann, so bald die Daten extrahiert wurden. Die Peaks entstehen
    zu zufälligen Zeiten. Ok es wäre möglich aber ich brauche die zeiten
    ständig als x-Werte. Das rekonstruieren würde nur über die extrahieren
    Methode wieder möglich sein, also zu aufwändig.
Zu 3.) Irgendwie lädt er die Daten bei mir nicht als 64bit complex ein.

Code: Alles auswählen

        f_output = open('../../../peakswerteundzeit.dat','wb')
        f_p_1 = open('../../../peakdetektor1.hex','rb')
        f_p_2 = open('../../../peakdetektor2.hex','rb')
        f_p_3 = open('../../../peakdetektor3.hex','rb')
        f_pv_1 = open('../../../peakband1.hex','rb')
        f_pv_2 = open('../../../peakband2.hex','rb')
        f_pv_3 = open('../../../peakband3.hex','rb')
        a_p_1 = numpy.fromfile(f_p_1,dtype='b')
        a_p_2 = numpy.fromfile(f_p_2,dtype='b')
        a_p_3 = numpy.fromfile(f_p_3,dtype='b')
        a_pv_1 = numpy.fromfile(f_pv_1,dtype='f')
        a_pv_2 = numpy.fromfile(f_pv_2,dtype='f')
        a_pv_3 = numpy.fromfile(f_pv_3,dtype='f')
        a_pv_1test = numpy.fromfile(f_pv_1,dtype='f8')
        a_pv_2test = numpy.fromfile(f_pv_2,dtype='f8')
        a_pv_3test = numpy.fromfile(f_pv_3,dtype='f8')
        print "Länge von a_pv_1[0] ist ",len(a_pv_1)
        print "Länge von a_pv_1test[0] ist ",len(a_pv_1test)
Dies gibt mir dann nur folgendes aus:

Code: Alles auswählen

Länge von a_pv_1[0] ist  1023752
Länge von a_pv_1test[0] ist  0
Wo stehen welche gültigen dtypes es gibt auf der numpy Homepage ?
http://docs.scipy.org/doc/numpy/referen ... ight=dtype
Bei mir scheinen aber keine Datentypen meinen Test Vektor mit 64bit
Werten zu füllen. Hat Jemand ne Idee was ich falsch mache ?

Ist 'f8' das gleiche wie numpy.complex64 ?

Danke und Grüße Markus
BlackJack

@feldmann_markus: Zu 6.): Du bräuchtest doch nur Anfangs-, Endwert und Schrittweite zu speichern, wenn die Zeiten Fliesskommazahlen sind, lässt sich mit diesen drei Angaben doch ganz einfach mit `numpy.arange()` wieder ein Array erstellen. Was das zu aufwändig angeht: Wenn man diese ganzen Daten in eine Klasse wegkapselt, die weiss wie sie sich selbst speichern und auch wieder laden kann, dann bekommt man davon "aussen" doch gar nicht mit welche Daten gespeichert werden, solange am Ende nur alle wieder da sind.

Zu 3.): Dateien funktionieren so ein bisschen wie ein Tonband. Es gibt einen Dateizeiger der immer weitergesetzt wird, wenn etwas gelesen wird. Du liest die Datei einmal komplett ein und dann steht dieser Zeiger ganz am Ende. Jeder weitere Leseversuch am Ende ergibt "nichts".

Der Typcode 'f8' ist auch nicht das was Du willst, das ist *ein* Float mit 8 Byte. Die beiden Alternativen hatte ich ja schon gezeigt: Zwei Floats mit 4 Byte oder den Typ für 64-Bit-Complex.

Gehören `a_p_1` und `a_pv_1` semantisch eigentlich zusammen? Könnte man dann auch noch mal in einer eigenen Klasse kapseln. Und sind das immer *drei*? Könnte man das nicht generischer für `n` Datensätze implementieren? Durchnummerierte Namen machen mich immer ein wenig nervös. :-)
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

BlackJack hat geschrieben:@feldmann_markus: Zu 6.): Du bräuchtest doch nur Anfangs-, Endwert
und Schrittweite zu speichern, wenn die Zeiten Fliesskommazahlen sind,
lässt sich mit diesen drei Angaben doch ganz einfach mit `numpy.arange()` wieder ein Array erstellen.
Es fallen doch beim extrahieren viele Werte weg, dadurch ändert sich die
Länge der Vektoren. Meine jetzigen test Die Dateien haben über
500000 Elemente. Die extrahierten Vektoren haben dann nur noch ein
paar tausend. Da stimmt beim zurückrechen der zeitstempel nicht mehr.
Hier mal ein Beispiel. Folgende Datensätze liegen vor:
Peak Vektor 1 = [1 0 0 0]

Peak vektor 2 = [1 0 0 0]

Peak Vektor 3 = [1 0 0 0]

Peak Werte von Band 1 = [ -1.87116675e-04 +6.73690811e-05j
-3.73210933e-05 +3.46032903e-05j
-3.82515136e-04 +5.63763548e-04j
-4.02121572e-04 -1.19002536e-04j]

Peak Werte von Band 2 = [ 0.00015192+0.00012837j
0.00011291+0.00010157j 0.00028497+0.00023856j
0.00012447+0.00010121j]

Peak Werte von Band 3 = [ 3.51970411e-05 -1.95676592e-04j
9.59062163e-05 -6.19327839e-05j
-1.20625962e-04 -1.87798141e-04j
1.16560026e-04 -2.71860717e-05j]

Wenn Du jetzt wüßtest das Die Messung bei 0 sek gestartet hat und
bei 600sek zu Ende war und es 500000 Werte gab, wie würdest
Du da die Zeit für die Werte aus den obigen Vektoren bestimmen ?

Wenn Dir nur diese Vektoren bekannt sind ohne den Zeit Vektor, wie willst
Du da auf die zeit zurück schließen. Die werte die ich extrahiere haben
ja keinen regelmäßigen Zeitabstand zueinander.

Hat man allerdings den Zeit Vektor:
Zeit werte = [0.0, 2.1489643551474629, 53.919469274609071, 126.74982487451582]
dann ist das zuordnen gleich viel leichter und ich brauche die Zeit Werte
für die x-Achse. An diesem Zeitvektor kannst man erkennen das
zwischem dem ersten und zweiten Peak nur c.a. 2 sek vergehen,
dagegen liegt zwischen dem zweiten und dritten peak 51 sek.
ich habe die Elemente in dem zeit Vektor mit 10000 multipliziert, damit
ich das besser bei dem bar() Elementen darstellen kann.
BlackJack hat geschrieben:Zu 3.): Dateien funktionieren so ein bisschen wie ein Tonband.
Gute Erklärung. :-)
BlackJack hat geschrieben:Der Typcode 'f8' ist auch nicht das was Du willst,
Ok ich werde <numpy.complex64> nutzen.
Er gibt mir aber Fehler rauß:
TypeError: only integer arrays with one element can be converted to an index

Der Code dazu sieht jetzt so aus:
http://nopaste.debianforum.de/21653
BlackJack hat geschrieben:Gehören `a_p_1` und `a_pv_1` semantisch eigentlich zusammen?

Ja die a_p_1 zeigt nur ob es sich um einen gemessenen Peak Wert handelt
und a_pv_1(array_peakvalue_1) gibt den Wert des Peaks an.
BlackJack hat geschrieben:Könnte man dann auch noch mal in einer eigenen Klasse kapseln.
Ich fand die Lösung mit alle Zeit werte in einen Vektor und alle Peak
Werte in einen Vektor schon ziemlich gut. Das erleichtert die Erstellung
des Graphen ungemein.
BlackJack hat geschrieben:Und sind das immer *drei*? Könnte man das nicht generischer für `n` Datensätze implementieren? Durchnummerierte Namen machen mich immer ein wenig nervös. :-)
Da hast Du auch einen wichtigen Punkt angesprochen. Zur zeit sind
es immer 3 Frequenzbereiche, also 3 Bänder. Dies könnte sich aber noch ändern. Sehe ich aber erstmal als optional an.
Zuletzt geändert von feldmaus am Dienstag 26. Mai 2009, 18:53, insgesamt 1-mal geändert.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

CM hat geschrieben:Du kannst sogar die komplette Schleife sparen:

Code: Alles auswählen

from numpy import array
a = array([0, 1, 0, 1, 1])
b = array([0, 0, 1, 1, 1])
criterion = (a == 1) | (b == 1)
a[criterion] # ist array([1, 0, 1, 1])
criterion = (a == 1) & (b == 1)
a[criterion] # ist array([1, 1])
.
Das funktioniert aber nur mit meine Vektoren wo nur 1'en und 0'en
drinnen sind also a_p_{1,3} ? Oder sehe ich das falsch ???

Aber nicht mit meinem Zeit Vektor a_time und meine Peak werte
Vektoren a_pv_{1,3}. Die Idee ist gut, aber wenn ich bei a_p_{1,3}[1]
elimiere dann muss ich das mit a_pv_{1,3}[1] und a_time[1] auch
machen.

Könnte mir da Jemand einen Tipp geben, wie ich das mit numpy
machen kann ?

Grüße Markus
BlackJack

@feldmann_markus: Argh. An das Filtern der Daten und dass die Zeitstempel dann nicht mehr so schön regelmässig sind, habe ich nicht gedacht. :oops:

Mit dem `dtype` 'b1' (oder `numpy.bool8`) bekommst Du gleich ein Boolean-Array, andererseits kannst Du auch die bitweise Oder-Verknüpfung mit den Zahlen machen und dann im Anschluss mit `astype()` in ein Boolean-Array umwandeln. 0 wird dann zu `False` und 1 zu `True`. Also:

Code: Alles auswählen

        criterion = (a_p_1 | a_p_2 | a_p_3).astype(numpy.bool8)
Bei der ``while``-Schleife würde ich nich versuchen mit `numpy.arange()` ein entsprechendes Array zu basteln und daraus dann auch mit `criterion` aus zu wählen. In Zeile 30 steht ja schon sowas, was bei einer Liste natürlich nicht funktioniert. Ungetestet:

Code: Alles auswählen

        a_time = numpy.arange(0.0, len(a_p_1)) * (timescale * 10000)
Man kann die einzelnen Daten ja auch ruhig in ihren eigenen Arrays lassen, aber diese Arrays könnte man in einer Klasse zusammenfassen.
Antworten