I have 2 DataFrame
s:
I need union like this:
The unionAll
function doesn't work because the number and the name of columns are different.
How can I do this?
Here In first dataframe (dataframe1) , the columns ['ID', 'NAME', 'Address'] and second dataframe (dataframe2 ) columns are ['ID','Age']. Now we have to add the Age column to the first dataframe and NAME and Address in the second dataframe, we can do this by using lit() function. This function is available in pyspark.
The PySpark unionByName() function is also used to combine two or more data frames but it might be used to combine dataframes having different schema. This is because it combines data frames by the name of the column and not the order of the columns. Where, data_frame1 and data_frame2 are the dataframes.
Different column names are specified for merges in Pandas using the “left_on” and “right_on” parameters, instead of using only the “on” parameter. Merging dataframes with different names for the joining variable is achieved using the left_on and right_on arguments to the pandas merge function.
In Scala you just have to append all missing columns as nulls
.
import org.apache.spark.sql.functions._ // let df1 and df2 the Dataframes to merge val df1 = sc.parallelize(List( (50, 2), (34, 4) )).toDF("age", "children") val df2 = sc.parallelize(List( (26, true, 60000.00), (32, false, 35000.00) )).toDF("age", "education", "income") val cols1 = df1.columns.toSet val cols2 = df2.columns.toSet val total = cols1 ++ cols2 // union def expr(myCols: Set[String], allCols: Set[String]) = { allCols.toList.map(x => x match { case x if myCols.contains(x) => col(x) case _ => lit(null).as(x) }) } df1.select(expr(cols1, total):_*).unionAll(df2.select(expr(cols2, total):_*)).show() +---+--------+---------+-------+ |age|children|education| income| +---+--------+---------+-------+ | 50| 2| null| null| | 34| 4| null| null| | 26| null| true|60000.0| | 32| null| false|35000.0| +---+--------+---------+-------+
Both temporal DataFrames
will have the same order of columns, because we are mapping through total
in both cases.
df1.select(expr(cols1, total):_*).show() df2.select(expr(cols2, total):_*).show() +---+--------+---------+------+ |age|children|education|income| +---+--------+---------+------+ | 50| 2| null| null| | 34| 4| null| null| +---+--------+---------+------+ +---+--------+---------+-------+ |age|children|education| income| +---+--------+---------+-------+ | 26| null| true|60000.0| | 32| null| false|35000.0| +---+--------+---------+-------+
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With