Diez nuevas transformaciones visuales en AWS Glue Studio

Diez nuevas transformaciones visuales en AWS Glue Studio

Nodo de origen: 2641422

Estudio de pegamento de AWS es una interfaz gráfica que facilita la creación, ejecución y supervisión de trabajos de extracción, transformación y carga (ETL) en Pegamento AWS. Le permite componer visualmente flujos de trabajo de transformación de datos utilizando nodos que representan diferentes pasos de manejo de datos, que luego se convierten automáticamente en código para ejecutar.

Estudio de pegamento de AWS lanzado recientemente 10 transformaciones visuales más para permitir la creación de trabajos más avanzados de forma visual sin conocimientos de codificación. En esta publicación, discutimos casos de usos potenciales que reflejan las necesidades comunes de ETL.

Las nuevas transformaciones que se demostrarán en esta publicación son: Concatenar, Dividir cadena, Matriz a columnas, Agregar marca de tiempo actual, Pivotar filas a columnas, Despivotar columnas a filas, Buscar, Explotar matriz o mapa en columnas, Columna derivada y Procesamiento de autoequilibrio .

Resumen de la solución

En este caso de uso, tenemos algunos archivos JSON con operaciones de opciones sobre acciones. Queremos hacer algunas transformaciones antes de almacenar los datos para que sea más fácil de analizar, y también queremos producir un resumen del conjunto de datos por separado.

En este conjunto de datos, cada fila representa una operación de contratos de opciones. Las opciones son instrumentos financieros que otorgan el derecho, pero no la obligación, de comprar o vender acciones a un precio fijo (llamado  precio del ejercicio) antes de una fecha de vencimiento definida.

Datos de entrada

Los datos siguen el siguiente esquema:

  • Solicitar ID – Una identificación única
  • símbolo – Un código generalmente basado en unas pocas letras para identificar a la corporación que emite las acciones subyacentes
  • instrumento – El nombre que identifica la opción específica que se compra o vende
  • moneda – El código de moneda ISO en el que se expresa el precio
  • precio – El monto que se pagó por la compra de cada contrato de opción (en la mayoría de los intercambios, un contrato le permite comprar o vender 100 acciones)
  • Intercambio – El código del centro o recinto cambiario donde se negoció la opción
  • vendido – Una lista de la cantidad de contratos que se asignaron para completar la orden de venta cuando se trata de una operación de venta
  • compró – Una lista de la cantidad de contratos que se asignaron para completar la orden de compra cuando se trata de una operación de compra

La siguiente es una muestra de los datos sintéticos generados para esta publicación:

{"order_id": 1679931512485, "symbol": "AMZN", "instrument": "AMZN MAR 24 23 102 PUT", "currency": "usd", "price": 17.18, "exchange": "EDGX", "bought": [18, 38]}
{"order_id": 1679931512486, "symbol": "BMW.DE", "instrument": "BMW.DE MAR 24 23 96 PUT", "currency": "eur", "price": 2.98, "exchange": "XETR", "bought": [28]}
{"order_id": 1679931512487, "symbol": "BMW.DE", "instrument": "BMW.DE APR 28 23 101 CALL", "currency": "eur", "price": 14.71, "exchange": "XETR", "sold": [9, 59, 54]}
{"order_id": 1679931512489, "symbol": "JPM", "instrument": "JPM JUN 30 23 140 CALL", "currency": "usd", "price": 11.83, "exchange": "EDGX", "bought": [33, 42, 55, 67]}
{"order_id": 1679931512490, "symbol": "SIE.DE", "instrument": "SIE.DE MAR 24 23 149 CALL", "currency": "eur", "price": 13.68, "exchange": "XETR", "bought": [96, 89, 82]}
{"order_id": 1679931512491, "symbol": "NKE", "instrument": "NKE MAR 24 23 112 CALL", "currency": "usd", "price": 3.23, "exchange": "EDGX", "sold": [67]}
{"order_id": 1679931512492, "symbol": "AMZN", "instrument": "AMZN MAY 26 23 95 CALL", "currency": "usd", "price": 11.44, "exchange": "EDGX", "sold": [41, 62, 12]}
{"order_id": 1679931512493, "symbol": "JPM", "instrument": "JPM MAR 24 23 121 PUT", "currency": "usd", "price": 1.0, "exchange": "EDGX", "bought": [61, 34]}
{"order_id": 1679931512494, "symbol": "SAP.DE", "instrument": "SAP.DE MAR 24 23 132 CALL", "currency": "eur", "price": 15.9, "exchange": "XETR", "bought": [69, 33]}

