es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Modificando UDF en Spark para crear una columna adicional de clave

Tengo un dataframe que consiste en filas de datos y una columna de XML que necesita ser analizada. Soy capaz de analizar ese XML con el siguiente código de esta solución de stack overflow:

import xml.etree.ElementTree as ET
import pyspark.sql.functions as F

@F.udf('array<><id:string, age:string,="" sex:string="">>')
def parse_xml(s):
    root = ET.fromstring(s)
    return list(map(lambda x: x.attrib, root.findall('visitor')))

df2 = df.select(
    F.explode(parse_xml('visitors')).alias('visitors')
).select('visitors.*')

df2.show()

Esta función crea un nuevo dataframe con los datos analizados del XML.

En cambio, ¿cómo puedo modificar esta función para incluir una columna del dataframe original de modo que pueda ser unida posteriormente?

Por ejemplo, si el dataframe original se ve así:

+----+---+----------------------+
|id  |a  |xml                   |
+----+---+----------------------+
|1234|.  |<row1, row2="">          |
|2345|.  |<row3, row4="">, <row5>  |
|3456|.  |<row6>                |
+----+---+----------------------+

¿Cómo puedo incluir el ID en cada una de las filas del nuevo dataframe creado?</row3,></row1,></id:string,>

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para incluir la columna ID del dataframe original en el nuevo dataframe de datos XML analizados, puedes modificar la UDF parse_xml de la siguiente manera:

    @F.udf('struct<id:string,></id:string,><><id:string, age:string,="" sex:string="">>>')
    def parse_xml_with_id(id, s):
        root = ET.fromstring(s)
        visitors = list(map(lambda x: x.attrib, root.findall('visitor')))
        return (id, visitors)
    

    Aquí, la UDF parse_xml_with_id toma dos argumentos: id y s. El argumento id representa la columna ID del dataframe original y se incluye en la estructura devuelta junto con los datos XML analizados. La UDF modificada devuelve una estructura con dos campos: id y visitor. El campo visitor es un arreglo de estructuras que representa los datos XML analizados.

    Para utilizar la UDF en la transformación del dataframe, puedes pasar tanto las columnas id como xml a la UDF de la siguiente manera:

    df2 = df.select(
        F.col('id'),
        F.explode(parse_xml_with_id('id', 'xml')).alias('parsed_xml')
    ).select(
        F.col('id'),
        F.col('parsed_xml.id').alias('visitor_id'),
        F.explode('parsed_xml.visitor').alias('visitor_data')
    ).select(
        'id',
        'visitor_id',
        'visitor_data.id',
        'visitor_data.age',
        'visitor_data.sex'
    )
    

    Aquí, primero seleccionamos las columnas id y xml del dataframe original. Luego, pasamos estas columnas a la UDF parse_xml_with_id para crear una nueva columna llamada parsed_xml, que es una estructura que contiene el ID y los datos XML analizados. Luego, explotamos la columna parsed_xml para crear un nuevo dataframe con las columnas id, visitor_id y visitor_data, donde visitor_id es el ID del dataframe original, y visitor_data es una estructura que representa los datos XML analizados. Finalmente, seleccionamos las columnas necesarias de este dataframe para crear la salida deseada.</id:string,>

Comments are closed.