Pandas时间比较报错:无法比较无时区与时区感知时间对象
问题定位与解决
核心问题
报错根源是时区不匹配:tweets['post_date']是不带时区信息(tz-naive)的datetime64[ns]类型,但stock数据的索引是带时区(tz-aware)的时间戳(如报错信息中的2015-01-01 12:00:00-05:00),两者直接比较运算时,pandas会抛出类型错误。
解决方案
统一两边的时区状态(要么都带时区,要么都不带),以下两种方案任选其一:
方案1:给tweets的时间列添加时区信息
修改时间处理代码,将tweets['post_date']转换为带时区的datetime对象(时区需与stock索引的时区一致,示例用美国东部时区):
import pytz import pandas as pd from datetime import timedelta # 转换时间并设置时区(先转UTC再转目标时区,确保准确性) tweets['post_date'] = pd.to_datetime(tweets['post_date'], unit='s').dt.tz_localize('UTC').dt.tz_convert('America/New_York') # 简化日期列生成,避免循环apply tweets['date'] = tweets['post_date'].dt.date
方案2:移除stock索引的时区信息
在getAvgPerPrice函数中,先将stock的索引转换为无时区的datetime:
from datetime import timedelta import pandas as pd def getAvgPerPrice(tweets, stockk): stock = stockk.copy() # 移除索引的时区信息,转为tz-naive stock.index = stock.index.tz_localize(None) result = pd.DataFrame([]) for i in range(0, len(stock)-1): d = stock.index[i] next_d = stock.index[i+1] wanted_tweets = tweets[((tweets.post_date - timedelta(hours=3)) >= (d + timedelta(hours=h))) & ((tweets.post_date - timedelta(hours=3)) < (next_d + timedelta(hours=h)))] result.at[i,'date'] = d result.at[i,'close'] = stock.iloc[i].Close result.at[i,'avgScore'] = wanted_tweets['score'].mean() return result
额外优化
原代码中生成date列的方式可简化为矢量化操作,比循环apply更高效:
# 替换原apply写法 tweets['date'] = tweets['post_date'].dt.date
内容的提问来源于stack exchange,提问作者Deniz Turan
相关产品推荐
相关产品推荐

