2013-06-18 28 views
21

タイムスタンプのあるデータがUTCで表示されます。このタイムスタンプのタイムゾーンを 'US/Pacific'に変換し、それを階層的なインデックスとしてpandas DataFrameに追加したいと思います。私はインデックスとしてタイムスタンプを変換することができましたが、DataFrameに列やインデックスとして追加しようとすると、タイムゾーンのフォーマットが失われます。pandasのdate-timeカラムのタイムゾーンを変更し、階層インデックスとして追加

>>> import pandas as pd 
>>> dat = pd.DataFrame({'label':['a', 'a', 'a', 'b', 'b', 'b'], 'datetime':['2011-07-19 07:00:00', '2011-07-19 08:00:00', '2011-07-19 09:00:00', '2011-07-19 07:00:00', '2011-07-19 08:00:00', '2011-07-19 09:00:00'], 'value':range(6)}) 
>>> dat.dtypes 
#datetime object 
#label  object 
#value  int64 
#dtype: object 

ここでシリーズを直接変換しようとするとエラーになります。

>>> times = pd.to_datetime(dat['datetime']) 
>>> times.tz_localize('UTC') 
#Traceback (most recent call last): 
# File "<stdin>", line 1, in <module> 
# File "/Users/erikshilts/workspace/schedule-detection/python/pysched/env/lib/python2.7/site-packages/pandas/core/series.py", line 3170, in tz_localize 
# raise Exception('Cannot tz-localize non-time series') 
#Exception: Cannot tz-localize non-time series 

インデックスに変換すると、それはtimeseriesとして操作できます。インデックスに太平洋標準時が設定されていることに注目してください。

>>> times_index = pd.Index(times) 
>>> times_index_pacific = times_index.tz_localize('UTC').tz_convert('US/Pacific') 
>>> times_index_pacific 
#<class 'pandas.tseries.index.DatetimeIndex'> 
#[2011-07-19 00:00:00, ..., 2011-07-19 02:00:00] 
#Length: 6, Freq: None, Timezone: US/Pacific 

それは書式設定のタイムゾーンを失うしかし、今私は戻ってデータフレームにインデックスを追加する問題に実行:

>>> dat_index = dat.set_index([dat['label'], times_index_pacific]) 
>>> dat_index 
#          datetime label value 
#label              
#a  2011-07-19 07:00:00 2011-07-19 07:00:00  a  0 
#  2011-07-19 08:00:00 2011-07-19 08:00:00  a  1 
#  2011-07-19 09:00:00 2011-07-19 09:00:00  a  2 
#b  2011-07-19 07:00:00 2011-07-19 07:00:00  b  3 
#  2011-07-19 08:00:00 2011-07-19 08:00:00  b  4 
#  2011-07-19 09:00:00 2011-07-19 09:00:00  b  5 

あなたは、インデックスの代わりにUTCタイムゾーンに戻っているがわかります変換された太平洋標準時。

タイムゾーンを変更してDataFrameのインデックスとして追加するにはどうすればよいですか?

+3

私はこれがバグだと思っています... –

+2

これは奇妙な動作です(タイムゾーンは悪です)。おそらく[問題](https://github.com/pydata/pandas/issues)を作成する価値があります! –

+0

「タイムゾーンは悪い」 - 二番目です。 – Jason

答えて

8

これで修正されました。たとえば、次のように呼び出すことができます。

dataframe.tz_localize('UTC', level=0) 

ただし、この例では2回呼び出す必要があります。 (つまり、レベルごとに1回)

18

あなたがインデックスとして設定した場合、それは自動的にインデックスに変換されます:次に

In [11]: dat.index = pd.to_datetime(dat.pop('datetime'), utc=True) 

In [12]: dat 
Out[12]: 
        label value 
datetime 
2011-07-19 07:00:00  a  0 
2011-07-19 08:00:00  a  1 
2011-07-19 09:00:00  a  2 
2011-07-19 07:00:00  b  3 
2011-07-19 08:00:00  b  4 
2011-07-19 09:00:00  b  5 

tz_localize行います

In [12]: dat.index = dat.index.tz_localize('UTC').tz_convert('US/Pacific') 

In [13]: dat 
Out[13]: 
          label value 
datetime 
2011-07-19 00:00:00-07:00  a  0 
2011-07-19 01:00:00-07:00  a  1 
2011-07-19 02:00:00-07:00  a  2 
2011-07-19 00:00:00-07:00  b  3 
2011-07-19 01:00:00-07:00  b  4 
2011-07-19 02:00:00-07:00  b  5 

をそしてあなたがインデックスにラベル列を追加することができます:

これは間違いなくバグです。

In [14]: dat.set_index('label', append=True).swaplevel(0, 1) 
Out[14]: 
          value 
label datetime 
a  2011-07-19 07:00:00  0 
     2011-07-19 08:00:00  1 
     2011-07-19 09:00:00  2 
b  2011-07-19 07:00:00  3 
     2011-07-19 08:00:00  4 
     2011-07-19 09:00:00  5 

ハック回避策は、(それがすでにマルチインデックスだとき)(日時)が直接レベル変換することです:

In [15]: dat.index.levels[1] = dat.index.get_level_values(1).tz_localize('UTC').tz_convert('US/Pacific') 

In [16]: dat1 
Out[16]: 
           value 
label datetime 
a  2011-07-19 00:00:00-07:00  0 
     2011-07-19 01:00:00-07:00  1 
     2011-07-19 02:00:00-07:00  2 
b  2011-07-19 00:00:00-07:00  3 
     2011-07-19 01:00:00-07:00  4 
     2011-07-19 02:00:00-07:00  5 
+0

私はこれに遭遇している2つの問題があります:1)私はtz_localizeまたはtz_convertをMultiIndexで呼び出すことはできません。 2)1つのインデックスから時間フィールドにアクセスすると、太平洋の値(つまり、[0,1,2,0、 1、2])。 –

+1

申し訳ありませんが、これは間違いなく*バグです(見つけてくれてありがとう)!私は回避策を追加しました(これはMultiIndexであるとdatetimeレベルを変換することです)... –

0

回避策は、階層的なインデックスのインデックス・レベルために動作するようには思えません不変であるように見えます(FrozenListは不変です)。

単数インデックスから始まり、追加も機能しません。

タイムスタンプとしてキャストし、to_datetime()によって返されたSeriesの各メンバーを変換するラムダ関数を作成することは機能しません。

タイムゾーン対応シリーズを作成し、それをデータフレームに挿入してインデックスにする方法はありますか?

joined_event_df = joined_event_df.set_index(['pandasTime']) 
joined_event_df.index = joined_event_df.index.get_level_values(1).tz_localize('UTC').tz_convert('US/Central') 
# we have tz-awareness above this line 
joined_event_df = joined_event_df.set_index('sequence', append = True) 
# we lose tz-awareness in the index as soon as we add another index 
joined_event_df = joined_event_df.swaplevel(0,1) 
1

パンダ0.13.1で動作し、かつFrozenListが問題割り当てることができません解決し、他の回避策:

index.levels = pandas.core.base.FrozenList([ 
    index.levels[0].tz_localize('UTC').tz_convert(tz), 
    index.levels[1].tz_localize('UTC').tz_convert(tz) 
]) 

この問題に多くの苦労は、マルチインデックスは、あまりにも多くの他の条件でTZを失います。

関連する問題