使用SparkSession.createDataFrame时,如何让PySpark识别datetime类型列?
问题原因与解决方法
你的判断没错,PySpark直接处理Python原生datetime.datetime类型时确实会出现解析问题——在字典列表创建DataFrame的场景下,Spark的自动类型推断机制无法正确识别该类型,最终导致列解析失败,抛出你看到的AnalysisException。
下面是几种可行的解决方法:
方法一:手动指定Schema(最推荐)
通过pyspark.sql.types定义明确的Schema,直接告诉Spark各列的数据类型,避免自动推断的不确定性:
import datetime from pyspark.sql import SparkSession from pyspark.sql.types import StructType, StructField, IntegerType, TimestampType sparkSession = SparkSession.builder.appName("test").getOrCreate() data=[ { 'id':1, 'create_time':datetime.datetime(2022,9,9,0,0,0) }, { 'id':2, 'create_time':datetime.datetime(2022,9,9,0,0,0) } ] # 定义Schema schema = StructType([ StructField("id", IntegerType(), nullable=False), StructField("create_time", TimestampType(), nullable=False) ]) dataframe = sparkSession.createDataFrame(data, schema=schema) dataframe.show() dataframe.printSchema()
方法二:将datetime转换为ISO字符串后再转类型
先把Python datetime对象转成标准ISO格式的字符串,再通过Spark的to_timestamp函数将列转为Timestamp类型:
import datetime from pyspark.sql import SparkSession from pyspark.sql.functions import to_timestamp sparkSession = SparkSession.builder.appName("test").getOrCreate() # 把datetime转成ISO格式字符串 data=[ { 'id':1, 'create_time':datetime.datetime(2022,9,9,0,0,0).isoformat() }, { 'id':2, 'create_time':datetime.datetime(2022,9,9,0,0,0).isoformat() } ] dataframe = sparkSession.createDataFrame(data) # 转换为Timestamp类型 dataframe = dataframe.withColumn("create_time", to_timestamp("create_time")) dataframe.show() dataframe.printSchema()
方法三:使用Row对象代替字典
PySpark对Row对象的类型推断更友好,用Row构造数据可以让Spark正确识别datetime类型:
import datetime from pyspark.sql import SparkSession, Row sparkSession = SparkSession.builder.appName("test").getOrCreate() data=[ Row(id=1, create_time=datetime.datetime(2022,9,9,0,0,0)), Row(id=2, create_time=datetime.datetime(2022,9,9,0,0,0)) ] dataframe = sparkSession.createDataFrame(data) dataframe.show() dataframe.printSchema()
内容的提问来源于stack exchange,提问作者Rinze
相关产品推荐
相关产品推荐

