[英]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.