【问题标题】:replace key value from dictionary替换字典中的键值
【发布时间】:2022-01-13 13:51:58
【问题描述】:

下面是我的 DF:

deviceDict = {'TABLET' : 'MOBILE', 'PHONE':'MOBILE', 'PC':'Desktop', 'CEDEX' : '', 'ST' : 'SAINT', 'AV' : 'AVENUE', 'BD': 'BOULEVARD'}
df = spark.createDataFrame([('TABLET', 'DAF ST PAQ BD'), ('PHONE', 'AVOTHA'),  ('PC', 'STPA CEDEX'), ('OTHER', 'AV DAF'), (None, None)], ["device_type", 'City'])
df.show()

输出:

+-----------+-------------+
|device_type|         City|
+-----------+-------------+
|     TABLET|DAF ST PAQ BD|
|      PHONE|       AVOTHA|
|         PC|   STPA CEDEX|
|      OTHER|       AV DAF|
|       null|         null|
+-----------+-------------+

目的是替换键/值,解决方案来自Pyspark: Replacing value in a column by searching a dictionary

tests = df.na.replace(deviceDict, 1)

结果:

+-----------+-------------+
|device_type|         City|
+-----------+-------------+
|     MOBILE|DAF ST PAQ BD|
|     MOBILE|       AVOTHA|
|    Desktop|   STPA CEDEX|
|      OTHER|       AV DAF|
|       null|         null|
+-----------+-------------+

它适用于 device_type,但我无法更改 city(即使使用子集)

预期输出:

+-----------+------------------------+
|device_type|                    City|
+-----------+------------------------+
|     MOBILE| DAF SAINT PAQ BOULEVARD|
|     MOBILE|                  AVOTHA|
|    Desktop|                    STPA|
|      OTHER|              AVENUE DAF|
|       null|                    null|
+-----------+------------------------+

【问题讨论】:

    标签: python dataframe apache-spark pyspark apache-spark-sql


    【解决方案1】:

    City 列不会发生替换,因为您尝试在列值中进行一些部分替换。而函数DataFrame.replace 使用整个值作为映射。

    要实现您对列 City 的要求,您可以使用多个嵌套的 regexp_replace 表达式,您可以使用 Python functools.reduce 动态生成这些表达式,例如:

    from functools import reduce
    import pyspark.sql.functions as F
    
    m = list(deviceDict.items())
    
    df1 = df.na.replace(deviceDict, 1).withColumn(
        "City",
        reduce(
            lambda acc, x: F.regexp_replace(acc, rf"\b{x[0]}\b", x[1]),
            m[1:],
            F.regexp_replace(F.col("City"), rf"\b{m[0][0]}\b", m[0][1]),
        )
    )
    
    df1.show(truncate=False)
    #+-----------+-----------------------+
    #|device_type|City                   |
    #+-----------+-----------------------+
    #|MOBILE     |DAF SAINT PAQ BOULEVARD|
    #|MOBILE     |AVOTHA                 |
    #|Desktop    |STPA                   |
    #|OTHER      |AVENUE DAF             |
    #|null       |null                   |
    #+-----------+-----------------------+
    

    【讨论】:

      最近更新 更多