Spark只在第一个文件中读取带有标题的多个CSV文件

时间:2018-04-09 06:59:33

标签: java apache-spark

我想从spark中读取多个CSV文件,但标题仅出现在第一个文件中,如:

文件1:

id, name
1, A
2, B
3, C

文件2:

4, D
5, E
6, F

PS:我想使用java API来做到这一点

3 个答案:

答案 0 :(得分:1)

您可以使用header = true并使用inferSchema = true从具有标题的文件中获取正确的数据类型。然后将此模式类型转换为Java中的StructType,并使用该模式类型导入其他没有头的csv文件。这已在Spark版本2.3.2中进行了测试

    import org.apache.spark.sql.Dataset;
    import org.apache.spark.sql.Row;
    import org.apache.spark.sql.SparkSession;


    SparkSession spark = SparkSession.builder()
        .appName("SimpleApp")
        .master("local")
        .getOrCreate();

  // Use this to get the headers automatically
    Dataset<Row> csvData = sparkSession.read()
       .format("csv")
       .option("header","true")
       .option("inferSchema","true")
       .load("C:\\MyData\\numData.csv");

    csvData.printSchema();

答案 1 :(得分:0)

您需要执行以下操作

Scala解决方案:

val sqlContext = new SQLContext(sc)

val file1DF = sqlContext
  .read
  .format("csv")
  .option("header", "true")
  .load("file1.csv")

val schema = file1.schema

val file2DF = sqlContext
  .read
  .format("csv")
  .schema(schema)
  .load("file2.csv")

Java将是类似的例外,您将希望使用StructType作为架构。

DataFrame file1DF = sqlContext.read()....;
StructType schema = file1DF.schema();
DataFrame file2DF = sqlContext.read()....schema(schema)....;

答案 2 :(得分:0)

当然,如果不是全部,您肯定会知道具有标题的文件的名称。 在这种情况下,从现有answer扩展,假设带有标题的文件名为h.csv

val sqlContext = new SQLContext(sc)

val file1DF = sqlContext
  .read
  .format("csv")
  .option("header", "true")
  .load("<path to folder>/h.csv")

val schema = file1.schema

val file2DF = sqlContext
  .read
  .format("csv")
  .schema(schema)
  .load("<path to folder>/{[^h],h[^.]}*.csv")

现在,提供的正则表达式功能并不太精致。但是,我不认为Spark DataFrameReader.load public api为我们提供了排除特定名称的强大方法。

此API接受的更多指向glob模式的链接是@ answer

来自hadoop的内部API虽然似乎允许过滤(在上面的答案中链接的相关书籍部分的图片下方):

PathFilter

对于您的情况,您可能希望使用带有简单名称的标题命名您的文件,例如h.csv以及上述代码中第二部分的正则表达式可能包含{[^h],h[^.]}*.csv,以包含所有不以h开头的文件,或者如果它们以h开头,那么第二个字符不是.