我使用SparkSession.createDataFrame
从一个dict列表中创建一个Dataframe,如下所示:
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')
}
]
dataframe = sparkSession.createDataFrame(data)
但是Spark引发了一个例外:
pyspark.sql.utils.AnalysisException:无法解析给定输入列的“create_time”
这是因为PySpark无法解析datetime.datetime
类型吗?我应该如何转换'create_time'的值,以便让Spark将此列识别为datetime类型?
3条答案
按热度按时间wlwcrazw1#
为了解决这个问题,我们需要了解列表、元组和数据类型。这是创建转换为 Dataframe 的Python结构的关键。但是,推断模式与定义模式同样重要。
首先,我将从两个元组创建一个dataframe。第一个字段是整数,第二个字段是字符串。我将数据和列作为参数提供。在这种情况下,Spark正在推断数据。
下面的屏幕显示数据在源列表中被格式化为数字和字符串。由于我们只是将没有任何模式定义的列名传递给create data frame方法,因此将推断出结果数据类型。得到的 Dataframe 具有用于列的long和string数据类型。
其次,我们不仅可以在源列表中更改数据类型,还可以提供模式。对于大型ASCII格式(如CSV、JSON和XML),提供模式是关键。这会阻止Spark引擎阅读整个文件来推断数据类型。
下面的图像显示我们现在有一个整数和时间戳数据类型的列表和 Dataframe 。
有时候,数据本身就是有问题的。因此,我们希望将数据作为字符串导入,然后应用转换函数。
第三,之后的数据转换很好地处理了畸形数据。
下图显示了年份为“2”的日期被转换为空值,因为它无效。这种格式错误的数据会破坏上面的时间戳示例。
简而言之,了解您的传入数据。分析数据的错误值。然后确定加载数据的最佳方法。请始终记住,提供模式会加快某些类型文件的加载速度。
6rqinv9w2#
正如已经提到的评论:使用整数表示日期时间:
在这里,我建议遵循官方文档,并使用Spark为SparkSession处理相同的变量命名。
关于你在评论中的问题:
如果你检查你的 Dataframe
您可能会注意到,
create_time
和id
都有一个类型。这是合理的,因为每个数据项都需要一个数据类型。在Python中,数据类型是动态提供的。我在这里假设(我并不完全喜欢Spark)Spark Dataframe 使用静态数据类型。因此,即使您没有指定id
列的类型,只要您使用createDataFrame
方法,该类型将根据此时number变量类型的数据类型确定。所以基本上如果我用它将不被表示为
bigint
,而是被表示为double
。如果你尝试混合两个类型,比如第一个是double
,第二个是bigint
,你会看到这个错误消息:这在某种程度上证明了我对静态类型的假设。
因此,即使您不想使用模式,Spark也会根据您的
data
输入确定模式,如下所示会出现的。
qhhrdooz3#
对于那些寻找更短版本的人: