在Spark中使用不同标头的CSV文件形成DataFrame

时间:2018-02-15 17:17:13

标签: java csv apache-spark apache-spark-sql spark-dataframe

我正在尝试使用变量列表读取Gzipped CSV的文件夹(没有扩展名)。 e.g:

CSV file 1: TIMESTAMP | VAR1 | VAR2 | VAR3

CSV file 2: TIMESTAMP | VAR1 | VAR3

每个文件代表一天。列的顺序可以不同(或者一个文件上可能缺少列)。

使用spark.read一次性读取整个文件夹的第一个选项将被丢弃,因为文件之间的连接考虑了列顺序而不是列名。 我的下一个选择是按文件阅读:

 for (String key : pathArray) {
       Dataset<Row> rawData = spark.read().option("header", true).csv(key);
       allDatasets.add(rawData);
    }

然后对列名进行完全外连接:

Dataset<Row> data = allDatasets.get(0);
     for (int i = 1; i < allDatasets.size(); i++) {
        ArrayList<String> columns = new 
        ArrayList(Arrays.asList(data.columns()));
        columns.retainAll(new  
        ArrayList(Arrays.asList(allDatasets.get(i).columns())));
        data = data.join(allDatasets.get(i), 
        JavaConversions.asScalaBuffer(columns), "outer");
      }

但是这个过程非常慢,因为它一次加载一个文件。

下一种方法是使用sc.binaryFilessc.readFiles一样,无法为添加自定义Hadoop编解码器制定解决方法(为了能够在没有gz的情况下读取Gzip文件延伸)。

使用最新方法并将this code翻译成Java我有以下内容:

  • 包含变量名称JavaPairRDD<String, Iterable<Tuple2<String, String>>>)的VAR1以及TIMESTAMP,VALUE的可迭代元组VAR

我想用这个表示所有文件的DataFrame,但是我完全迷失了如何将最终的PairRDD转换为Dataframe。 DataFrame应该一起表示所有文件的内容。我想要的最终DataFrame示例如下:

  TIMESTAMP | VAR1 | VAR2 | VAR3 
   01           32      12    32  ==> Start of contents of file 1
   02           10       5     7  ==> End of contents of file 1
   03                    1     5  ==> Start of contents of file 2
   04                    4     8  ==> End of contents of file 2

有任何建议或想法吗?

1 个答案:

答案 0 :(得分:0)

最后,我得到了非常好的表现:

  1. 按月阅读&#34;背景&#34; (使用Java Executor并行读取其他文件夹与CSV&#s;),使用此方法,Driver扫描每个文件夹时所花费的时间减少,因为并行完成。
  2. 接下来,该过程一方面提取标题,另一方面提取其内容(带有varname,timestamp,value的元组)。
  3. 最后,使用RDD API将内容合并,并使用标头创建Dataframe。