CSV-Datei einlesen - Error could not convert string to float

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
geopython
User
Beiträge: 6
Registriert: Dienstag 7. August 2018, 22:31

Hallöchen,

ich brauche etwas Hilfe. Ich habe eine CSV-Datei bzw habe es auch schon als Textdatei probiert - es ändert nichts am Fehler.
Folgenden vereinfachten Code habe ich:

import matplotlib as mlp
import matplotlib.pyplot as plt
import pandas as panda
import numpy as np

x,y= np.loadtxt('Test.txt', unpack = True, delimiter = ',')


plt.title("Test", fontsize=24)
plt.ylabel('Menge')
plt.xlabel('Datum')

plt.grid(True)
plt.show()


Die Textdatei ist wie folgt aufgebaut:
Menge,Datum_Uhrzeit
0.039984,07.08.2014 08:00
0.039984,07.08.2014 08:01
0.039984,07.08.2014 08:02
0.039984,07.08.2014 08:03
0.039984,07.08.2014 08:04


Wenn ich das Skript ausführe bekomme ich folgende Errormeldung:

ValueError: could not convert string to float: ÿþA

Ich vermute ganz stark, dass es an den Datums- und Uhrzeitangaben liegt. Aber wie kann ich die importieren, sodass sie korrekt eingelesen werden?
Zudem würde ich geren folgende Zeile ergänzen:
plt.plot([Menge], [Datum], 'b-')

Das funktioniert natürlich nur wenn die Daten richtig eingelesen werden.

Schonmal vielen vielen dank für die Hilfe! :)
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

Wie sieht denn die Test.txt-Datei genau aus? Welches Encoding?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Könnte ein Microsoft UTF8 BOM sein. Dazu wäre es gut, die ersten paar BYTES! hier zu posten. ZB mit

print(repr(open(file name, “rb)[:20]))
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@__deets__: Nein, das ist ein UTF16-BOM, aber dann macht das A keinen Sinn.
geopython
User
Beiträge: 6
Registriert: Dienstag 7. August 2018, 22:31

Vielen Dank schonmal für eure Ideen.
Ich habe die Datei nun zu UTF-8 ohne BOM konvertiert.
(Der COde von_deets_ hat leider nicht funktioniert, bin aber auch nicht wirklich bewand in solchen Python-Codes)
Nach der Konvertierung habe ich das Skript nochmal gestartet und bekomme nun folgende Fehlermeldung:

ValueError: could not convert string to float: Abfluss,Datum_Uhrzeit

Wenn ich die "normale" UTF-8 Kodierung nehme, da bekomme ich denselben Fehler. HAtte vorher wohl eine sehr seltsame Kodierung.

Die Spalten erkennt er jetzt ja sozusagen. Der Fehler bleibt trotzdem.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das erklärt das A - du hast nicht die richtigen Spaltennamen gepostet. Und das hat Verwirrung gestiftet. Bitte die echten Daten, Code und Fehlermeldungen Posten, nicht etwas ausgedachtes, das irgendwie so ähnlich klingt.

Und du musst nicht all zu überraschend die Kopfzeile überspringen - “Abfluss” ist ja nun keine Zahl. Dazu kennt loadtxt den Parameter skiprows, der muss auf 1 gesetzt werden.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und irgendwas stimmt auch mit dem delimiter nicht. Laut Code ist es richtig, aber der Fehler der sich auch auf “,Datum_Uhrzeit” bezieht, passt dazu nicht. Wie gesagt, richtigen Code, Daten und passenden Fehler Posten.
geopython
User
Beiträge: 6
Registriert: Dienstag 7. August 2018, 22:31

Vielen Dank schonmal.
Ich hab einiges ausprobiert, deswegen ist da was durcheinander gekommen. Sorry
Code:

import matplotlib as mlp
import matplotlib.pyplot as plt
import pandas as panda
import numpy as np

