如何合并具有不同标题(名称和计数)的csv数据集?

时间:2018-12-12 15:07:04

标签: apache-spark pyspark apache-spark-sql

我有一个或多个要在pyspark中合并的csv文件:

文件1:

c1,c2,c3
1,3,4

文件2:

c4,c5,c6
4,5,6

文件3

c1,c2
7,8

我需要合并文件,以便结果为:

c1,c2,c3,c4,c5,c6
1,2,3,null,null,null
null,null,null,4,5,6
7,8,null,null,null,null

我尝试过:

  1. 使用加载方法从文件夹加载所有文件:

    spark.read.format("csv").option("header","true")

  2. 使用merge合并文件。

两者都只使用了一种文件架构

c1,c2,c3
1,3,4
4,5,6
7,8

1 个答案:

答案 0 :(得分:1)

读取所有文件-f1,f2,f3并合并列名称。然后,对于每个文件,找到补码列并使用lit(null)生成新列。最后,通过按顺序选择列名称来合并所有df。这是Scala解决方案。

val f1 = spark.read.format("csv").option("inferSchema","true").option("header","true").load("in/f1.csv")
val f2 = spark.read.format("csv").option("inferSchema","true").option("header","true").load("in/f2.csv")
val f3 = spark.read.format("csv").option("inferSchema","true").option("header","true").load("in/f3.csv")

val fall = f1.columns.union(f2.columns).union(f3.columns).distinct

val f1c = fall.diff(f1.columns)
val f1a = f1c.foldLeft(f1)( (acc,r) => acc.withColumn(r,lit(null)) )

val f2c = fall.diff(f2.columns)
val f2a = f2c.foldLeft(f2)( (acc,r) => acc.withColumn(r,lit(null)) )

val f3c = fall.diff(f3.columns)
val f3a = f3c.foldLeft(f3)( (acc,r) => acc.withColumn(r,lit(null)) )

val result = f1a.select(fall.head,fall.tail:_*).union(f2a.select(fall.head,fall.tail:_*)).union(f3a.select(fall.head,fall.tail:_*))
result.printSchema
result.show(false)

结果:

root
 |-- c1: integer (nullable = true)
 |-- c2: integer (nullable = true)
 |-- c3: integer (nullable = true)
 |-- c4: integer (nullable = true)
 |-- c5: integer (nullable = true)
 |-- c6: integer (nullable = true)

+----+----+----+----+----+----+
|c1  |c2  |c3  |c4  |c5  |c6  |
+----+----+----+----+----+----+
|1   |3   |4   |null|null|null|
|null|null|null|4   |5   |6   |
|7   |8   |null|null|null|null|
+----+----+----+----+----+----+