如何将RDD保存到单个镶木地板文件中?

时间:2016-10-04 17:20:44

标签: python hadoop apache-spark pyspark rdd

我使用pyspark 2.0,hadoop 2.7.2。 这是我的代码:

def func(df):
    new_df = pd.DataFrame(df['id'])
    new_df['num'] = new_df['num'] * 12
    return new_df

set = sqlContext.read.parquet("data_set.parquet")
columns = set.columns
map_res = set.rdd.mapPartitions(lambda iter_: func(pd.DataFrame(list(iter_), 
                                                   columns=columns)))

现在,我需要将 map_res RDD保存为镶木地板文件 new.parquet 。 有没有什么办法可以在保存之前不创建大型数据帧的情况下做到这一点?或者可能是单独保存RDD的每个分区然后合并所有保存的文件?

P.S。我想在不创建数据帧的情况下进行管理,因为它的大小非常大。

4 个答案:

答案 0 :(得分:2)

只有两种方法可以做到这一点:

一个是使用"coalesce(1)" 这将确保将所有数据保存到1个文件而不是多个文件(200是分区的spark默认值)使用dataframe.write.save("/this/is/path")

另一个选项是将输出写入配置单元表,然后使用hive -e "select * from table" > data.tsv,它将以制表符分隔。

答案 1 :(得分:1)

我建议:

dataframes = []
#creating index
map_res = map_res.zipWithIndex()
# setting index as key
map_res = map_res.map(lambda x: (x[1],x[0]))
# creating one spark df per element
for i in range(0, map_res.count()):
    partial_dataframe_pd  = map_res.lookup(i)
    partial_dataframe = sqlContext.createDataFrame(partial_dataframe_pd)
    dataframes.append(partial_dataframe)
# concatination
result_df = dataframes.pop()
for df in dataframes:
    result_df.union(df)   
#saving
result_df.write.parquet("...")

如果您的分区数量较少(2-100),那么它的工作速度应该相当快。

答案 2 :(得分:0)

要以Parquet格式保存文件,您需要将Rdd转换为DataFrame,因为Parquet File始终需要一种架构进行处理。

答案 3 :(得分:0)

您可以使用:

set.coalesce(1).write.parquet("myFile.parquet")