[英]Merge two spark dataframes with different columns to get all columns
假設我有 2 個 spark 數據幀:
Location Date Date_part Sector units
USA 7/1/2021 7/1/2021 Cars 200
IND 7/1/2021 7/1/2021 Scooters 180
COL 7/1/2021 7/1/2021 Trucks 100
Location Date Brands units values
UK null brand1 400 120
AUS null brand2 450 230
CAN null brand3 150 34
我需要我的結果 dataframe 作為
Location Date Date_part Sector Brands units values
USA 7/1/2021 7/1/2021 Cars 200
IND 7/1/2021 7/1/2021 Scooters 180
COL 7/1/2021 7/1/2021 Trucks 100
UK null 7/1/2021 brand1 400 120
AUS null 7/1/2021 brand2 450 230
CAN null 7/1/2021 brand3 150 34
所以我想要的 df 應該包含兩個數據框中的所有列我還需要所有行中的 Date_part 這是我嘗試過的:
df_result= df1.union(df_2)
但我得到這個作為我的結果。 正在交換值,第二個 dataframe 中的一列丟失。
Location Date Date_part Sector Brands units
USA 7/1/2021 7/1/2021 Cars 200
IND 7/1/2021 7/1/2021 Scooters 180
COL 7/1/2021 7/1/2021 Trucks 100
UK null brand1 400 120
AUS null brand2 450 230
CAN null brand3 150 34
任何建議請
union
:這個 function 按 position (不是按名稱)解析列
這就是為什么您認為“正在交換值並且缺少第二個 dataframe 中的一列”的原因。
您應該使用unionByName
,但此函數要求兩個 dataframe 具有相同的結構。
我為您提供了這個簡單的代碼來協調您的數據幀的結構,然后執行 union(ByName)。
from pyspark.sql import DataFrame
from pyspark.sql import functions as F
def add_missing_columns(df: DataFrame, ref_df: DataFrame) -> DataFrame:
"""Add missing columns from ref_df to df
Args:
df (DataFrame): dataframe with missing columns
ref_df (DataFrame): referential dataframe
Returns:
DataFrame: df with additionnal columns from ref_df
"""
for col in ref_df.schema:
if col.name not in df.columns:
df = df.withColumn(col.name, F.lit(None).cast(col.dataType))
return df
df1 = add_missing_columns(df1, df2)
df2 = add_missing_columns(df2, df1)
df_result = df1.unionByName(df2)
這是@Steven 回復的附加內容(因為我沒有足夠的聲譽直接在他的帖子下發表評論):
除了@minus34 為 Spark 3.1+ 及更高版本建議的可選參數之外,@Steven 的解決方案( add_missing_columns
)是一個完美的解決方法。 但是,調用withColumn
會在內部引入一個投影,當在大循環中調用它時會生成可能導致性能問題的大計划,最終會導致大型數據集出現StackOverflowError
。
@Steven 代碼的可擴展修改可以是:
from pyspark.sql import DataFrame
from pyspark.sql import functions as F
from pyspark.sql import types as T
def add_missing_columns(df: DataFrame, ref_df: DataFrame) -> DataFrame:
"""Add missing columns from ref_df to df
Args:
df (DataFrame): dataframe with missing columns
ref_df (DataFrame): referential dataframe
Returns:
DataFrame: df with additionnal columns from ref_df
"""
missing_col = []
for col in ref_df.schema:
if col.name not in df.columns:
missing_col.append(col.name)
df = df.select(['*'] + [F.lit(None).cast(T.NullType()).alias(c) for c in missing_col])
return df
因此select
是一個可能的替代方案,將值None
的新空列轉換為NullType()
可能會更好,因為您不需要指定特定的數據類型來將此空列轉換為! ( NullType()
在union
和unionByName
中與 spark 中的任何數據類型都能正常工作)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.