在我的应用程序中,我从S3上不同位置的数据创建不同的数据帧,然后尝试将数据帧合并为单个数据帧。现在我正在使用for循环。但我有一种感觉,这可以通过在pyspark中使用map和reduce函数以更有效的方式完成。这是我的代码:
from pyspark import SparkConf, SparkContext
from pyspark.sql import SQLContext, GroupedData
import pandas as pd
from datetime import datetime
sparkConf = SparkConf().setAppName('myTestApp')
sc = SparkContext(conf=sparkConf)
sqlContext = SQLContext(sc)
filepath = 's3n://my-s3-bucket/report_date='
date_from = pd.to_datetime('2016-08-01',format='%Y-%m-%d')
date_to = pd.to_datetime('2016-08-22',format='%Y-%m-%d')
datelist = pd.date_range(date_from, date_to)
First = True
#THIS is the for-loop I want to get rid of
for dt in datelist:
date_string = datetime.strftime(dt, '%Y-%m-%d')
print('Running the pyspark - Data read for the date - '+date_string)
df = sqlContext.read.format("com.databricks.spark.csv").options(header = "false", inferschema = "true", delimiter = "\t").load(filepath + date_string + '/*.gz')
if First:
First=False
df_Full = df
else:
df_Full = df_Full.unionAll(df)
答案 0 :(得分:2)
实际上,迭代union
虽然不是最理想的,但并不是最重要的问题。模式推理(inferschema = "true"
)引入了更为严重的问题。
它不仅使数据帧创建不是懒惰的,而且还需要单独的数据扫描来进行推理。如果您事先知道架构,则应将其作为DataFrameReader
的参数:
schema = ...
df = sqlContext.read.format("com.databricks.spark.csv").schema(schema)
否则你可以从第一个DataFrame
中提取它。结合良好的并行性,它应该可以正常工作,但如果你获取的文件数量很大,你应该考虑比迭代联合更聪明的方法。您在我对Spark union of multiple RDDs的回答中找到了一个示例。它更昂贵但具有更好的一般性能。
关于您的想法,无法在分布式数据结构上嵌套操作,因此如果您想要读取map
内的数据,您必须直接使用S3客户端而不使用SQLContext
。< / p>