El uso de Chispa 1.6, tengo un Spark DataFrame column (denominado digamos col1) con los valores de a, B, C, DS, DNS, E, F, G y H, y quiero crear una nueva columna (decir col2) con los valores de la dict aquí abajo, ¿cómo puedo hacer de este mapa? (para f.yo. ‘A’ debe ser asignado a ‘S’, etc..)

dict = {'A': 'S', 'B': 'S', 'C': 'S', 'DS': 'S', 'DNS': 'S', 'E': 'NS', 'F': 'NS', 'G': 'NS', 'H': 'NS'}
InformationsquelleAutor ad_s | 2017-03-23

2 Comentarios

  1. 26

    Solución ineficaz con UDF (versión independiente):

    from pyspark.sql.types import StringType
    from pyspark.sql.functions import udf
    
    def translate(mapping):
        def translate_(col):
            return mapping.get(col)
        return udf(translate_, StringType())
    
    df = sc.parallelize([('DS', ), ('G', ), ('INVALID', )]).toDF(['key'])
    mapping = {
        'A': 'S', 'B': 'S', 'C': 'S', 'DS': 'S', 'DNS': 'S', 
        'E': 'NS', 'F': 'NS', 'G': 'NS', 'H': 'NS'}
    
    df.withColumn("value", translate(mapping)("key"))

    con el resultado:

    +-------+-----+
    |    key|value|
    +-------+-----+
    |     DS|    S|
    |      G|   NS|
    |INVALID| null|
    +-------+-----+

    Mucho más eficiente (Spark 2.0+ solamente) es crear un MapType literal:

    from pyspark.sql.functions import col, create_map, lit
    from itertools import chain
    
    mapping_expr = create_map([lit(x) for x in chain(*mapping.items())])
    
    df.withColumn("value", mapping_expr.getItem(col("key")))

    con el mismo resultado:

    +-------+-----+
    |    key|value|
    +-------+-----+
    |     DS|    S|
    |      G|   NS|
    |INVALID| null|
    +-------+-----+

    pero más eficiente plan de ejecución:

    == Physical Plan ==
    *Project [key#15, keys: [B,DNS,DS,F,E,H,C,G,A], values: [S,S,S,NS,NS,NS,S,NS,S][key#15] AS value#53]
    +- Scan ExistingRDD[key#15]

    comparación con UDF versión:

    == Physical Plan ==
    *Project [key#15, pythonUDF0#61 AS value#57]
    +- BatchEvalPython [translate_(key#15)], [key#15, pythonUDF0#61]
       +- Scan ExistingRDD[key#15]

Dejar respuesta

Please enter your comment!
Please enter your name here