如何加载带有混洗列的多个csv文件?

时间:2019-04-01 13:37:08

标签: apache-spark apache-spark-sql bigdata

我有多个要加载到蜂巢表中的csv文件,我的问题是我的csv文件头的顺序不固定。

如果我有两个csv文件

sample1.csv 

  column1,column2
      "A","B"

sample2.csv

column2,column1
"A","B"

我正在尝试使用以下代码。

spark.sql("drop table if exists faizan.sample")
val df = spark.read.format("csv").option("wholeFile", true).option("multiline",true).option("inferSchema", "true").option("header", true).option("escape","\"").csv("faizan/sample/sample/sample1.csv", "faizan/sample/sample/sample3.csv")
val newNames = Seq("column1","column2") 
val dfRenamed = df.toDF(newNames: _*)
    dfRenamed.createOrReplaceTempView("tempTable")
val tempDf = spark.sql("select * from tempTable where")
    tempDf.write.saveAsTable("faizan.sample")

我正在输出:

+-------+-------+
|column1|column2|
+-------+-------+
|      A      B|
|      A      B|
+-------+-------+

预期输出:

+-------+-------+
|column1|column2|
+-------+-------+
|      A      B|
|      B      A|
+-------+-------+

2 个答案:

答案 0 :(得分:0)

我希望火花能足够聪明地解决不同文件中的无序列。

尝试一个接一个地加载它们,但是您始终会创建2个数据框并对其进行合并。

val dfReader = spark.read.format("csv").option("wholeFile", true).option("multiline",true).option("inferSchema", "true").option("header", true).option("escape","\"")

val df1 = dfReader.csv("faizan/sample/sample/sample1.csv")
val df2 = dfReader.csv("faizan/sample/sample/sample3.csv")

val df = df1.union(df2)

您可以尝试使用inferSchema为false的其他方法,以

创建自己的模式
StructType(Array(StructField("column1", StringType),StructField("column2", StringType)))

答案 1 :(得分:0)

也许下面的解决方案将帮助您解决问题

val df1 = spark.read.format.....(filepath1)
val df2 = spark.read.format.....(filepath2)

从sql.fucntions导入col方法

import org.apache.spark.sql.functions.col

将Seq(col_name1,col_name2)或Seq(String)转换为Seq(Column)

基本上df1.columns将返回Array [String]列名。

所以我们应该像下面那样将Array [String]转换为Array [Column]

 val cols = df1.columns.map(e=>col(e))

然后在dataframe2上进行union转换with selecting converted ordered cols of df1

  df1.union(df2.select(cols:_*))