我有两个数据框中的数据:
selectedPersonDF:
ID key
1
2
3
4
5
selectedDetailsDF:
first second third key
--------------------------
1 9 9 777
9 8 8 878
8 10 10 765
10 12 19 909
11 2 20 708
代码:
val personDF = spark.read.option("header", "true").option("inferSchema", "false").csv("person.csv")
val detailsDF = spark.read.option("header", "true").option("inferSchema", "false").csv("details.csv")
val selectedPersonDF=personDF.select((col("ID"),col("key"))).show()
val selectedDetailsDF=detailsDF.select(col("first"),col("second"),col("third"),col("key")).show()
我必须将selectedPersonDF id列与selectedDetailsDF匹配所有列(First,Second,Third)如果任何列数据与person id匹配,那么我们必须从selectedDetailsDF获取键值并且必须在selectedPersonDF键中更新柱。
预期输出(在selectedPersonDF中):
ID key
1 777
2 708
3
4
5
并且从人员中移除第一行后,因为它与detailsdf相匹配,所以剩余数据应该存储在另一个df中。
答案 0 :(得分:1)
您可以使用join
并使用||
条件检查和left join
作为
val finalDF = selectedPersonDF.join(selectedDetailsDF.withColumnRenamed("key", "key2"), $"ID" === $"first" || $"ID" === $"second" || $"ID" === $"third", "left")
.select($"ID", $"key2".as("key"))
.show(false)
所以finalDF
应该给你
+---+----+
|ID |key |
+---+----+
|1 |777 |
|2 |708 |
|3 |null|
|4 |null|
|5 |null|
+---+----+
我们可以在上面的数据框(.na.fill("")
列必须为key
)上致电StringType()
以获取
+---+---+
|ID |key|
+---+---+
|1 |777|
|2 |708|
|3 | |
|4 | |
|5 | |
+---+---+
之后,您可以使用filter
使用key
列将数据框分隔为匹配和非匹配 值和 null 分别为
val notMatchingDF = finalDF.filter($"key" === "")
val matchingDF = finalDF.except(notMatchingDF)
更新了如果selectedDetailsDF的列名称未知,除了键列
如果第二个数据框的列名称 未知,那么您必须形成未知的array
列列为
val columnsToCheck = selectedDetailsDF.columns.toSet - "key" toList
import org.apache.spark.sql.functions._
val tempSelectedDetailsDF = selectedDetailsDF.select(array(columnsToCheck.map(col): _*).as("array"), col("key").as("key2"))
现在tempSelectedDetailsDF
数据框有两列:所有未知列的组合列为array
列,键列重命名为key2
。
之后,您需要udf
函数来加入
val arrayContains = udf((array: collection.mutable.WrappedArray[String], value: String) => array.contains(value))
然后使用对定义的join
函数的调用udf
数据帧
val finalDF = selectedPersonDF.join(tempSelectedDetailsDF, arrayContains($"array", $"ID"), "left")
.select($"ID", $"key2".as("key"))
.na.fill("")
上面已经定义了其余的过程。
我希望答案有用且可以理解。