Requisitos ETL

Estos datos tienen una serie de características únicas, como se encuentran a menudo en los sistemas más antiguos, que hacen que los datos sean más difíciles de usar.

Los siguientes son los requisitos de ETL:

  • El nombre del instrumento tiene información valiosa que está destinada a que los humanos la entiendan; queremos normalizarlo en columnas separadas para facilitar el análisis.
  • Los atributos bought y sold son mutuamente excluyentes; podemos consolidarlos en una sola columna con los números de contrato y tener otra columna que indique si los contratos fueron comprados o vendidos en este orden.
  • Queremos mantener la información sobre las asignaciones de contratos individuales, pero como filas individuales en lugar de obligar a los usuarios a tratar con una serie de números. Podríamos sumar los números, pero perderíamos información sobre cómo se ejecutó la orden (lo que indica la liquidez del mercado). En su lugar, elegimos desnormalizar la tabla para que cada fila tenga un solo número de contratos, dividiendo los pedidos con varios números en filas separadas. En un formato de columna comprimido, el tamaño adicional del conjunto de datos de esta repetición suele ser pequeño cuando se aplica la compresión, por lo que es aceptable hacer que el conjunto de datos sea más fácil de consultar.
  • Queremos generar una tabla resumen de volumen para cada tipo de opción (call y put) para cada acción. Esto proporciona una indicación del sentimiento del mercado para cada acción y el mercado en general (avaricia frente a miedo).
  • Para habilitar los resúmenes comerciales generales, queremos proporcionar para cada operación el total general y estandarizar la moneda a dólares estadounidenses, utilizando una referencia de conversión aproximada.
  • Queremos agregar la fecha en que se produjeron estas transformaciones. Esto podría ser útil, por ejemplo, para tener una referencia de cuándo se realizó la conversión de moneda.

Según esos requisitos, el trabajo producirá dos resultados:

  • Un archivo CSV con un resumen de la cantidad de contratos para cada símbolo y tipo
  • Una tabla de catálogo para llevar un histórico del pedido, después de hacer las transformaciones indicadas
    Esquema de datos

Requisitos previos

Necesitará su propio depósito S3 para seguir este caso de uso. Para crear un nuevo depósito, consulte Crear un cubo.

Generar datos sintéticos

Para seguir esta publicación (o experimentar con este tipo de datos por su cuenta), puede generar este conjunto de datos sintéticamente. El siguiente script de Python se puede ejecutar en un entorno de Python con Boto3 instalado y acceso a Servicio de almacenamiento simple de Amazon (Amazon S3).