x,y= np.loadtxt('r"C:\Users\0\Desktop\Test.txt", unpack = True, skiprows = 1)

'''
print(x)
print(y)
'''

plt.plot()

plt.title("Test", fontsize=24)
plt.ylabel('Menge')
plt.xlabel('Datum')

plt.grid(True)
plt.show()



Textdatei:

Menge,Datum,Uhrzeit
0.039984,07.08.2014,08:00
0.039984,07.08.2014,08:01
0.039984,07.08.2014,08:02
0.039984,07.08.2014,08:03
0.039984,07.08.2014,08:04


Fehlermeldung (Ich habe skiprows ergänzt und ein Komma zwischen dem Datum und der Uhrzeit):

unfile('C:/Users/0/untitled4.py', wdir='C:/Users/0/Desktop')
Traceback (most recent call last):

File "<ipython-input-13-a298f5aadfaa>", line 1, in <module>
runfile('C:/Users/0/untitled4.py', wdir='C:/Users/0/Desktop')

File "D:\Anaconda\lib\site-packages\spyder\utils\site\sitecustomize.py", line 880, in runfile
execfile(filename, namespace)

File "D:\Anaconda\lib\site-packages\spyder\utils\site\sitecustomize.py", line 87, in execfile
exec(compile(scripttext, filename, 'exec'), glob, loc)

File "C:/Users/lea.SEBO7.000/untitled4.py", line 13, in <module>
x,y= np.loadtxt(r"C:\Users\0\Desktop\Test.txt", unpack = True, skiprows = 1)
File "D:\Anaconda\lib\site-packages\numpy\lib\npyio.py", line 985, in loadtxt
items = [conv(val) for (conv, val) in zip(converters, vals)]

File "D:\Anaconda\lib\site-packages\numpy\lib\npyio.py", line 687, in floatconv
return float(x)

ValueError: invalid literal for float(): 0.039984,07.08.2014,08:00
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@geopython: wie __deets__ schon geschrieben hat, ist der Delimiter bei Dir ",".

Mehrzeilige Strings sind keine Kommentare. Wenn man was auskommentiert nimmt man '#'. Das kann auch jeder anständige Editor blockweise.
geopython
User
Beiträge: 6
Registriert: Dienstag 7. August 2018, 22:31

Habe den Code mit dem delimiter angepasst und zwar wie folgt:

import matplotlib as mlp
import matplotlib.pyplot as plt
import pandas as panda
import numpy as np

x,y= np.loadtxt(r"C:\Users\0\Desktop\Test.txt", unpack = True, delimiter =' , ', skiprows = 1)



plt.title("Test", fontsize=24)
plt.ylabel('Menge')
plt.xlabel('Datum')

plt.grid(True)
plt.show()


Bekomme dann trotzdem folgende Fehlermeldung:

runfile('C:/Users/0/untitled4.py', wdir='C:/Users/0/Desktop')
Traceback (most recent call last):

File "<ipython-input-5-a298f5aadfaa>", line 1, in <module>
runfile('C:/Users/0/untitled4.py', wdir='C:/Users/0/Desktop')

File "D:\Anaconda\lib\site-packages\spyder\utils\site\sitecustomize.py", line 880, in runfile
execfile(filename, namespace)

File "D:\Anaconda\lib\site-packages\spyder\utils\site\sitecustomize.py", line 87, in execfile
exec(compile(scripttext, filename, 'exec'), glob, loc)

File "C:/Users/lea.SEBO7.000/untitled4.py", line 13, in <module>
x,y= np.loadtxt(r"C:\Users\0\Desktop\Test.txt", unpack = True, delimiter =',', skiprows = 1)

File "D:\Anaconda\lib\site-packages\numpy\lib\npyio.py", line 985, in loadtxt
items = [conv(val) for (conv, val) in zip(converters, vals)]

File "D:\Anaconda\lib\site-packages\numpy\lib\npyio.py", line 687, in floatconv
return float(x)
ValueError: invalid literal for float(): 07.08.2014


Da ich noch kein Experte bin was Python angeht, verstehe ich eure Ratschläge vllt auch falsch?!
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Schau dir doch mal AN, was da steht? Was ist denn "07.08.2014" fuer ein Ding, und wo steht das, und was probierst du damit?
geopython
User
Beiträge: 6
Registriert: Dienstag 7. August 2018, 22:31

Wie man dem Code u.U., entnehmen kann, möchte ich ein (Linien)Diagramm erstellen. Auf der x-Achse das Datum und auf der y-Achse die Menge. Der Wert "07.08.2014" stellt somit das Datum dar. Das Datum bzw. der Wert "07.08.2014" steht in meiner Textdatei in der Spalte "Datum".
Offensichtlich gibt es Probleme beim EInlesen des Datums. Wenn ich wüsste, was ich mit der Fehlermeldung anfangen sollte, hätte ich hier nicht nachgefragt.
Ich vermute, dass es was mit der Konvertierung von String zu float zu tun hat und ich vielleicht ein numpay array erstellen muss oder ähnliches, um erstmal die Datumswerte einlesen zu können. WIe ich hinteher das Diagramm erstelle oder die Texte und Beschriftungen ansetze, das ist kein Problem. Wie ich jedoch die Werte aus meiner Textdatei richtg einlese, ist mir in diesem Fall offensichtlich nicht klar. Wenn ich einfach eine Liste mit den Werten erstellen würde, wäre das auch klar. Aber ich möchte nicht händisch/manuell alle 3000 Werte eingeben, sondern sie von dem Skript einlesen lassen und dann verarbeiten.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

es gibt halt keine eindeutige uns selbstverständliche Art, aus einem Datum eine Fliesskommazahl zu machen. Also macht Python das nicht.

Und was ist mit der Uhrzeit? Soll die nicht auch dazu gehören? Und mit dem Datum zu einem Zeitstempel verknüpft werden? Oder sollen die Zeilen für einen Tag aggregiert werden?
geopython
User
Beiträge: 6
Registriert: Dienstag 7. August 2018, 22:31

Optimal wäre es natürlich wenn sowohl Datum und Uhrzeit auf der x-Achse stehen, mit einem Intervall von ca. 6 h.
Nein, die Daten sollen nicht aggregiert werden. Jeder einzelne Wert soll im Diagramm angezeigt werden und die Beschriftung dann halt im Intervall von 6h.
mit "datetime" könnte man ja evtl. auch was machen, allerdings hab ich da zu wenig Erfahrung und hab daher gedacht es wäre einfacher, die Daten einfach aus der Datei auszulesen.
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@geopython: es ist etwas ungeschickt, dass Datum und Uhrzeit in zwei verschiedenen Spalten stehen. Was heißt `... es wäre einfacher, die Daten einfach aus der Datei auszulesen`? Hast Du die Daten schon in einer anderen Form vorliegen?

Ansonsten gibt es genug Beispiele im Netz, wie man mit numpy Dateien mit Datumsspalten liest, so dass man es nicht jedesmal hier wieder von neuem vorkauen muß. Noch einfacher geht das mit Pandas, das Du ja sowieso schon importierst aber aus unerfindlichen Gründen in panda umbenennst.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Fuer solche heterogenen Daten ist es deutlich besser, Pandas zu benutzen.

Code: Alles auswählen

import io
import pandas as pd


DATA = """Menge,Datum,Uhrzeit
0.039984,07.08.2014,08:00
0.039984,07.08.2014,08:01
0.039984,07.08.2014,08:02
0.039984,07.08.2014,08:03
0.039984,07.08.2014,08:04
"""

frame = pd.read_csv(io.StringIO(DATA), parse_dates=[['Datum', 'Uhrzeit']])
print(frame)
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Also bei mir muss ich da noch ``dayfirst=True`` übergeben damit das Datum stimmt. Eventuell könnte es auch Sinn machen den Zeitstempel als Index zu verwenden.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten