将CSV载入PySpark中的DataFrame时出现问题

时间:2018-09-18 03:40:21

标签: python csv dataframe pyspark aws-glue

我正在尝试将一堆CSV文件聚合到一个文件中,并使用AWS Glue中的ETL作业以ORC格式将其输出到S3。我汇总的CSV如下所示:

header1,header2,header3
foo1,foo2,foo3
bar1,bar2,bar3

我有一个汇总的CSV字符串表示形式,称为aggregated_csv,内容为header1,header2,header3\nfoo1,foo2,foo3\nbar1,bar2,bar3。  我读过pyspark有一种直接的方式将CSV文件转换为DataFrames(我需要这样做,以便我可以利用Glue的能力轻松在ORC中输出)。这是我尝试过的代码片段:

def f(glueContext, aggregated_csv, schema):
    with open('somefile', 'a+') as agg_file:
        agg_file.write(aggregated_csv)
        #agg_file.seek(0)
        df = glueContext.read.csv(agg_file, schema=schema, header="true")
        df.show()

无论是否尝试,我都尝试过。当我不调用seek()时,作业成功完成,但是df.show()除了标题以外没有显示任何数据。当我调用seek()时,出现以下异常:

pyspark.sql.utils.AnalysisException: u'Path does not exist: hdfs://ip-172-31-48-255.us-west-2.compute.internal:8020/user/root/header1,header2,header3\n;'

由于seek似乎改变了行为,并且由于csv中的标头是异常字符串的一部分,因此我假设问题与将文件传递给{{1}时文件游标的位置有关},但我不确定如何解决。如果我取消对glueContext.read.csv()调用的注释并添加了seek(0)命令,则可以按预期看到文件的全部内容。我需要进行哪些更改才能成功读取刚刚写入Spark数据帧的csv文件?

1 个答案:

答案 0 :(得分:2)

我认为您正在将错误的参数传递给csv函数。我相信GlueContext.read.csv()将得到DataFrameReader.csv()的实例,并且它的签名将文件名作为第一个参数,并且您要传递的是一个类似文件的对象。

def f(glueContext, aggregated_csv, schema):
    with open('somefile', 'a+') as agg_file:
        agg_file.write(aggregated_csv)
        #agg_file.seek(0)
    df = glueContext.read.csv('somefile', schema=schema, header="true")
    df.show()

但是,如果您只想编写一个ORC文件,并且已经将数据读取为aggregated_csv,则可以直接从元组列表中创建DataFrame

df = spark.createDataFrame([('foo1','foo2','foo3'), ('bar1','bar2','bar3')], ['header1', 'header2', 'header3'])

然后,如果您需要胶水DynamicFrame,请使用fromDF函数

dynF = fromDF(df, glueContext, 'myFrame')

更多信息:编写ORC不需要胶水-完全可以产生火花。只需使用DataFrameWriter.orc()函数:

df.write.orc('s3://path')