繁体   English   中英

合并两个具有不同列的 spark 数据框以获取所有列

[英]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()unionunionByName中与 spark 中的任何数据类型都能正常工作)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM