Seite 1 von 1

error bei string to float

Verfasst: Sonntag 29. Oktober 2006, 23:21
von pmartinez
Hallo,
ich mochte Werte aus einer Text-Datei lesen und in float konvertieren

Die Text-Datei sieht so aus (als Beispiel)
'decimal';'23.345';'-123.3454'

Der Python Script (abgekürzt):
wert = float(spalte[1])

Error:
ValueError: invalid literal for float(): '23.345'

Any Ideas?

pe

Verfasst: Sonntag 29. Oktober 2006, 23:25
von BlackJack
Die Anführungszeichen sind das Problem, die sind nicht Bestandteil von Zahlen. Das hier müsste funktionieren:

Code: Alles auswählen

wert = float(spalte[1][1:-1])
Wie kommen die Daten denn in Dein Programm? Wenn Du die Datei mit dem `csv` Modul einliest, dann kannst Du festlegen welche Art von Anführungszeichen in den Einträgen vorkommen können. Die werden dann automatisch rausgefiltert.

Verfasst: Montag 30. Oktober 2006, 00:05
von pmartinez
BlackJack hat geschrieben:Die Anführungszeichen sind das Problem, die sind nicht Bestandteil von Zahlen. Das hier müsste funktionieren:

Code: Alles auswählen

wert = float(spalte[1][1:-1])
Wie kommen die Daten denn in Dein Programm? Wenn Du die Datei mit dem `csv` Modul einliest, dann kannst Du festlegen welche Art von Anführungszeichen in den Einträgen vorkommen können. Die werden dann automatisch rausgefiltert.
Hallo, danke für den Vorschlag!
Ja, die Daten kommen aus einer cvs-Datei. Darin sind coordenaten in unterschiedlichen Formate. Ich kann deswegen die ' nicht einfach rausfiltern, da einige Einträge so aussehen : 45°56'12''N

Mein Script erkennt die unterschiedlichen Formate (lat-long, GPS, decimal-degrees) uns soll sie alle in decimal-degrees umwandeln. Bei lat-long und GPS-Format klappt es ohne Probleme, Aber bei dec.degrees bekomme ich den Error.

Bei deinen Vorschlag kriege ich den error:
ValueError: invalid literal for float(): -123.3454'

Ich habe es geändert in

wert = float(spalte[1][1:-1:])
Kriege ich aber den selben Error!
Verstehe ich nicht, den im der console klapt es:
>>> a = "1234"
>>> b = a[1:-1:]
>>> b
'23'
>>>

pe

Verfasst: Montag 30. Oktober 2006, 00:10
von pmartinez
Verstehe ich nicht, den im der console klapt es:
Warum kann ich in der console:

Code: Alles auswählen

>>> a = "123.3"
>>> b=float(a)
>>> b
123.3
>>>
Aber nicht wenn ich aus einer datei lese?

pe

Verfasst: Montag 30. Oktober 2006, 00:33
von Leonidas
Hallo pmartinez, willkommen im Forum,

pmartinez hat geschrieben:Warum kann ich in der console:

Code: Alles auswählen

>>> a = "123.3"
>>> b=float(a)
>>> b
123.3
>>>
Aber nicht wenn ich aus einer datei lese?
Ganz einfach, weil dein String den du aus einer Datei ausliest anders aussieht als der den du in die Konsole eintippst:

Code: Alles auswählen

In [1]: con_str = "123.3"
In [2]: float(con_str)
Out[2]: 123.3
In [3]: dat_str = "'123.3'"
In [4]: float(dat_str)
---------------------------------------------------------------------------
exceptions.ValueError                                Traceback (most recent call last)

/home/marek/<ipython console>

ValueError: invalid literal for float(): '123.3'
In [5]: print con_str
123.3
In [6]: print dat_str
'123.3'
Du siehst also, du liest aus der Datei zu viele Anführungszeichen heraus, mit denen float() nichts anfangen kann.

Verfasst: Montag 30. Oktober 2006, 00:36
von pmartinez
Ich schon wieder:
Ich habs.
Das Problem ist wenn der String am Ende der Zeile ist, muss man
2 Zeichen (nicht nur 1 ) vom abziehen. Ist das vielleicht der unsichtbaren Retourn Zeichen?
Also es klapt wenn es heisst:

Code: Alles auswählen

>>> for zeile in zeilen:
...     spalte = re.split('[;]',zeile)
...     print "%s  %s  %s" % (spalte[0][1:-1], spalte[1][1:-1], spalte[2][1:-2])
...
primera  45°23'12N  123°56'23E
segunda  23°34'56S  12°45'56W
decimal  23.345  -123.3454
Im Gegensatz:

Code: Alles auswählen

>>> for zeile in zeilen:
...     spalte = re.split('[;]',zeile)
...     print "%s  %s  %s" % (spalte[0][1:-1], spalte[1][1:-1], spalte[2][1:-1])
...
primera  45°23'12N  123°56'23E'
segunda  23°34'56S  12°45'56W'
decimal  23.345  -123.3454'
Danke für den Tip!

pe

Verfasst: Montag 30. Oktober 2006, 08:54
von BlackJack
pmartinez hat geschrieben:Ja, die Daten kommen aus einer cvs-Datei. Darin sind coordenaten in unterschiedlichen Formate. Ich kann deswegen die ' nicht einfach rausfiltern, da einige Einträge so aussehen : 45°56'12''N
Das `csv`-Modul filtert auch nicht alle heraus sondern nur die, die zum einschliessen von Werten benutzt werden. Der Wert, den Du da oben angibst, wie sieht der denn in der Datei genau aus? Wenn da wirklich ein ' einfach so mitten im Wert steht, dann bekommt das `csv` Modul allerdings ein Problem.

Wie kommen die Werte denn zustande? Warum ist da um jeden Wert überhaupt ein einfaches Anführungszeichen?
Bei deinen Vorschlag kriege ich den error:
ValueError: invalid literal for float(): -123.3454'
Das Problem hast Du mit dem `csv` Modul auch nicht, das entfernt das Zeilenende für Dich.

Code: Alles auswählen

In [10]: a = StringIO("'decimal';'23.345';'-123.3454'\n")

In [11]: b = csv.reader(a, delimiter=';', quotechar="'")

In [12]: for row in b:
   ....:     print row
   ....:
['decimal', '23.345', '-123.3454']
Last but not least: Um eine Zeile an einem Zeichen aufzuteilen braucht man nicht so etwas mächtiges wie reguläre Ausdrücke bemühen. Ein einfaches ``line.split(';')`` tut es auch.

Verfasst: Montag 30. Oktober 2006, 09:47
von pmartinez
Das `csv`-Modul filtert auch nicht alle heraus sondern nur die, die zum einschliessen von Werten benutzt werden. Der Wert, den Du da oben angibst, wie sieht der denn in der Datei genau aus? Wenn da wirklich ein ' einfach so mitten im Wert steht, dann bekommt das `csv` Modul allerdings ein Problem.
Jetzt weiss ich was du meinst. Ich habe das csv-Modul gar nicht benutzt (wusste nicht von seiner Existenz) sonder zu Fuss mit:

Code: Alles auswählen

zeile = datei.readline()
zeilen = datei.readlines()
for zeile in zeilen:
	spalte = re.split('[;]',zeile)
Wie kommen die Werte denn zustande? Warum ist da um jeden Wert überhaupt ein einfaches Anführungszeichen?
Sind in einer Excel-Datei, per OpenOffice als CSV gespeichert und las quotechar ' gewählt.

Mit dem csv-Modul geht es super. Habe schon ausprobiert. Danke.