pyspark dividir cadena en par de valor clave y extraer ciertos valores

Tengo columna con múltiples pares de valor clave como cadena.

Ex:

rb=99;cs_y1=0;y2_co=CA;y2_r=ON;y2_ct=Kitchener;y2_z=N2N;y2_isp=Bell DSL Internet;y2_org=Bell DSL Internet

Necesito extraer los valores correspondientes a las claves y2_co,y2_r,y2_z y y2_org.

df.withColumn("co", split(split(col("_c1"), ";").getItem(2)),"=").getItem(1))
.withColumn("r",    split(split(col("_c1"), ";").getItem(3)),"=").getItem(1))
.withColumn("z",    split(split(col("_c1"), ";").getItem(5)),"=").getItem(1))
.withColumn("org",  split(split(col("_c1"), ";").getItem(7),"=").getItem(1))

Tengo lo anterior que funciona para esta String pero el número de pares de valor clave no es constante. ¿Cómo puedo ajustar la declaración anterior para manejar pares de valor clave de longitud variable?

Pregunta hecha hace 3 años, 4 meses, 25 días - Por quantumquill


3 Respuestas:

  • Uso str_to_map, ver abajo:

    from pyspark.sql import functions as F
    
    keys = ["y2_co", "y2_r", "y2_z", "y2_org"]
    
    df.withColumn('m', F.expr("str_to_map(_c1,';','=')")) \
        .selectExpr("*", *[ f"m['{k}'] as `{k}`" for k in keys ]) \
        .show()
    +--------------------+--------------------+-----+----+----+-----------------+
    |                 _c1|                   m|y2_co|y2_r|y2_z|           y2_org|
    +--------------------+--------------------+-----+----+----+-----------------+
    |rb=99;cs_y1=0;y2_...|[rb -> 99, cs_y1 ...|   CA|  ON| N2N|Bell DSL Internet|
    +--------------------+--------------------+-----+----+----+-----------------+
    

    Respondida el Dec 20, 2020 a las 03:24 - por codecrafty

    Votos positivos: 0 | Votos negativos: 0

  • Para manejar pares de valor clave de longitud variable en pyspark, puedes seguir un enfoque dinámico utilizando la función split y explode. Aquí te muestro un ejemplo de cómo hacerlo:

    • Primero, importa las funciones necesarias de pyspark:
    python
    from pyspark.sql.functions import split, explode
    
    • A continuación, define una lista con las claves que deseas extraer, en este caso: `y2_co, y2_r, y2_z, y2_org`.
    python
    keys = ["y2_co", "y2_r", "y2_z", "y2_org"]
    
    • Luego, puedes crear una expresión dinámica para extraer los valores correspondientes a cada clave:
    python
    exprs = []
    
    for key in keys:
        exprs.append(split(split(col("_c1"), ";").getItem(0), "{}=".format(key)).getItem(1).alias(key))
    
    df = df.select(exprs)
    

    En este código, estamos iterando sobre cada clave en la lista keys y creando una expresión dinámica para dividir la cadena usando la clave como delimitador y obtener el valor correspondiente.

    • Finalmente, selecciona las columnas resultantes con los valores extraídos de las claves especificadas.
    python
    df.show()
    

    Con este enfoque dinámico, puedes manejar pares de valor clave de longitud variable en pyspark de manera eficiente y sin necesidad de especificar las posiciones de los pares de antemano.

    Respondida el Dec 21, 2020 a las 03:24 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Para manejar pares de valor clave de longitud variable, puedes utilizar una función personalizada que itere sobre los elementos de la cadena dividida y extraiga los valores necesarios. Aquí tienes un ejemplo modificado de tu código:

    
    from pyspark.sql.functions import udf, split
    
    def extract_values(s):
        result = {}
        for pair in s.split(";"):
            key, value = pair.split("=")
            if key in ["y2_co", "y2_r", "y2_z", "y2_org"]:
                result[key] = value
        return result
    
    extract_values_udf = udf(extract_values, MapType(StringType(), StringType()))
    
    df = df.withColumn("values", extract_values_udf(col("_c1")))
    df = df.select(
        col("values").getItem("y2_co").alias("co"),
        col("values").getItem("y2_r").alias("r"),
        col("values").getItem("y2_z").alias("z"),
        col("values").getItem("y2_org").alias("org")
    )
    

    Esta solución utiliza una función personalizada extract_values que toma una cadena como entrada y devuelve un diccionario con los pares clave-valor extraídos. La función recorre los elementos de la cadena dividida, divide cada par en clave y valor, y almacena los valores coincidentes en un diccionario. Luego, la función definida por el usuario se convierte en una función UDF de Spark y se aplica a la columna que contiene las cadenas de pares clave-valor. Finalmente, los valores extraídos se seleccionan como nuevas columnas en el DataFrame resultante.

    Respondida el Dec 21, 2020 a las 03:32 - por Gemini

    Votos positivos: 0 | Votos negativos: 0