拼接Pandas DataFrame时的时区不一致问题排查与修复
问题根因
- Pandas的
tz_localize()、tz_convert()方法默认不修改原DataFrame对象,执行后会返回处理后的新对象。你的代码里调用这两个方法后没有将返回值重新赋值给原变量,两行时区处理代码实际没有生效。 - IB接口返回的两类时间数据本身属性存在差异:调用
reqHistoricalData时传入formatDate=1,返回的date字段是无时区标识的朴素时间,对应Pacific/Johnston时区的本地时间;而reqRealTimeBars返回的bar.time是自带UTC时区标识的时间戳。未生效的时区处理+原始数据的时区属性差,直接导致拼接后索引时区不统一。
修复方法
给时区处理的代码加上返回值赋值即可,修正后的核心代码如下:
def onBarUpdate(bars, hasNewBar): df_new_bar = pd.DataFrame([[bars[-1].time, bars[-1].open_, bars[-1].high, bars[-1].low, bars[-1].close, bars[-1].count]], columns=['date', 'open', 'high', 'low', 'close', 'volume']) df_new_bar.set_index('date', inplace=True) # 接收tz_convert返回的处理后对象 df_new_bar = df_new_bar.tz_convert('Pacific/Johnston') df_5_sec = pd.concat([df_5_sec, df_new_bar], axis='rows') print(df_5_sec.tail(5)) def main(): bars_hist = ib.reqHistoricalData( contract, endDateTime='', durationStr='2500 S', barSizeSetting='5 secs', whatToShow='TRADES', useRTH=True, keepUpToDate=False, formatDate=1) df_5_sec = pd.DataFrame(bars_hist) df_5_sec.set_index('date', inplace=True) # 接收tz_localize返回的处理后对象 df_5_sec = df_5_sec.tz_localize('Pacific/Johnston') bars = ib.reqRealTimeBars(contract, 5, 'TRADES', False) ib.barUpdateEvent += onBarUpdate
修复后历史数据和实时数据的date索引会统一为Pacific/Johnston时区,拼接后不会出现时间格式、时区不一致的问题。如果需要增加鲁棒性,可以在拼接前增加时区校验逻辑,确认两边索引时区一致再执行concat操作。
内容的提问来源于stack exchange,提问作者R M
相关产品推荐
相关产品推荐

