unpacking

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.
Antworten
flying sheep
User
Beiträge: 48
Registriert: Donnerstag 17. September 2009, 16:44
Kontaktdaten:

ich werd langsam blöd. ich hab hier base64-kodierte big-endian-floats mit 32 bit präzision, aber ich werd nicht mit ihnen fertig. ich muss sie im reißverschlussverfahren auf zwei listen aufteilen (also erstes in liste1, zweites in liste2, drittes in liste1, usw.)

ich hab es mit array wie struct probiert, aber beides funzt nicht so doll. hier mal ein beispiel: http://www.python-forum.de/pastebin.php?mode=view&s=131

mein code:

Code: Alles auswählen

xdata, ydata = [], []
		
data = array.array(str("d"), data)
for i in range(0, len(data), 2):
			xdata.append(data[i])
			ydata.append(data[i+1])
oder:

Code: Alles auswählen

for flo in range(0, len(data)/4, 2):
			xdata.append(struct.unpack_from(str(">f"), data, flo))
			ydata.append(struct.unpack_from(str(">f"), data, flo+1))
ich vermute stark, dass in ersterem die endianness nicht stimmt oder so, aber ich hab keine ahnung, was im 2. kaputt ist.

kann mir wer helfen?
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Du versuchst ja auch Floats auszupacken. Du willst aber Integer auspacken.

Code: Alles auswählen

data = '...'.decode('base64')

while data:
    chunk, data = data[:4], data[4:]
    print struct.unpack('>i', chunk)
flying sheep
User
Beiträge: 48
Registriert: Donnerstag 17. September 2009, 16:44
Kontaktdaten:

und wieso will ich das? ich will 32-bit-floats, dachte ich zumindest. (steht im obigen post)
Zuletzt geändert von flying sheep am Samstag 22. Januar 2011, 00:57, insgesamt 1-mal geändert.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Uups. Falsch gelesen, sorry! Dann hat das mit dem 'f' doch gestimmt. Was ist denn an deinen Ergebnissen genau falsch?
flying sheep
User
Beiträge: 48
Registriert: Donnerstag 17. September 2009, 16:44
Kontaktdaten:

die resultierenden daten sollen plots aus einem massenspektrometer sein.
sieht so aus:
Bild

das heißt, dass der zweite wert (intensity, y-achse) im wertebereich 0-100 und der erste (m/z, x achse) positiv sein sollten.

aber es kommen negative und absurd hohe werte raus:

(1.9208320643695348e-13,) (862978920415232.0,)
(735.95001220703125,) (3.0136325221974403e-05,)
(-8.526429000960009e+36,) (-205706512.0,)
(693.2738037109375,) (1.1910087499567013e-11,)
(72084398080.0,) (-3.696164054886877e-35,)
(1068.6282958984375,) (-1.3927868922535615e-35,)
(-7.8389454819201933e-27,) (1.6227439324602869e-22,)
flying sheep
User
Beiträge: 48
Registriert: Donnerstag 17. September 2009, 16:44
Kontaktdaten:

aber da deine hübsche methode funktioniert, wenn man ein "i" durch ein "f" ersetzt nimm ich einfach die. danke!
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Ich denk mal das Problem bei deiner Funktion war, dass du in 2er-Schritten iteriert hast anstatt in 4er.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Zudem könnte man beim Iterieren auf islize aus dem itertools-Modul setzen. Damit wäre dann der unschöne Indexvorgriff a la [i+1] unnötig.

Code: Alles auswählen

In [3]: from itertools import islice

In [4]: l = range(10)

In [5]: list(islice(l, 0, None, 2))
Out[5]: [0, 2, 4, 6, 8]

In [6]: list(islice(l, 1, None, 2))
Out[6]: [1, 3, 5, 7, 9]
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Weil ich es grad sah: Vielleicht ist das hier ja für Dich interessant?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hyperion hat geschrieben:Weil ich es grad sah: Vielleicht ist das hier ja für Dich interessant?
Wenn du sowas suchst, dann werf ich auch noch construct ins Rennen. Damit habe ich mal ein Custom Binärformat gelesen und geschrieben, hat wirklich überaus gut funktioniert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
flying sheep
User
Beiträge: 48
Registriert: Donnerstag 17. September 2009, 16:44
Kontaktdaten:

danke für die tips, ich schau mir das alles mal an. ist sicher nicht das letze mal, dass ich mit binärdaten arbeiten muss.

und es war auch nicht das erste mal: ich hab mal ein chinesisches ttc2ttf*-progamm von c++ (eine sprache, die ich nur wenig mehr kann als die chinesischen kommentare) nach python portiert (mit struct). die magic numbers hab ich nicht zu schreiben hingekriegt, aber TeX konnte die ttfs trotzdem lesen (und das ttc davor nicht)

*ttf: true type font; ttc: collection dieser fonts, weil einzelne nur ne begrenzte zahl symbole aufnehmen können.
flying sheep
User
Beiträge: 48
Registriert: Donnerstag 17. September 2009, 16:44
Kontaktdaten:

Hyperion hat geschrieben:Weil ich es grad sah: Vielleicht ist das hier ja für Dich interessant?
durch dich sind mir jetzt 3 dinge klar:
  1. ich muss mal wieder in haskell programmieren. dein slicing-ansatz ist so viel schöner und verständlicher als das herumgefuchtle mit indices…
  2. es gibt tatsächlich python-libs für binärdaten, wunderbar.
  3. (wegen deiner sig:) python3 ist ein segen. ich rage jedesmal so hart, wenn schon wieder irgend eine funktion einen string statt unicode haben will, QStrings, die nicht in unicode(QString_variable) gewrappt werden, ascii-encoding-errors schmeißen, print-funktionen failen, …

    mit python3 hatte ich halt einfach noch nie so nen fehler.
PS: construct sieht genauso interessant wie biwako aus. ich speichere beide in meinen megabyte-großen firefox-lesezeichen und schau sie mir genauer ann, wenn ich wieder binärdaten lesen will.
Antworten