我在spark数据帧中遇到了一个非常奇怪的错误,该错误导致将字符串作为时间戳进行评估。
这是我的设置代码:
from datetime import datetime
from pyspark.sql import Row
from pyspark.sql.types import StructType, StructField, StringType, TimestampType
new_schema = StructType([StructField("item_id", StringType(), True),
StructField("date", TimestampType(), True),
StructField("description", StringType(), True)
])
df = sqlContext.createDataFrame([Row(description='description', date=datetime.utcnow(), item_id='id_string')], new_schema)
这给了我以下错误:
这似乎是将字符串传递给TimestampType.toInternal()
真正奇怪的是,此数据框会产生相同的错误:
df = sqlContext.createDataFrame([Row(description='hey', date=None, item_id='id_string')], new_schema)
虽然这一工程:
df = sqlContext.createDataFrame([Row(description=None, date=datetime.now(), item_id='id_string')], new_schema)
这个也很好:
df = sqlContext.createDataFrame([Row(description=None, date=datetime.now(), item_id=None)], new_schema)
对我来说,这意味着pyspark会以某种方式将“item_id”中的值放入“日期”列中,因此会产生此错误。
我做错什么了吗?这是数据框中的错误吗?
信息:
我正在使用pyspark 2.0.1
编辑:
df = sqlContext.createDataFrame([Row(description=None, date=datetime.now(), item_id=None)], new_schema)
df.first()
最佳答案
创建Row对象时,字段将按字母顺序(http://spark.apache.org/docs/2.0.1/api/python/pyspark.sql.html#pyspark.sql.Row)进行排序,因此,当您创建Row(description, date, item_id)
对象时,该对象将按(date, description, item_id)
进行排序。
由于您的架构按StringType, TimestampType, StringType
排序,因此在创建具有此Row和架构的DataFrame时,Spark会将date
中的内容映射到StringType
,将description
中的内容映射到TimestampType
,将item_id
中的内容映射到StringType
。
将时间戳记(以datetime
格式)传递给StringType
不会导致错误,但是将字符串传递给TimestampType
却会导致错误,因为它要求提供tzinfo
属性,正如错误所指出的那样,String对象没有该属性。
同样,为您工作的数据框实际工作的原因是因为None
被传递到架构中的TimestampType
,这是一个可接受的值。