Sie können die Funktion verwenden tz_localize
, um einen Zeitstempel oder eine DateTimeIndex-Zeitzone bekannt zu machen. Wie können Sie jedoch das Gegenteil tun: Wie können Sie einen zeitzonenbewussten Zeitstempel in einen naiven umwandeln, während die Zeitzone erhalten bleibt?
Ein Beispiel:
In [82]: t = pd.date_range(start="2013-05-18 12:00:00", periods=10, freq='s', tz="Europe/Brussels")
In [83]: t
Out[83]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2013-05-18 12:00:00, ..., 2013-05-18 12:00:09]
Length: 10, Freq: S, Timezone: Europe/Brussels
Ich könnte die Zeitzone entfernen, indem ich sie auf Keine setze, aber dann wird das Ergebnis in UTC konvertiert (12 Uhr wurde 10):
In [86]: t.tz = None
In [87]: t
Out[87]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2013-05-18 10:00:00, ..., 2013-05-18 10:00:09]
Length: 10, Freq: S, Timezone: None
Gibt es eine andere Möglichkeit, einen DateTimeIndex in eine naive Zeitzone zu konvertieren, aber unter Beibehaltung der Zeitzone, in der er festgelegt wurde?
Einige Zusammenhänge zu dem Grund, warum ich dies frage: Ich möchte mit zeitzonen-naiven Zeitreihen arbeiten (um den zusätzlichen Aufwand mit Zeitzonen zu vermeiden, und ich brauche sie nicht für den Fall, an dem ich arbeite).
Aber aus irgendeinem Grund muss ich mich in meiner lokalen Zeitzone (Europa / Brüssel) mit einer zeitzonenbewussten Zeitreihe befassen. Da alle meine anderen Daten zeitzonennaiv sind (aber in meiner lokalen Zeitzone dargestellt werden), möchte ich diese Zeitreihen in naiv konvertieren, um weiter damit arbeiten zu können. Sie muss jedoch auch in meiner lokalen Zeitzone dargestellt werden (entfernen Sie einfach die Zeitzoneninformationen). ohne die vom Benutzer sichtbare Zeit in UTC umzuwandeln ).
Ich weiß, dass die Zeit tatsächlich intern als UTC gespeichert und nur dann in eine andere Zeitzone konvertiert wird, wenn Sie sie darstellen. Daher muss es eine Konvertierung geben, wenn ich sie "delokalisieren" möchte. Mit dem Python-Datum / Uhrzeit-Modul können Sie beispielsweise die Zeitzone wie folgt "entfernen":
In [119]: d = pd.Timestamp("2013-05-18 12:00:00", tz="Europe/Brussels")
In [120]: d
Out[120]: <Timestamp: 2013-05-18 12:00:00+0200 CEST, tz=Europe/Brussels>
In [121]: d.replace(tzinfo=None)
Out[121]: <Timestamp: 2013-05-18 12:00:00>
Auf dieser Grundlage könnte ich Folgendes tun, aber ich nehme an, dass dies bei der Arbeit mit einer größeren Zeitreihe nicht sehr effizient ist:
In [124]: t
Out[124]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2013-05-18 12:00:00, ..., 2013-05-18 12:00:09]
Length: 10, Freq: S, Timezone: Europe/Brussels
In [125]: pd.DatetimeIndex([i.replace(tzinfo=None) for i in t])
Out[125]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2013-05-18 12:00:00, ..., 2013-05-18 12:00:09]
Length: 10, Freq: None, Timezone: None
replace
.tz_localize
dasreplace(tzinfo=None)
Gegenteil davon, was das für Datumsangaben tut, aber es ist in der Tat kein sehr offensichtlicher Weg.Antworten:
Um meine eigene Frage zu beantworten, wurde diese Funktionalität in der Zwischenzeit Pandas hinzugefügt. Ab Pandas 0.15.0 können Sie
tz_localize(None)
die Zeitzone entfernen, die zur Ortszeit führt.Siehe den aktuellen Eintrag: http://pandas.pydata.org/pandas-docs/stable/whatsnew.html#timezone-handling-improvements
Also mit meinem Beispiel von oben:
using
tz_localize(None)
entfernt die Zeitzoneninformationen, was zu einer naiven Ortszeit führt :Darüber hinaus können Sie auch
tz_convert(None)
die Zeitzoneninformationen entfernen, aber in UTC konvertieren, um eine naive UTC-Zeit zu erhalten :Dies ist viel leistungsfähiger als die
datetime.replace
Lösung:quelle
from tzlocal import get_localzone
,tz_here = get_localzone()
,<datetime object>.tz_convert(tz_here).tz_localize(None)
t.dt.tz_localize(None)
odert.dt.tz_convert(None)
. Beachten Sie die.dt
.Ich denke, Sie können nicht effizienter erreichen, als Sie vorgeschlagen haben.
Das zugrunde liegende Problem ist, dass die Zeitstempel (wie Sie scheinen) aus zwei Teilen bestehen. Die Daten, die die UTC-Zeit und die Zeitzone tz_info darstellen. Die Zeitzoneninformationen werden nur zu Anzeigezwecken verwendet, wenn die Zeitzone auf dem Bildschirm gedruckt wird. Zur Anzeigezeit werden die Daten entsprechend versetzt und +01: 00 (oder ähnlich) zur Zeichenfolge hinzugefügt. Durch das Entfernen des Werts tz_info (mit tz_convert (tz = None)) werden die Daten, die den naiven Teil des Zeitstempels darstellen, nicht geändert.
Die einzige Möglichkeit, das zu tun, was Sie möchten, besteht darin, die zugrunde liegenden Daten zu ändern (Pandas lassen dies nicht zu ... DatetimeIndex sind unveränderlich - siehe die Hilfe zu DatetimeIndex) oder einen neuen Satz von Zeitstempelobjekten zu erstellen und diese zu verpacken in einem neuen DatetimeIndex. Ihre Lösung macht Letzteres:
Als Referenz ist hier die
replace
Methode vonTimestamp
(siehe tslib.pyx):Sie können anhand der Dokumente
datetime.datetime
sehen, dassdatetime.datetime.replace
auch ein neues Objekt erstellt wird.Wenn Sie können, ist es für die Effizienz am besten, die Datenquelle so zu ändern, dass die Zeitstempel (fälschlicherweise) ohne ihre Zeitzone gemeldet werden. Du hast erwähnt:
Ich wäre gespannt, auf welchen zusätzlichen Ärger Sie sich beziehen. Ich empfehle in der Regel für alle Softwareentwicklungen, den Zeitstempel "naive Werte" in UTC beizubehalten. Es gibt kaum etwas Schlimmeres, als zwei verschiedene int64-Werte zu betrachten und sich zu fragen, zu welcher Zeitzone sie gehören. Wenn Sie immer, immer, immer UTC für den internen Speicher verwenden, vermeiden Sie unzählige Kopfschmerzen. Mein Mantra lautet: Zeitzonen sind nur für menschliche E / A vorgesehen .
quelle
Das
tz
explizite Festlegen des Indexattributs scheint zu funktionieren:quelle
tz
konvertiert das Setzen von "Keine" es auch in UTC.tz_convert
einen Fehler auslöst .Weil ich immer Schwierigkeiten habe, mich zu erinnern, eine kurze Zusammenfassung dessen, was jeder von ihnen tut:
quelle
Aufbauend auf dem Vorschlag von DA, dass " die einzige Möglichkeit, das zu tun, was Sie wollen, darin besteht, die zugrunde liegenden Daten zu ändern " und numpy verwendet, um die zugrunde liegenden Daten zu ändern ...
Das funktioniert bei mir und ist ziemlich schnell:
quelle
Die akzeptierte Lösung funktioniert nicht, wenn eine Serie mehrere verschiedene Zeitzonen enthält. Es wirft
ValueError: Tz-aware datetime.datetime cannot be converted to datetime64 unless utc=True
Die Lösung besteht darin, die
apply
Methode zu verwenden.Bitte beachten Sie die folgenden Beispiele:
quelle
Der späte Beitrag stieß jedoch in Python datetime auf etwas Ähnliches, und Pandas geben unterschiedliche Zeitstempel für dasselbe Datum an .
Wenn Sie eine zeitzonenbezogene Datumszeit in
pandas
haben ,tz_localize(None)
ändert sich der POSIX-Zeitstempel (der intern verwendet wird) technisch so, als ob die Ortszeit vom Zeitstempel UTC wäre. Lokal bedeutet in diesem Zusammenhang lokal in der angegebenen Zeitzone . Ex:Beachten Sie, dass dies bei Sommerzeitübergängen zu merkwürdigen Dingen führt , z
Im Gegensatz dazu wird
tz_convert(None)
der interne Zeitstempel nicht geändert, sondern nur der entfernttzinfo
.Mein Fazit wäre: Halten Sie sich an die zeitzonenbezogene Datums- und Uhrzeitangabe, wenn Sie
t.tz_convert(None)
den zugrunde liegenden POSIX-Zeitstempel verwenden können oder nur, wenn er nicht geändert wird . Denken Sie daran, dass Sie dann praktisch mit UTC arbeiten.(Python 3.8.2 x64 unter Windows 10,
pandas
v1.0.5.)quelle
Das Wichtigste ist das Hinzufügen,
tzinfo
wenn Sie ein Datum / Uhrzeit-Objekt definieren.quelle