我有来自不同时代和各大洲的许多温度测量数据。 我将数据加载到rdd(我在此代码示例中给出了数据示例),按键组合,然后将dicts列表转换为dataframe。
def to_list(a):
return [a]
def append(a, b):
a.append(b)
return a
def extend(a, b):
a.extend(b)
return a
def main():
sc = pyspark.SparkContext()
parsing_obj = [[('Africa', {'time': '1', 'temp': '2'})], [('Africa', {'time': '1', 'temp': '2'})],
[('America', {'time': '1', 'temp': '2'})], [('America', {'time': '1', 'temp': '2'})],
[('Africa', {'time': '1', 'temp': '2'})]]
rdd = sc.parallelize(parsing_obj)
rdd = rdd.map(lambda l: l[0]).combineByKey(to_list, append, extend)
print rdd.collect()
这个数据结构输出:
[
('Africa', [{'temp': '2', 'time': '1'}, {'temp': '2', 'time': '1'}, {'temp': '2', 'time': '1'}]),
('America', [{'temp': '2', 'time': '1'}, {'temp': '2', 'time': '1'}])
]
\ 有没有办法在没有驱动驱动程序中的rdd的每个键,创建数据帧并保存到hdfs? 我希望采用更加平行和通用的方式来实现它。
答案 0 :(得分:0)
您可以简单地执行以下操作
parsing_obj = [[('Africa', {'time': '1', 'temp': '2'})], [('Africa', {'time': '1', 'temp': '2'})],
[('America', {'time': '1', 'temp': '2'})], [('America', {'time': '1', 'temp': '2'})],
[('Africa', {'time': '1', 'temp': '2'})]]
df = sc.parallelize(parsing_obj).toDF(['info'])
df = df.select(df.info._1.alias('country'), df.info._2.alias('info'))
from pyspark.sql import functions as F
df = df.groupBy(df.country).agg(F.collect_list(df.info).alias('info'))
df.show(truncate=False)
会给你
+-------+---------------------------------------------------------------------------------+
|country|info |
+-------+---------------------------------------------------------------------------------+
|Africa |[Map(temp -> 2, time -> 1), Map(temp -> 2, time -> 1), Map(temp -> 2, time -> 1)]|
|America|[Map(temp -> 2, time -> 1), Map(temp -> 2, time -> 1)] |
+-------+---------------------------------------------------------------------------------+
您可以将其另存为parquet
文件
df.coalesce(1).write.parquet('path to parquet file`)
<强>更新强>
如果您不希望保存表格的schema
并希望将其保存为纯文本csv ,那么您将需要转换字典和数组到纯文本。我有定义了一个udf
函数,用于将dict转换为文本json,并使用concat_ws
将所有列转换为csv文本
from pyspark.sql import functions as F
from pyspark.sql import types as T
import json
def makeStringFunc(list):
return '['+', '.join(json.dumps(x).replace("\"", "'") for x in list)+']'
makeStringUdf = F.udf(makeStringFunc, T.StringType())
df = df.groupBy(df.country)\
.agg(makeStringUdf(F.collect_list(df.info)).alias('info'))\
.select(F.concat_ws(", ", F.col('country'), F.col('info')))
应该是
+--------------------------------------------------------------------------------------------+
|concat_ws(, , country, info) |
+--------------------------------------------------------------------------------------------+
|Africa, [{'temp': '2', 'time': '1'}, {'temp': '2', 'time': '1'}, {'temp': '2', 'time': '1'}]|
|America, [{'temp': '2', 'time': '1'}, {'temp': '2', 'time': '1'}] |
+--------------------------------------------------------------------------------------------+
您可以使用csv
函数
df.coalesce(1).write.csv("path to ouput path")