如何在PySpark中实现宽表与明细数据的匹配关联?
解决PySpark关联宽表与明细表匹配取值问题
核心思路
先把宽表df转换成和df2结构匹配的长表,再通过共同字段关联获取对应数值。
步骤1:将宽表转为长表
宽表的列名遵循COL_{FRUIT}_{TYPE}格式,我们用stack函数把多列拆成多行,同时解析出FRUIT和TYPE:
from pyspark.sql import functions as F # 筛选出所有非STORE的数值列 value_cols = [col for col in df.columns if col != "STORE"] # 用stack转换宽表,生成包含列名和对应值的临时列,再拆分出FRUIT和TYPE df_long = df.select( "STORE", F.expr(f"stack({len(value_cols)}, {','.join([f'{repr(col)}, {col}' for col in value_cols])}) as (col_name, COL_VALUE)") ).withColumn( "FRUIT", F.split(F.col("col_name"), "_")[1] ).withColumn( "TYPE", F.split(F.col("col_name"), "_")[2] ).drop("col_name")
如果列名格式有变动(比如分隔符不同),可以改用正则提取更稳妥:
df_long = df_long.withColumn( "FRUIT", F.regexp_extract(F.col("col_name"), r"COL_(\w+)_(\w+)", 1) ).withColumn( "TYPE", F.regexp_extract(F.col("col_name"), r"COL_(\w+)_(\w+)", 2) )
步骤2:关联长表与明细表
现在df_long的结构是STORE、COL_VALUE、FRUIT、TYPE,和df2的匹配字段完全对应,直接关联即可:
# 左关联保留df2所有行,内关联只保留匹配行,按需选择 df2_with_value = df2.join( df_long, on=["STORE", "FRUIT", "TYPE"], how="left" )
关联后df2_with_value就新增了COL_VALUE列,对应df中匹配组合的数值。
内容的提问来源于stack exchange,提问作者Scope
相关产品推荐
相关产品推荐

