我建议采用以下两种方法中的一种(实际上我发现第一种方法在性能方面给出了更好的结果) .
将每个Zip文件写入单独的Parquet文件
在这里你可以使用 pyarrow 将一个Parquet文件写入HDFS:
def convert_gzip_to_parquet(file_from, file_to):
gzipped_csv = read_gzip_file(file_from)
pyarrow_table = to_pyarrow_table(gzipped_csv)
hdfs_client = pyarrow.HdfsClient()
with hdfs_client.open(file_to, "wb") as f:
pyarrow.parquet.write_table(pyarrow_table, f)
# Filename RDD contains tuples with file_from and file_to
filenameRDD.map(lambda x: convert_gzip_to_parquet(x[0], x[1]))
有两种方法可以获取pyarrow.Table对象:
要么从pandas DataFrame中获取它(在这种情况下你也可以使用pandas的read_csv()函数): pyarrow_table = pyarrow.Table.from_pandas(pandas_df)
要使pyarrow使用HDFS,需要正确设置多个环境变量,请参阅here
将所有Zip-Files中的行连接到一个Parquet-File中
def get_rows_from_gzip(file_from):
rows = read_gzip_file(file_from)
return rows
# read the rows of each zip file into a Row object
rows_rdd = filenameRDD.map(lambda x: get_rows_from_gzip(x[0]))
# flatten list of lists
rows_rdd = rows_rdd.flatMap(lambda x: x)
# convert to DataFrame and write to Parquet
df = spark_session.create_DataFrame(rows_rdd)
df.write.parquet(file_to)
如果您事先知道数据的架构,则将架构对象传递给 create_DataFrame 将加速DataFrame的创建 .