You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySpark DataFrame中如何展开ArrayType类型的Items与Value1列

问题描述

我有如下PySpark DataFrame,需要展开其中的Items和Value1列。

当前使用的代码:

df_ob_exploded = df.withColumn('op_it.objects',
                    F.explode(F.array(*[F.array(F.col('op_it.objects')[i]['Items'][j].Name,
                                F.array(*[F.col('op_it.Objects')[i]['Items'[j]['Items'][k].Name for k in range(9)]).cast('string'),
                                F.array(*[F.from_json(F.col('op_it.objects')[i]['Items'][k].Selected, sc).getItem('Value') for k in range(9)]).cast('string'),
                                F.from_json(F.col('op_it.objects')[i]['Items'][j].Selected,sc).getItem('Value'))for i in range(9) for j in range(9)]))).dropDuplicates()
                                
df_obj_json = df_ob_exploded.select('ID', F.col('op_it.object'[0].alias('Name'), F.col('op_it.objects')[1].alias('Items'),
                                          F.col('op_it.object'[2].alias('Value1'), F.col('op_it.objects')[1].alias('Value'))\
                                          .na.drop(how='all', subset=['Name','Items','Value1','Value'])

但无法成功展开Items和Value1列,我的DataFrame示例如下:

ID      Name        Items                   Value1      Value
1       Contact     [platform,chat, , ,]    [,,,,,]     null
1       action      [,,,,,,]                [,,,,,]     windows
1       cycle       [,,,,,,]                [,,,,,]     article
解决方案

要同时展开Items和Value1数组列且保持元素对应关系,不需要复杂的硬编码遍历,用arrays_zip打包数组后再explode即可,步骤如下:

1. 打包并展开数组

用arrays_zip将Items和Value1中同位置的元素配对成结构体数组,再通过explode拆分成单独行:

from pyspark.sql import functions as F

# 打包数组并展开
df_exploded = df.withColumn(
    "zipped",
    F.explode(F.arrays_zip("Items", "Value1"))
).select(
    "ID", "Name", "Value",
    F.col("zipped.Items").alias("Item"),
    F.col("zipped.Value1").alias("Value1_element")
)

2. 过滤无效空值

原数组包含大量空字符串,过滤掉这些无效行:

df_result = df_exploded.filter(
    (F.col("Item") != "") & (F.col("Value1_element") != "")
)

完整测试示例

基于你提供的测试数据运行完整代码:

# 创建测试DataFrame
data = [
    (1, "Contact", ["platform", "chat", "", "", ""], ["", "", "", "", ""], None),
    (1, "action", ["", "", "", "", "", ""], ["", "", "", "", "", ""], "windows"),
    (1, "cycle", ["", "", "", "", "", ""], ["", "", "", "", "", ""], "article")
]
df = spark.createDataFrame(data, ["ID", "Name", "Items", "Value1", "Value"])

# 执行展开和过滤
df_exploded = df.withColumn(
    "zipped",
    F.explode(F.arrays_zip("Items", "Value1"))
).select(
    "ID", "Name", "Value",
    F.col("zipped.Items").alias("Item"),
    F.col("zipped.Value1").alias("Value1_element")
)

df_result = df_exploded.filter(
    (F.col("Item") != "") & (F.col("Value1_element") != "")
)

df_result.show()

关键说明

  • arrays_zip确保展开后Item和Value1_element始终是原数组中同一位置的对应元素,避免错位
  • 无需硬编码数组长度,适配任意长度的数组列
  • 过滤条件可根据实际需求调整,比如只保留非空的Item或Value1_element

内容的提问来源于stack exchange,提问作者user175025

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 12:07:37