Spark especifica múltiples condiciones de columna para unirse al marco de datos
Cómo dar más condiciones de columna al unir dos marcos de datos. Por ejemplo quiero ejecutar lo siguiente:
val Lead_all = Leads.join(Utm_Master,
Leaddetails.columns("LeadSource","Utm_Source","Utm_Medium","Utm_Campaign") ==
Utm_Master.columns("LeadSource","Utm_Source","Utm_Medium","Utm_Campaign"),
"left")
Quiero unirme solo cuando estas columnas coincidan. Pero la sintaxis anterior no es válida ya que cols solo toma una cadena. Entonces, ¿cómo consigo lo que quiero?
Hay una unión API de columna/expresión de Spark para tal caso:
Leaddetails.join(
Utm_Master,
Leaddetails("LeadSource") <=> Utm_Master("LeadSource")
&& Leaddetails("Utm_Source") <=> Utm_Master("Utm_Source")
&& Leaddetails("Utm_Medium") <=> Utm_Master("Utm_Medium")
&& Leaddetails("Utm_Campaign") <=> Utm_Master("Utm_Campaign"),
"left"
)
El <=>
operador en el ejemplo significa " Prueba de igualdad que es segura para valores nulos ".
La principal diferencia con la prueba de igualdad simple ( ===
) es que la primera es segura de usar en caso de que una de las columnas tenga valores nulos.
A partir de la versión 1.5.0 de Spark (que actualmente no está publicada), puede unirse en varias columnas de DataFrame. Consulte SPARK-7990: Agregar métodos para facilitar la unión equivalente en múltiples claves de unión .
Pitón
Leads.join(
Utm_Master,
["LeadSource","Utm_Source","Utm_Medium","Utm_Campaign"],
"left_outer"
)
escala
La pregunta pedía una respuesta de Scala, pero yo no uso Scala. Aquí está mi mejor suposición....
Leads.join(
Utm_Master,
Seq("LeadSource","Utm_Source","Utm_Medium","Utm_Campaign"),
"left_outer"
)
Una cosa que puedes hacer es usar SQL sin formato:
case class Bar(x1: Int, y1: Int, z1: Int, v1: String)
case class Foo(x2: Int, y2: Int, z2: Int, v2: String)
val bar = sqlContext.createDataFrame(sc.parallelize(
Bar(1, 1, 2, "bar") :: Bar(2, 3, 2, "bar") ::
Bar(3, 1, 2, "bar") :: Nil))
val foo = sqlContext.createDataFrame(sc.parallelize(
Foo(1, 1, 2, "foo") :: Foo(2, 1, 2, "foo") ::
Foo(3, 1, 2, "foo") :: Foo(4, 4, 4, "foo") :: Nil))
foo.registerTempTable("foo")
bar.registerTempTable("bar")
sqlContext.sql(
"SELECT * FROM foo LEFT JOIN bar ON x1 = x2 AND y1 = y2 AND z1 = z2")
Las ===
opciones me dan columnas duplicadas. Entonces lo uso Seq
en su lugar.
val Lead_all = Leads.join(Utm_Master,
Seq("Utm_Source","Utm_Medium","Utm_Campaign"),"left")
Por supuesto, esto sólo funciona cuando los nombres de las columnas que se unen son los mismos.