开发者社区> 问答> 正文

pyspark将行转换为带有空值的json

目标: 对于具有架构的数据框

id:string
Cold:string
Medium:string
Hot:string
IsNull:string
annual_sales_c:string
average_check_c:string
credit_rating_c:string
cuisine_c:string
dayparts_c:string
location_name_c:string
market_category_c:string
market_segment_list_c:string
menu_items_c:string
msa_name_c:string
name:string
number_of_employees_c:string
number_of_rooms_c:string
Months In Role:integer
Tenured Status:string
IsCustomer:integer
units_c:string
years_in_business_c:string
medium_interactions_c:string
hot_interactions_c:string
cold_interactions_c:string
is_null_interactions_c:string
我想添加一个新列,它是列的所有键和值的JSON字符串。我在这篇文章PySpark中使用了这种方法- 逐行转换为JSON和相关问题。我的代码

df = df.withColumn("JSON",func.to_json(func.struct([df[x] for x in small_df.columns])))
我有一个问题:

问题: 当任何行的列具有空值(并且我的数据有许多...)时,Json字符串不包含该键。即如果27列中只有9列具有值,那么JSON字符串只有9个键...我想要做的是维护所有键但是对于空值只传递一个空字符串“”

展开
收起
社区小助手 2018-12-05 13:21:53 1913 0
1 条回答
写回答
取消 提交回答
  • 社区小助手是spark中国社区的管理员,我会定期更新直播回顾等资料和文章干货,还整合了大家在钉群提出的有关spark的问题及回答。

    请考虑以下示例DataFrame:

    data = [

    ('one', 1, 10),
    (None, 2, 20),
    ('three', None, 30),
    (None, None, 40)

    ]

    sdf = spark.createDataFrame(data, ["A", "B", "C"])
    sdf.printSchema()

    root

    |-- A: string (nullable = true)

    |-- B: long (nullable = true)

    |-- C: long (nullable = true)

    使用when来实现IF-THEN-ELSE逻辑。如果列不为null,请使用该列。否则返回一个空字符串。

    from pyspark.sql.functions import col, to_json, struct, when, lit
    sdf = sdf.withColumn(

    "JSON",
    to_json(
        struct(
           [
                when(
                    col(x).isNotNull(),
                    col(x)
                ).otherwise(lit("")).alias(x) 
                for x in sdf.columns
            ]
        )
    )

    )
    sdf.show()

    +-----+----+---+-----------------------------+

    |A |B |C |JSON |

    +-----+----+---+-----------------------------+

    |one |1 |10 |{"A":"one","B":"1","C":"10"} |

    |null |2 |20 |{"A":"","B":"2","C":"20"} |

    |three|null|30 |{"A":"three","B":"","C":"30"}|

    |null |null|40 |{"A":"","B":"","C":"40"} |

    +-----+----+---+-----------------------------+

    另一种选择是使用pyspark.sql.functions.coalesce而不是when:

    from pyspark.sql.functions import coalesce

    sdf.withColumn(

    "JSON",
    to_json(
        struct(
           [coalesce(col(x), lit("")).alias(x) for x in sdf.columns]
        )
    )

    ).show(truncate=False)

    Same as above

    2019-07-17 23:18:20
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
File Format Benchmark - Avro, JSON, ORC, & Parquet 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载