我正在使用带有DatetimeIndex
的Pandas数据帧来操作时间序列数据。数据存储在UTC
时间,我通常保持这种方式(使用naive DatetimeIndex
),并且只使用时区进行输出。我喜欢这样,因为世界上没有什么比试图操纵时区更让我困惑。
e.g。
In: ts = pd.date_range('2017-01-01 00:00','2017-12-31 23:30',freq='30Min')
data = np.random.rand(17520,1)
df= pd.DataFrame(data,index=ts,columns = ['data'])
df.head()
Out[15]:
data
2017-01-01 00:00:00 0.697478
2017-01-01 00:30:00 0.506914
2017-01-01 01:00:00 0.792484
2017-01-01 01:30:00 0.043271
2017-01-01 02:00:00 0.558461
我想绘制一年中每一天的数据与时间的关系图,因此我重新设计数据框,以便在索引和列日期之间留出时间
df.index = [df.index.time,df.index.date]
df_new = df['data'].unstack()
In: df_new.head()
Out :
2017-01-01 2017-01-02 2017-01-03 2017-01-04 2017-01-05 \
00:00:00 0.697478 0.143626 0.189567 0.061872 0.748223
00:30:00 0.506914 0.470634 0.430101 0.551144 0.081071
01:00:00 0.792484 0.045259 0.748604 0.305681 0.333207
01:30:00 0.043271 0.276888 0.034643 0.413243 0.921668
02:00:00 0.558461 0.723032 0.293308 0.597601 0.120549
如果我不担心时区,我可以这样画:
fig, ax = plt.subplots()
ax.plot(df_new.index,df_new)
但是我想在当地时区(tz = pytz.timezone('Australia/Sydney'
)绘制数据,以节省夏令时,但时间和日期不再是Timestamp
个对象,所以我无法使用熊猫时区处理。或者我可以吗?
假设我不能,我试图手动换班(给定DST从凌晨2点开始1/10,凌晨2点结束1/4),所以我已经走到了这一步:
df_new[[c for c in df_new.columns if c >= dt.datetime(2017,4,1) and c <dt.datetime(2017,10,1)]].shift_by(+10)
df_new[[c for c in df_new.columns if c < dt.datetime(2017,4,1) or c >= dt.datetime(2017,10,1)]].shift_by(+11)
但我不确定如何编写函数shift_by
。
(这在正确的转换日期间不会在午夜到凌晨2点处理,这不太理想,但我可以忍受)
答案 0 :(得分:3)
使用dt.tz_localize
+ dt.tz_convert
将数据框日期转换为特定时区。
df.index = df.index.tz_localize('UTC').tz_convert('Australia/Sydney')
df.index = [df.index.time, df.index.date]
在创建MuliIndex
时要小心 - 正如您所观察到的那样,它会创建两行重复的时间戳,所以如果是这样的话,请使用duplicated
删除它:< / p>
df = df[~df.index.duplicated()]
df = df['data'].unstack()
您还可以使用df.plot
:
df.plot(subplots=True)
plt.show()