Para generar los datos, complete los siguientes pasos:

  1. En AWS Glue Studio, cree un nuevo trabajo con la opción Editor de secuencias de comandos de shell de Python.
  2. Asigne un nombre al trabajo y en la Detalles del trabajo pestaña, seleccione una papel adecuado y un nombre para el script de Python.
  3. En Detalles del trabajo sección, ampliar Propiedades avanzadas Y desplácese hacia abajo hasta Parámetros de trabajo.
  4. Ingrese un parámetro llamado --bucket y asigne como valor el nombre del depósito que desea usar para almacenar los datos de muestra.
  5. Ingrese el siguiente script en el editor de shell de AWS Glue:
    import argparse
    import boto3
    from datetime import datetime
    import io
    import json
    import random
    import sys # Configuration
    parser = argparse.ArgumentParser()
    parser.add_argument('--bucket')
    args, ignore = parser.parse_known_args()
    if not args.bucket: raise Exception("This script requires an argument --bucket with the value specifying the S3 bucket where to store the files generated") data_bucket = args.bucket
    data_path = "transformsblog/inputdata"
    samples_per_file = 1000 # Create a single file with synthetic data samples
    s3 = boto3.client('s3')
    buff = io.BytesIO() sample_stocks = [("AMZN", 95, "usd"), ("NKE", 120, "usd"), ("JPM", 130, "usd"), ("KO", 130, "usd"), ("BMW.DE", 95, "eur"), ("SIE.DE", 140, "eur"), ("SAP.DE", 115, "eur")]
    option_type = ["PUT", "CALL"]
    operations = ["sold", "bought"]
    dates = ["MAR 24 23", "APR 28 23", "MAY 26 23", "JUN 30 23"]
    for i in range(samples_per_file): stock = random.choice(sample_stocks) symbol = stock[0] ref_price = stock[1] currency = stock[2] strike_price = round(ref_price * 0.9 + ref_price * random.uniform(0.01, 0.3)) sample = { "order_id": int(datetime.now().timestamp() * 1000) + i, "symbol": stock[0], "instrument":f"{symbol} {random.choice(dates)} {strike_price} {random.choice(option_type)}", "currency": currency, "price": round(random.uniform(0.5, 20.1), 2), "exchange": "EDGX" if currency == "usd" else "XETR" } sample[random.choice(operations)] = [random.randrange(1,100) for i in range(random.randrange(1,5))] buff.write(json.dumps(sample).encode()) buff.write("n".encode()) s3.put_object(Body=buff.getvalue(), Bucket=data_bucket, Key=f"{data_path}/{int(datetime.now().timestamp())}.json")

  6. Ejecute el trabajo y espere hasta que se muestre como completado con éxito en la pestaña Ejecuciones (debe tomar solo unos segundos).

Cada ejecución generará un archivo JSON con 1,000 filas bajo el depósito especificado y el prefijo transformsblog/inputdata/. Puede ejecutar el trabajo varias veces si desea probar con más archivos de entrada.
Cada línea de los datos sintéticos es una fila de datos que representa un objeto JSON como el siguiente:

{ "order_id":1681986991888, "symbol":"AMZN", "instrument":"AMZN APR 28 23 100 PUT", "currency":"usd", "price":2.89, "exchange":"EDGX", "sold":[88,49]
}

Cree el trabajo visual de AWS Glue

