PySpark处理纪元前时间戳调用toPandas()报错的解决办法问询
解决Spark纪元前时间戳转Pandas报错的问题
错误原因
你遇到的问题本质是Windows系统下Python的datetime.fromtimestamp()不支持解析1970年1月1日(Unix纪元)之前的时间戳,而Spark在将TimestampType数据转换为Python datetime对象时调用了这个方法,因此触发OSError: [Errno 22] Invalid argument。
可行解决方法
方法1:避免在Spark中转换为Timestamp类型
如果业务不需要对时间做Spark侧的日期运算,直接保留原始字符串格式,跳过to_timestamp转换,直接转Pandas:
df = ss.createDataFrame([('1969-12-31 18:59:59',)], ['col_timestamp']) # 直接导出字符串格式的时间 df.select('col_timestamp').toPandas()
方法2:Spark侧输出字符串,Pandas侧再解析时间
如果需要在Pandas中使用datetime类型,可以让Spark输出原始时间字符串,然后在Pandas中用strptime解析(该方法支持纪元前时间):
import datetime df = ss.createDataFrame([('1969-12-31 18:59:59',)], ['col_timestamp']) # 先导出字符串列 df_pd = df.select('col_timestamp').toPandas() # 在Pandas侧解析为datetime df_pd['col_datetime'] = df_pd['col_timestamp'].apply( lambda x: datetime.datetime.strptime(x, '%Y-%m-%d %H:%M:%S') )
方法3:用Unix时间戳+第三方库解析
先在Spark中将时间转换为Unix时间戳(纪元前的时间会是负数),导出到Pandas后用支持宽时间范围的库(如PyArrow)解析:
import pyarrow as pa from pyspark.sql.functions import unix_timestamp, col df = ss.createDataFrame([('1969-12-31 18:59:59',)], ['col_timestamp']) # 转换为Unix时间戳(单位:秒) df_ts = df.select( unix_timestamp(col('col_timestamp'), 'yyyy-MM-dd HH:mm:ss').alias('unix_ts') ).toPandas() # 用PyArrow解析负数时间戳 df_ts['col_datetime'] = df_ts['unix_ts'].apply( lambda x: pa.TimestampValue(x, unit='s').as_py() )
内容的提问来源于stack exchange,提问作者bezbiker
相关产品推荐
相关产品推荐

