1. ホーム
  2. python

[解決済み] pandasのタイムゾーンに対応したDateTimeIndexを、特定のタイムゾーンに対応したナイーブなタイムスタンプに変換する。

2022-07-10 21:03:08

質問

あなたは関数 tz_localize を使ってTimestampやDateTimeIndexをタイムゾーンに対応させることができますが、その逆を行うにはどうしたらよいでしょうか。タイムゾーンを意識したTimestampを、タイムゾーンを維持したまま素直なものに変換するにはどうしたらよいでしょうか。

例を挙げます。

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

タイムゾーンをNoneにすることで削除できましたが、その場合、結果はUTCに変換されます(12時が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

DateTimeIndexをtimezone naiveに変換し、設定されているタイムゾーンを維持する他の方法はありますか?


いくつかの コンテキスト 私がこれを尋ねている理由に関して。私はタイムゾーンなしの時系列で作業したいのです(タイムゾーンの余分な手間を省くため、そして私が作業しているケースには必要ない)。

しかし、何らかの理由で、私のローカルタイムゾーン(ヨーロッパ/ブリュッセル)でタイムゾーンを考慮した時系列を処理する必要があります。私の他のすべてのデータはタイムゾーンナイブ(ただし、私のローカル タイムゾーンで表現)であるため、この時系列をさらに扱うためにナイブに変換したいのですが、これも私のローカル タイムゾーンで表現しなければなりません(したがって、タイムゾーン情報を削除し ユーザー可視 を UTC に変換することなく、タイムゾーン情報を削除するだけです)。

時刻は実際にはUTCとして内部に保存され、あなたがそれを表現するときにだけ別のタイムゾーンに変換されることを知っています。例えば、pythonのdatetimeモジュールでは、以下のようにタイムゾーンを削除することができます。

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> 

ということで、これを元に以下のようにすればいいのですが、大きな時系列を扱う場合はあまり効率的ではないのでしょうね。

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

どのように解決するのですか?

私自身の質問に答えると、この機能は一応pandasに追加されています。開始 をpandas 0.15.0から を使うことができます。 tz_localize(None) を使ってタイムゾーンを削除し、ローカルタイムにします。

whatsnew のエントリを参照してください。 http://pandas.pydata.org/pandas-docs/stable/whatsnew.html#timezone-handling-improvements

では、先ほどの私の例で。

In [4]: t = pd.date_range(start="2013-05-18 12:00:00", periods=2, freq='H',
                          tz= "Europe/Brussels")

In [5]: t
Out[5]: DatetimeIndex(['2013-05-18 12:00:00+02:00', '2013-05-18 13:00:00+02:00'],
                       dtype='datetime64[ns, Europe/Brussels]', freq='H')

を使って tz_localize(None) はタイムゾーンの情報を除去し 素朴な現地時間 :

In [6]: t.tz_localize(None)
Out[6]: DatetimeIndex(['2013-05-18 12:00:00', '2013-05-18 13:00:00'], 
                      dtype='datetime64[ns]', freq='H')

さらに tz_convert(None) を使ってタイムゾーンの情報を削除し、UTC に変換することもできます。 単純なUTC時間 :

In [7]: t.tz_convert(None)
Out[7]: DatetimeIndex(['2013-05-18 10:00:00', '2013-05-18 11:00:00'], 
                      dtype='datetime64[ns]', freq='H')


これは多くの より高性能で よりも datetime.replace ソリューションよりも高性能です。

In [31]: t = pd.date_range(start="2013-05-18 12:00:00", periods=10000, freq='H',
                           tz="Europe/Brussels")

In [32]: %timeit t.tz_localize(None)
1000 loops, best of 3: 233 µs per loop

In [33]: %timeit pd.DatetimeIndex([i.replace(tzinfo=None) for i in t])
10 loops, best of 3: 99.7 ms per loop