以下元组列表的正确 PySpark 模式应该是什么?我想将架构应用于以下数据:
[('a', 0.0), ('b', 6), ('c', 44), ('d', 107), ('e', 0), ('f', 3), ('g', 4), ('h', 0.025599999353289604), ('i', 0.03239999711513519), ('j', -0.03205680847167969), ('k', 0.10429033637046814), ('l', (34.190006256103516, 31.09000015258789, 31.099994659423828)), ('m', (-9.32000732421875, -9.32000732421875, -11.610000610351562)) ]
我希望结果采用以下格式: Format
答案 0 :(得分:1)
在使Spark等效之前,亲自描述元组会有所帮助。在Python中,似乎您有一个包含2个元素的元组。第一个是String
,第二个是由3个Double
值组成的另一个元组。前几项不一定符合此要求,但您不能期望有一个“动态”模式,但看起来至少第二个元组中的String和第一个数字始终存在。无论如何,表示这种数据类型的一种方法如下:
(String, (Double, Double, Double))
与此相对应的Pyspark模式为:
from pyspark.sql.types import StructType, StructField, StringType, DoubleType
schema = StructType([
StructField('char', StringType(), nullable=False),
StructType([
StructField('num_1', DoubleType, nullable=False),
StructField('num_2', DoubleType, nullable=True),
StructField('num_3', DoubleType, nullable=True),
])
])
答案 1 :(得分:1)
尽管我想提出另一种方法,但天津的答案应该可行。无需找出应该添加到架构中的列数来创建array / list类型的列。接下来的代码将您的数据转换为rdd,而不是元组包含[key,value]的行,其中value是双精度的列表。然后,您可以轻松地应用以下架构。
for key in dict.keys():
print(key)
请注意,to_float_list函数接受一个元组或一个数字,并将其转换为一个double列表。这将输出:
def test():
l = [('a', 0.0),
('b', 6),
('c', 44),
('d', 107),
('e', 0),
('f', 3),
('g', 4),
('h', 0.025599999353289604),
('i', 0.03239999711513519),
('j', -0.03205680847167969),
('k',0.10429033637046814),
('l',(34.190006256103516, 31.09000015258789, 31.099994659423828)),
('m',(-9.32000732421875, -9.32000732421875, -11.610000610351562))]
# this schema should work for all your cases
schema = StructType([
StructField("id", StringType(), False),
StructField("num_list", ArrayType(DoubleType(), True), True)
])
rdd = spark.sparkContext.parallelize(l).map(lambda r: (r[0], to_float_list(r[1])))
df = spark.createDataFrame(rdd, schema)
df.show(100, False)
def to_float_list(value):
if type(value) is tuple:
return list(map(float, value))
return [float(value)]