pandas.to_datetime转换Unix时间为本地时区的方法及报错处理
问题说明
需要通过pandas.to_datetime将Unix毫秒时间戳转换为US/Central时区的本地时间,现有代码运行后时间不符合预期,且时区转换时报错。
现有代码
def _new_values_list(arg1=list()): import time keys = arg1[1] sym = arg1[0] """ ========================================================================== :param: 接收seperate_key_value()返回的变量形式数据,通常为candle_data、candleD等K线数据 ========================================================================== :returns: 排序后的pandas DataFrame,包含开盘、最高、最低、收盘、成交量列,datetime为索引,同时包含epoch时间列方便时间序列计算 ========================================================================== """ o = [] for vals in keys: o.append(vals['open']) h = [] for vals in keys: h.append(vals['high']) l = [] for vals in keys: l.append(vals['low']) c = [] for vals in keys: c.append(vals['close']) etime = [] for vals in keys: etime.append(vals['datetime']) time = [] for vals in keys: vals = pd.to_datetime(vals['datetime'], unit='ms') time.append(vals) vol = [] for vals in keys: vol.append(vals['volume']) df = pd.DataFrame({'unix_time':etime, 'datetime': time, 'open': o, 'high': h, 'low': l, 'close': c,'volume': vol}) return df
遇到的问题
- datetime列显示的时间为UTC时间,比US/Central时区快6小时,例如本应显示为
08:30:00的时间实际输出为14:30:00 - 执行
new_data['datetime'].tz_convert('US/Central')转换时区时抛出TypeError,错误信息如下:
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-93-1843a60046f9> in <module> 3 data = _values_list(rdata) 4 new_data = _new_values_list(rdata) ----> 5 new_data['datetime'].tz_convert('US/Central') 6 new_data['std'] = new_data['close'] - new_data['open'] 7 new_data['std'] = new_data['std'].std() ~\anaconda3\lib\site-packages\pandas\core\generic.py in tz_convert(self, tz, axis, level, copy) 9773 if level not in (None, 0, ax.name): 9774 raise ValueError(f"The level {level} is not valid") -> 9775 ax = _tz_convert(ax, tz) 9776 9777 result = self.copy(deep=copy) ~\anaconda3\lib\site-packages\pandas\core\generic.py in _tz_convert(ax, tz) 9755 if len(ax) > 0: 9756 ax_name = self._get_axis_name(axis) -> 9757 raise TypeError( 9758 f"{ax_name} is not a valid DatetimeIndex or PeriodIndex" 9759 ) TypeError: index is not a valid DatetimeIndex or PeriodIndex
解决方案
问题原因
- 默认
pd.to_datetime处理时间戳生成的是无时区信息的原生datetime对象,默认按UTC时间显示,没有绑定时区属性,无法直接调用tz_convert转换时区 tz_convert仅支持对已绑定时区的datetime对象、DatetimeIndex或PeriodIndex调用,普通原生datetime列的Series不支持直接调用该方法
修改后代码
方案1:生成时间时直接转换为目标时区(推荐)
在调用pd.to_datetime时直接指定UTC时区,再转换为US/Central时区,同时按照函数注释要求将datetime设为索引:
def _new_values_list(arg1=list()): import time keys = arg1[1] sym = arg1[0] """ ========================================================================== :param: 接收seperate_key_value()返回的变量形式数据,通常为candle_data、candleD等K线数据 ========================================================================== :returns: 排序后的pandas DataFrame,包含开盘、最高、最低、收盘、成交量列,datetime为索引,同时包含epoch时间列方便时间序列计算 ========================================================================== """ o = [] for vals in keys: o.append(vals['open']) h = [] for vals in keys: h.append(vals['high']) l = [] for vals in keys: l.append(vals['low']) c = [] for vals in keys: c.append(vals['close']) etime = [] for vals in keys: etime.append(vals['datetime']) time = [] for vals in keys: # 新增utc=True绑定UTC时区,直接转换为US/Central时区 vals = pd.to_datetime(vals['datetime'], unit='ms', utc=True).tz_convert('US/Central') time.append(vals) vol = [] for vals in keys: vol.append(vals['volume']) df = pd.DataFrame({'unix_time':etime, 'datetime': time, 'open': o, 'high': h, 'low': l, 'close': c,'volume': vol}) # 按注释要求将datetime设为索引 df = df.set_index('datetime') return df
方案2:对现有DataFrame的datetime列转换时区
如果不想修改原有函数逻辑,可在得到返回结果后,通过dt访问器完成时区转换:
# 先给原生datetime绑定原始UTC时区,再转换为US/Central new_data['datetime'] = new_data['datetime'].dt.tz_localize('UTC').dt.tz_convert('US/Central') # 如果需要设为索引: new_data = new_data.set_index('datetime')
内容的提问来源于stack exchange,提问作者CMWolfe
相关产品推荐
相关产品推荐

