尝试使用Spark SQL创建DataFrame时,通过传递一个行列表,如下所示:
some_data = [{'some-column': [{'timestamp': 1353534535353, 'strVal': 'some-string'}]},
{'some-column': [{'timestamp': 1353534535354, 'strVal': 'another-string'}]}]
spark.createDataFrame([Row(**d) for d in some_data]).printSchema()
生成的DataFrame架构是:
root
|-- some-column: array (nullable = true)
| |-- element: map (containsNull = true)
| | |-- key: string
| | |-- value: long (valueContainsNull = true)
这个模式是错误的,因为strVal列是string类型的(实际上收集此DataFrame将导致nulls此列)。
我期望模式是Array合适的Structs- 通过对值的类型的一些Python反射推断。为什么不是这样?除了在这种情况下明确提供架构之外,我还能做些什么吗?
要使用结构,您应该使用嵌套Rows(namedtuples通常是首选,但需要有效的名称标识符):
from pyspark.sql import Row
Outer = Row("some-column")
Inner = Row("timestamp", "strVal")
spark.createDataFrame([
Outer([Inner(1353534535353, 'some-string')]),
Outer([Inner(1353534535354, 'another-string')])
]).printSchema()
root
|-- some-column: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- timestamp: long (nullable = true)
| | |-- strVal: string (nullable = true)
根据您目前的结构,可以使用中间JSON实现方案结果:
import json
spark.read.json(sc.parallelize(some_data).map(json.dumps)).printSchema()
root
|-- some-column: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- strVal: string (nullable = true)
| | |-- timestamp: long (nullable = true)
或显式模式:
from pyspark.sql.types import *
schema = StructType([StructField(
"some-column", ArrayType(StructType([
StructField("timestamp", LongType()),
StructField("strVal", StringType())])
))])
spark.createDataFrame(some_data, schema)
虽然最后一种方法可能不完美。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。