Para crear el trabajo visual de AWS Glue, complete los siguientes pasos:

  1. Vaya a AWS Glue Studio y cree un trabajo usando la opción Visual con un lienzo en blanco.
  2. Editar Untitled job para darle un nombre y asignar un rol adecuado para AWS Glue en Detalles del trabajo .
  3. Agregue una fuente de datos S3 (puede nombrarla JSON files source) e ingrese la URL de S3 en la que se almacenan los archivos (por ejemplo, s3://<your bucket name>/transformsblog/inputdata/), luego seleccione JSON como formato de datos.
  4. Seleccione Inferir esquema por lo que establece el esquema de salida en función de los datos.

Desde este nodo de origen, seguirás encadenando transformaciones. Al agregar cada transformación, asegúrese de que el nodo seleccionado sea el último agregado para que se asigne como principal, a menos que se indique lo contrario en las instrucciones.

Si no seleccionó el padre correcto, siempre puede editar el padre seleccionándolo y eligiendo otro padre en el panel de configuración.

Configuración principal del nodo

Para cada nodo agregado, le dará un nombre específico (para que el propósito del nodo se muestre en el gráfico) y una configuración en el Transformar .

Cada vez que una transformación cambia el esquema (por ejemplo, agrega una nueva columna), el esquema de salida debe actualizarse para que sea visible para las transformaciones posteriores. Puede editar manualmente el esquema de salida, pero es más práctico y seguro hacerlo usando la vista previa de datos.
Además, de esa manera puede verificar que la transformación esté funcionando como se esperaba. Para ello, abra el Vista previa de datos pestaña con la transformación seleccionada e iniciar una sesión de vista previa. Después de haber verificado que los datos transformados se ven como se esperaba, vaya a la esquema de salida pestaña y elegir Usar esquema de vista previa de datos para actualizar el esquema automáticamente.

A medida que agrega nuevos tipos de transformaciones, la vista previa puede mostrar un mensaje sobre una dependencia que falta. Cuando esto suceda, elija Finalizar sesión y el inicio de uno nuevo, por lo que la vista previa recoge el nuevo tipo de nodo.

Extraer información del instrumento

Comencemos tratando con la información sobre el nombre del instrumento para normalizarlo en columnas a las que sea más fácil acceder en la tabla de salida resultante.

  1. Agrega una Cadena dividida nodo y nombrarlo Split instrument, que tokenizará la columna del instrumento usando una expresión regular de espacio en blanco: s+ (un solo espacio serviría en este caso, pero de esta manera es más flexible y visualmente más claro).
  2. Queremos mantener la información del instrumento original como está, así que ingrese un nuevo nombre de columna para la matriz dividida: instrument_arr.
    Configuración dividida
  3. Añadir un Matriz a columnas nodo y nombrarlo Instrument columns para convertir la columna de matriz recién creada en nuevos campos, a excepción de symbol, para el que ya tenemos una columna.
  4. Seleccione la columna instrument_arr, omita el primer token y dígale que extraiga las columnas de salida month, day, year, strike_price, type usando índices 2, 3, 4, 5, 6 (los espacios después de las comas son para facilitar la lectura, no afectan la configuración).
    Configuración de matriz

El año extraído se expresa con sólo dos dígitos; pongamos un recurso provisional para suponer que es en este siglo si solo usan dos dígitos.

  1. Agrega una Columna derivada nodo y nombrarlo Four digits year.
  2. Participar year como la columna derivada para que la anule e ingrese la siguiente expresión SQL:
    CASE WHEN length(year) = 2 THEN ('20' || year) ELSE year END
    Configuración de columna derivada del año

Para mayor comodidad, construimos un expiration_date campo que un usuario puede tener como referencia de la última fecha en que puede ejercer la opción.

  1. Agrega una Concatenar columnas nodo y nombrarlo Build expiration date.
  2. Nombra la nueva columna expiration_date, seleccione las columnas year, monthy day (en ese orden), y un guión como espaciador.
    Configuración de fecha concatenada

El diagrama hasta ahora debería parecerse al siguiente ejemplo.

DÍA

La vista previa de datos de las nuevas columnas hasta el momento debería parecerse a la siguiente captura de pantalla.

Vista previa de datos

Normalizar el número de contratos

Cada una de las filas de los datos indica el número de contratos de cada opción que se compraron o vendieron y los lotes en los que se completaron las órdenes. Sin perder la información sobre los lotes individuales, queremos tener cada cantidad en una fila individual con un solo valor de cantidad, mientras que el resto de la información se replica en cada fila producida.

Primero, combinemos las cantidades en una sola columna.

  1. Añadir un Deshacer el pivote de columnas en filas nodo y nombrarlo Unpivot actions.
  2. Elige las columnas bought y sold para anular el pivote y almacenar los nombres y valores en columnas denominadas action y contracts, respectivamente.
    Desactivar configuración
    Observe en la vista previa que la nueva columna contracts sigue siendo una matriz de números después de esta transformación.
  1. Añadir un Explotar matriz o mapa en filas fila nombrada Explode contracts.
  2. Elija el contracts columna y entrar contracts como la nueva columna para anularla (no es necesario mantener la matriz original).

La vista previa ahora muestra que cada fila tiene un solo contracts cantidad, y el resto de los campos son iguales.

Esto también significa que order_id ya no es una clave única. Para sus propios casos de uso, debe decidir cómo modelar sus datos y si desea desnormalizarlos o no.
Explotar configuración

La siguiente captura de pantalla es un ejemplo de cómo se ven las nuevas columnas después de las transformaciones hasta el momento.
Vista previa de datos

Crear una tabla de resumen

Ahora crea una tabla de resumen con la cantidad de contratos negociados para cada tipo y cada símbolo bursátil.

Supongamos con fines ilustrativos que los archivos procesados ​​pertenecen a un solo día, por lo que este resumen brinda a los usuarios comerciales información sobre cuál es el interés y el sentimiento del mercado ese día.

  1. Agrega una Seleccionar campos y seleccione las siguientes columnas para conservar el resumen: symbol, typey contracts.
    Campos seleccionados
  2. Agrega una Pivotar filas en columnas nodo y nombrarlo Pivot summary.
  3. agregado en el contracts columna usando sum y elija convertir el type columna.
    Configuración de pivote

Normalmente, lo almacenaría en alguna base de datos o archivo externo como referencia; en este ejemplo, lo guardamos como un archivo CSV en Amazon S3.

  1. Añadir un Procesamiento de autoequilibrado nodo y nombrarlo Single output file.
  2. Aunque ese tipo de transformación se usa normalmente para optimizar el paralelismo, aquí lo usamos para reducir la salida a un solo archivo. Por lo tanto, ingrese 1 en la configuración del número de particiones.
    Configuración de autoequilibrio
  3. Agregue un destino S3 y asígnele un nombre CSV Contract summary.
  4. Elija CSV como formato de datos e ingrese una ruta de S3 donde el rol de trabajo puede almacenar archivos.

La última parte del trabajo ahora debería parecerse al siguiente ejemplo.
DÍA

  1. Guarde y ejecute el trabajo. Utilizar el Ron pestaña para verificar cuando ha terminado con éxito.
    Encontrará un archivo en esa ruta que es un CSV, a pesar de no tener esa extensión. Probablemente necesitará agregar la extensión después de descargarla para abrirla.
    En una herramienta que puede leer el CSV, el resumen debería parecerse al siguiente ejemplo.
    Hoja de cálculo

Limpiar columnas temporales

En preparación para guardar los pedidos en una tabla histórica para un análisis futuro, limpie algunas columnas temporales creadas en el camino.

  1. Agrega una Soltar campos nodo con el Explode contracts nodo seleccionado como su padre (estamos ramificando la canalización de datos para generar una salida separada).
  2. Seleccione los campos a descartar: instrument_arr, month, dayy year.
    El resto lo queremos conservar para que quede guardado en la tabla histórica que crearemos más adelante.
    Soltar campos

Estandarización de moneda

Estos datos sintéticos contienen operaciones ficticias en dos monedas, pero en un sistema real podría obtener monedas de mercados de todo el mundo. Es útil estandarizar las monedas manejadas en una sola moneda de referencia para que puedan compararse y agregarse fácilmente para informes y análisis.

Utilizamos Atenea amazónica para simular una tabla con conversiones de divisas aproximadas que se actualiza periódicamente (aquí asumimos que procesamos las órdenes lo suficientemente a tiempo como para que la conversión sea un representante razonable para propósitos de comparación).

  1. Abra la consola de Athena en la misma región en la que utiliza AWS Glue.
  2. Ejecute la siguiente consulta para crear la tabla configurando una ubicación de S3 donde sus roles de Athena y AWS Glue puedan leer y escribir. Además, es posible que desee almacenar la tabla en una base de datos diferente a la default (si lo hace, actualice el nombre completo de la tabla según corresponda en los ejemplos proporcionados).
    CREATE EXTERNAL TABLE default.exchange_rates(currency string, exchange_rate double)
    ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    STORED AS TEXTFILE
    LOCATION 's3://<enter some bucket>/exchange_rates/';

  3. Ingrese algunas conversiones de muestra en la tabla:
    INSERT INTO default.exchange_rates VALUES ('usd', 1.0), ('eur', 1.09), ('gbp', 1.24);
  4. Ahora debería poder ver la tabla con la siguiente consulta:
    SELECT * FROM default.exchange_rates
  5. De vuelta en el trabajo visual de AWS Glue, agregue un Lookup nodo (como hijo de Drop Fields) y llámalo Exchange rate.
  6. Ingrese el nombre calificado de la tabla que acaba de crear, usando currency como tecla y seleccione la exchange_rate campo a utilizar.
    Debido a que el campo tiene el mismo nombre tanto en los datos como en la tabla de búsqueda, solo podemos ingresar el nombre currency y no es necesario definir una asignación.Configuración de búsqueda
    En el momento de escribir este artículo, la transformación de búsqueda no se admite en la vista previa de datos y mostrará un error de que la tabla no existe. Esto es solo para la vista previa de datos y no impide que el trabajo se ejecute correctamente. Los pocos pasos restantes de la publicación no requieren que actualice el esquema. Si necesita ejecutar una vista previa de datos en otros nodos, puede eliminar el nodo de búsqueda temporalmente y luego volver a colocarlo.
  7. Agrega una Columna derivada nodo y nombrarlo Total in usd.
  8. Asigne un nombre a la columna derivada total_usd y utilice la siguiente expresión SQL:
    round(contracts * price * exchange_rate, 2)
    Configuración de conversión de moneda
  9. Agrega una Agregar marca de tiempo actual nodo y nombre la columna ingest_date.
  10. Usa el formato %Y-%m-%d para su marca de tiempo (para fines de demostración, solo estamos usando la fecha; puede hacerlo más preciso si lo desea).
    Configuración de marca de tiempo

Guardar la tabla histórica de pedidos

Para guardar la tabla de pedidos históricos, complete los siguientes pasos:

  1. Agregue un nodo de destino de S3 y asígnele un nombre Orders table.
  2. Configure el formato Parquet con una compresión rápida y proporcione una ruta de destino de S3 bajo la cual almacenar los resultados (separados del resumen).
  3. Seleccione Cree una tabla en el catálogo de datos y, en ejecuciones posteriores, actualice el esquema y agregue nuevas particiones.
  4. Introduzca una base de datos de destino y un nombre para la nueva tabla, por ejemplo: option_orders.
    Configuración del fregadero de la mesa

La última parte del diagrama ahora debería verse similar a la siguiente, con dos ramas para las dos salidas separadas.
DÍA

Después de ejecutar el trabajo correctamente, puede usar una herramienta como Athena para revisar los datos que ha producido el trabajo consultando la nueva tabla. Puede encontrar la tabla en la lista de Athena y elegir Tabla de vista previa o simplemente ejecute una consulta SELECT (actualizando el nombre de la tabla al nombre y catálogo que usó):

SELECT * FROM default.option_orders limit 10

El contenido de su tabla debe ser similar a la siguiente captura de pantalla.
Contenido de la tabla

Limpiar

Si no desea mantener este ejemplo, elimine los dos trabajos que creó, las dos tablas en Athena y las rutas de S3 donde se almacenaron los archivos de entrada y salida.

Conclusión

En esta publicación, mostramos cómo las nuevas transformaciones en AWS Glue Studio pueden ayudarlo a realizar transformaciones más avanzadas con una configuración mínima. Esto significa que puede implementar más casos de uso de ETL sin tener que escribir ni mantener ningún código. Las nuevas transformaciones ya están disponibles en AWS Glue Studio, por lo que puede usar las nuevas transformaciones hoy en sus trabajos visuales.


Acerca del autor.

gonzalo herreros es Arquitecto Senior de Big Data en el equipo de AWS Glue.

Sello de tiempo:

Mas de Big Data de AWS