Formatiert aus Textdateien lesen

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
Lebostein
User
Beiträge: 9
Registriert: Freitag 4. August 2006, 09:03

Hi,

ich habe mehrere lange Textdateien mit folgendem Aufbau:

Code: Alles auswählen

  ...
  4.15292212E+01 -3.21320849E-02 -2.56962394E+01
  4.14830210E+01 -1.30006143E-02 -2.56981922E+01
  4.14792219E+01 -3.21353576E-02 -2.56983141E+01
  4.13678231E+01 -3.21319478E-02 -2.46497314E+01
  4.13232229E+01 -1.30003931E-02 -2.46617714E+01
  ...
Also 3 Zahlen hintereinander, gespeichert mit dem Format '%16.8E%16.8E%16.8E'

Jetzt möchte ich gerne so schnell wie möglich die Daten als Numeric/numpy-array zurücklesen. Bisher mache ich das in etwa so:

Code: Alles auswählen

# ===================================================================

from numpy import *

# ===================================================================

def line_to_vektor_f(zeile, anzahl, length):

	vektor = zeros(anzahl, float)
	cursor = 0
	for i in range(anzahl):
		vektor[i] = float(zeile[cursor : cursor + length])
		cursor = cursor + length
	return vektor

# ===================================================================

file = open('datei.txt', 'r')
lines = file.readlines()
file.close()

for each in lines:
	a = line_to_vektor_f(each, 3, 16)

# ===================================================================
Gibt es einen schnelleren bzw. eleganteren Weg? ISt nicht grade der Brüller, was die Geschwindigkeit angeht... Kann man wie in C oder FORTRAN direkt mit dem Formatbezeichner z.B. Float-Variablen füllen?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Mit numpy kenne ich mich zwar nicht aus, aber dieses array dürfte ja so eine Art Liste sein. Evtl. kennt dieser Datentyp ja auch ein extend, ansonsten ggf. am Ende einfach die Liste in ein solches array umwandeln.

Code: Alles auswählen

datei = open("datei.txt","r")
liste = []
for zeile in datei:
    liste.extend(map(float,zeile.split()))
datei.close()
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Bin auch kein 'Numpy-Experte' und komme auf ähnliches:

Code: Alles auswählen

import numpy

f = open('vectors.txt', 'r')

vecs = map(lambda x: numpy.array(x, float),
           [map(float, vs.split()) for vs in f])

f.close()

for v in vecs:
  print v
:wink:
yipyip
Lebostein
User
Beiträge: 9
Registriert: Freitag 4. August 2006, 09:03

Danke. Sehr interessante Sachen. Das mit dem map() kannte ich noch gar nicht. Komischerweise trotzdem langsamer als mein Code. Ich hab mal die von mir oben gezeigten 5 Zahlenzeilen in eine neue Textdatei gepackt und als 'datei.txt' gespeichert, zum Testen:

Code: Alles auswählen

# ===================================================================

from numpy import zeros, array
from time import time

# ===================================================================

def line_to_vektor_f(zeile, anzahl, length):

    vektor = zeros(anzahl, float)
    cursor = 0
    for i in range(anzahl):
        vektor[i] = float(zeile[cursor : cursor + length])
        cursor = cursor + length
    return vektor

# ===================================================================

file = open('datei.txt', 'r')
lines = file.readlines()
file.close()

start = time()
for i in range(100000):
  for each in lines:
    a = line_to_vektor_f(each, 3, 16)
print time() - start

start = time()
for i in range(100000):
  for each in lines:
    a = array(map(float, each.split()), float)
print time() - start

# ===================================================================
Folgendes Ergebnis:
10.2350001335 s mit line_to_vektor_f(...
14.6089999676 s mit array(map(float...
Sollte ich durch mein naives Herangehen schon die schnellste Lösung gefunden haben? So richtig glaub ich es nicht...
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Das hat mich jetzt auch verblüfft...
Habe mal folgendes getestet:

Code: Alles auswählen

...
start = time()
for i in range(100000):
  a = zeros(3, float)
  a[0] = 1.0
  a[1] = 2.0
  a[2] = 3.0
print time() - start

start = time()
for i in range(100000):
  a = array([1.0, 2.0, 3.0], float)
print time() - start
ergibt:
0.419311761856 mit zeros()
0.999112844467 mit array()
Daher tippe ich auf array() als Zeitfresser, was ich aber nicht verstehe,
da bei __beiden__ ein array-objekt erzeugt wird.

:?
yipyip
Antworten