En este tema, exploraremos dos conceptos fundamentales en Apache Spark: las transformaciones y las acciones. Estos conceptos son esenciales para entender cómo manipular y procesar datos en Spark.
¿Qué son las Transformaciones?
Las transformaciones en Spark son operaciones que se aplican a un RDD (Resilient Distributed Dataset) y producen un nuevo RDD. Las transformaciones son perezosas, lo que significa que no se ejecutan inmediatamente. En lugar de eso, se registran en un plan de ejecución que se ejecuta cuando se llama a una acción.
Tipos de Transformaciones
-
map(función): Aplica una función a cada elemento del RDD y devuelve un nuevo RDD con los resultados.
rdd = sc.parallelize([1, 2, 3, 4]) rdd2 = rdd.map(lambda x: x * 2) print(rdd2.collect()) # Salida: [2, 4, 6, 8]
-
filter(función): Filtra los elementos del RDD que no cumplen con una condición.
rdd = sc.parallelize([1, 2, 3, 4]) rdd2 = rdd.filter(lambda x: x % 2 == 0) print(rdd2.collect()) # Salida: [2, 4]
-
flatMap(función): Similar a
map
, pero cada entrada puede ser mapeada a cero o más elementos de salida (es decir, puede devolver una lista de elementos).rdd = sc.parallelize(["hello world", "hi"]) rdd2 = rdd.flatMap(lambda x: x.split(" ")) print(rdd2.collect()) # Salida: ['hello', 'world', 'hi']
-
distinct(): Devuelve un nuevo RDD con elementos únicos.
rdd = sc.parallelize([1, 2, 2, 3, 4, 4]) rdd2 = rdd.distinct() print(rdd2.collect()) # Salida: [1, 2, 3, 4]
-
union(rdd): Devuelve un nuevo RDD que contiene los elementos de ambos RDDs.
rdd1 = sc.parallelize([1, 2, 3]) rdd2 = sc.parallelize([3, 4, 5]) rdd3 = rdd1.union(rdd2) print(rdd3.collect()) # Salida: [1, 2, 3, 3, 4, 5]
-
intersection(rdd): Devuelve un nuevo RDD que contiene solo los elementos comunes a ambos RDDs.
rdd1 = sc.parallelize([1, 2, 3]) rdd2 = sc.parallelize([3, 4, 5]) rdd3 = rdd1.intersection(rdd2) print(rdd3.collect()) # Salida: [3]
¿Qué son las Acciones?
Las acciones en Spark son operaciones que devuelven un valor al controlador del programa o escriben datos a un sistema de almacenamiento externo. Las acciones desencadenan la ejecución de las transformaciones perezosas.
Tipos de Acciones
-
collect(): Devuelve todos los elementos del RDD como una lista.
rdd = sc.parallelize([1, 2, 3, 4]) print(rdd.collect()) # Salida: [1, 2, 3, 4]
-
count(): Devuelve el número de elementos en el RDD.
rdd = sc.parallelize([1, 2, 3, 4]) print(rdd.count()) # Salida: 4
-
first(): Devuelve el primer elemento del RDD.
rdd = sc.parallelize([1, 2, 3, 4]) print(rdd.first()) # Salida: 1
-
take(n): Devuelve los primeros
n
elementos del RDD.rdd = sc.parallelize([1, 2, 3, 4]) print(rdd.take(2)) # Salida: [1, 2]
-
reduce(función): Aplica una función de reducción a los elementos del RDD.
rdd = sc.parallelize([1, 2, 3, 4]) suma = rdd.reduce(lambda x, y: x + y) print(suma) # Salida: 10
-
saveAsTextFile(path): Escribe los elementos del RDD en un archivo de texto en el sistema de archivos.
rdd = sc.parallelize([1, 2, 3, 4]) rdd.saveAsTextFile("/ruta/al/archivo")
Ejercicio Práctico
Ejercicio 1: Transformaciones Básicas
- Crea un RDD a partir de la lista
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
. - Aplica una transformación
filter
para obtener solo los números pares. - Aplica una transformación
map
para multiplicar cada número por 2. - Usa la acción
collect
para obtener los resultados y muéstralos.
Solución
from pyspark import SparkContext sc = SparkContext("local", "Transformaciones y Acciones") # Paso 1: Crear el RDD rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) # Paso 2: Filtrar números pares rdd_pares = rdd.filter(lambda x: x % 2 == 0) # Paso 3: Multiplicar cada número por 2 rdd_multiplicado = rdd_pares.map(lambda x: x * 2) # Paso 4: Recoger y mostrar los resultados resultados = rdd_multiplicado.collect() print(resultados) # Salida: [4, 8, 12, 16, 20]
Ejercicio 2: Acciones Básicas
- Crea un RDD a partir de la lista
[10, 20, 30, 40, 50]
. - Usa la acción
count
para contar el número de elementos en el RDD. - Usa la acción
first
para obtener el primer elemento del RDD. - Usa la acción
reduce
para sumar todos los elementos del RDD.
Solución
# Paso 1: Crear el RDD rdd = sc.parallelize([10, 20, 30, 40, 50]) # Paso 2: Contar el número de elementos conteo = rdd.count() print(conteo) # Salida: 5 # Paso 3: Obtener el primer elemento primero = rdd.first() print(primero) # Salida: 10 # Paso 4: Sumar todos los elementos suma = rdd.reduce(lambda x, y: x + y) print(suma) # Salida: 150
Conclusión
En esta sección, hemos aprendido sobre las transformaciones y acciones en Apache Spark. Las transformaciones son operaciones perezosas que crean nuevos RDDs, mientras que las acciones desencadenan la ejecución de estas transformaciones y devuelven resultados. Comprender estos conceptos es crucial para trabajar eficientemente con Spark y manipular grandes volúmenes de datos.
En el próximo tema, exploraremos los DataFrames de Spark, una abstracción de datos más avanzada y optimizada que facilita el trabajo con datos estructurados.
Curso de Apache Spark
Módulo 1: Introducción a Apache Spark
Módulo 2: Conceptos Básicos de Spark
- RDDs (Conjuntos de Datos Distribuidos Resilientes)
- Transformaciones y Acciones
- DataFrames de Spark
- Spark SQL
Módulo 3: Procesamiento de Datos con Spark
Módulo 4: Programación Avanzada en Spark
Módulo 5: Ajuste y Optimización del Rendimiento
- Entendiendo los Trabajos de Spark
- Caché y Persistencia
- Gestión de Memoria
- Optimizando Aplicaciones Spark
Módulo 6: Spark en la Nube
- Ejecutando Spark en AWS
- Ejecutando Spark en Azure
- Ejecutando Spark en Google Cloud
- Spark con Kubernetes
Módulo 7: Aplicaciones del Mundo Real y Estudios de Caso
- Procesamiento de Datos en Tiempo Real
- Analítica de Big Data
- Pipelines de Aprendizaje Automático
- Estudios de Caso