Datetime64[ns] in x Achse plotten

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Samoth
User
Beiträge: 41
Registriert: Freitag 24. November 2017, 15:13

Donnerstag 4. Januar 2018, 11:59

Hallo,
Ich habe eine Frage, worin liegt der Fehler. Alle gegoogelten Ergebnisse ergaben keine Lösung
Mein eingelesenes Datenformat sieht so aus.

Code: Alles auswählen

707   2017-05-31 13:19:01
708   2017-05-31 13:48:57
709   2017-05-31 14:28:11
710   2017-05-31 14:34:40
711   2017-05-31 14:48:54
712   2017-05-31 15:03:58
713   2017-05-31 15:50:33
714   2017-05-31 16:05:19
715   2017-05-31 16:17:15
716   2017-05-31 16:27:16
717   2017-05-31 16:35:46
718   2017-05-31 16:43:07
719   2017-05-31 16:53:24
720   2017-05-31 17:06:00
Length: 721, dtype: datetime64[ns]
Nun möchte ich diese Zeitangaben mit y-Werten plotten.

Zunächst einmal habe ich die Daten so eingelesen.

Code: Alles auswählen

temp=pandas.read_csv(fns[1], delimiter=',', header=4)

time=temp['Date(dd-mm-yy)']+' '+temp['Time(hh:mm:ss)']
dat64=pandas.to_datetime(time, format='%d:%m:%Y %H:%M:%S')
#dates2=datetime.strptime(dates, '%d:%m:%Y %H:%M:%S')
Um diese zu plotten muss ich daraus ein Zeitstamp oder float usw. erzeugen (laut Matplotlib)

Problem:

Code: Alles auswählen

In [134]: dat64[720]
Out[134]: Timestamp('2017-05-31 17:06:00')

In [135]: time.strptime(dat64[720],time_format)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-135-20a5d6f77171> in <module>()
----> 1 time.strptime(dat64[720],time_format)

/home/samothkociok/.conda/envs/thomypy/lib/python3.4/site-packages/pandas/core/generic.py in __getattr__(self, name)
   3079             if name in self._info_axis:
   3080                 return self[name]
-> 3081             return object.__getattribute__(self, name)
   3082 
   3083     def __setattr__(self, name, value):

AttributeError: 'Series' object has no attribute 'strptime'
Hat einer eine idee?
narpfel
User
Beiträge: 241
Registriert: Freitag 20. Oktober 2017, 16:10

Donnerstag 4. Januar 2018, 14:27

Moin,

um Zeitreihen mit `matplotlib` plotten zu können, müssen die Daten in `datetime.datetime`-Objekte umgewandelt werden. Das geht, wenn du eine `Series` mit den Daten hast, mittels `dat64.dt.to_pydatetime()`.

Je nach Anwendungsfall kann es auch Sinn machen, die Datetime-Spalte als Index zu verwenden. Dann kann das `.dt` entfallen.

Das Parsen der Zeiten lässt sich übrigens auch einfacher formulieren:

Code: Alles auswählen

In [7]: paste
%%file test.csv
foo,Date(dd-mm-yy),Time(hh:mm:ss)
707,2017-05-31,13:19:01
708,2017-05-31,13:48:57
709,2017-05-31,14:28:11
710,2017-05-31,14:34:40
711,2017-05-31,14:48:54
712,2017-05-31,15:03:58

## -- End pasted text --
Writing test.csv

In [8]: df = pd.read_csv(
   ...:     "test.csv",
   ...:     delimiter=",",
   ...:     parse_dates=[["date", "time"]],
   ...:     names=["foo", "date", "time"],
   ...:     skiprows=1,
   ...: )

In [9]: df
Out[9]:
            date_time  foo
0 2017-05-31 13:19:01  707
1 2017-05-31 13:48:57  708
2 2017-05-31 14:28:11  709
3 2017-05-31 14:34:40  710
4 2017-05-31 14:48:54  711
5 2017-05-31 15:03:58  712

In [10]: import matplotlib.pyplot as plt

In [11]: plt.plot(
    ...:     df.date_time.dt.to_pydatetime(),
    ...:     df.foo,
    ...: )
Out[11]: [<matplotlib.lines.Line2D at 0x7f575ae6ff28>]
Ich hab’ in diesem Beispiel die Spalten umbenannt, damit die generierte `date_time`-Spalte einen handlicheren Namen hat. Kann man aber natürlich auch weglassen.

Dein Fehler bei `time.strptime` kommt wahrscheinlich daher, dass du mit der Zeile `time=temp['Date(dd-mm-yy)']+' '+temp['Time(hh:mm:ss)']` den Namen des `time`-Moduls überschrieben hast. Das ist ein Grund, warum man mit eigenen Namen nicht die Namen von Builtins oder importierten Modulen überschreiben sollte.

Weiterführende Lektüre: Die `pandas`-Dokumentation zu Zeitreihen.
Samoth
User
Beiträge: 41
Registriert: Freitag 24. November 2017, 15:13

Donnerstag 4. Januar 2018, 17:20

Hey,
mit dat64.dt.to_pydatetime() hat es funktioniert... nur habe ich nirgends etwas mit to_pydatetime gefunden...
wofür steht das dt? datetime? Die Methode finde ich nicht.

Ich h atte das wie du bereits schon versucht... allerdings so.

Code: Alles auswählen

In [8]: df = pd.read_csv(
   ...:     "test.csv",
   ...:     delimiter=",",
   ...:     parse_dates=[[1, 2]]
   ...: )
   
demzufolge wurden beide eiträge in eins Eingefügt (mit alten Spaltennamen).
Gibt es da ne elegante Lösung die erste und die zweite Spalte zusammenzuführen und dann beide anderen Spalten zu löschen? Also aus zwei mach eins?

Gruß
narpfel
User
Beiträge: 241
Registriert: Freitag 20. Oktober 2017, 16:10

Donnerstag 4. Januar 2018, 18:51

Die Dokumentation zu Zeitreihen beschreibt auch `to_pydatetime`. Und `dt` ist im Abschnitt Essential Basic Functionality beschrieben.

Dein Code führt doch die Datums- und die Zeitspalte zu einer `datetime`-Spalte zusammen und entfernt die beiden Ursprungsspalten (mein Code macht das auch). Insofern verstehe ich deine Frage nicht ganz.

Falls dich der Name stört:

Code: Alles auswählen

df.rename(columns={"Date(dd-mm-yy)_Time(hh:mm:ss)": "datetime"}, inplace=True)
Antworten