Scala PySpark Big Data en la práctica: el código y los comandos que realmente importan
Scala PySpark Big Data: lo esencial en un artículo — código real, esquemas y pasos concretos, extractos de un curso de 47 lecciones.
Sin teoría interminable aquí: abrimos la terminal y practicamos. Aquí lo esencial de Scala PySpark Big Data, extraído directamente de un curso completo de 47 lecciones — con código real que puedes copiar y pegar ahora.
- Introducción a los Paradigmas de Programación
- Instalar el entorno Big Data
- Descubrir el Big Data y Spark
- Fundamentos de Scala
- Scala avanzado para Spark
Trabajos prácticos Spark completos
spark-shell (Scala) y PySpark. Este módulo es un laboratorio práctico guiado: escribes los comandos uno por uno y observas los resultados.Objetivos pedagógicos
- Spark instalado (ver Capítulo 01)
- El
spark-shellaccesible desde tu terminal - Una carpeta de trabajo (ejemplo:
C:/Users/user01/Desktop/SPARK/)
PARTE 0 – Dominar el spark-shell (REPL)
spark-shell es un REPL (Read-Eval-Print Loop): un terminal interactivo donde escribes un comando Scala, Spark lo ejecuta inmediatamente y muestra el resultado. Es la herramienta ideal para aprender y probar tus comandos Spark rápidamente, sin necesidad de crear un proyecto completo.spark-shell, Spark crea automáticamente dos variables para ti:
spark: un objeto SparkSession (el punto de entrada principal de Spark)sc: un objeto SparkContext (utilizado para crear RDD)
import spark.implicits._ ya está importado automáticamente (lo que permite usar .toDF()).0.1 – Lanzar el spark-shell
# Windows (PowerShell) : spark-shell # macOS / Linux : ./bin/spark-shell # O si Spark está en tu PATH : spark-shell
http://localhost:4040. Si el puerto 4040 está ocupado, Spark prueba 4041, 4042, etc. Esta interfaz te permite ver los jobs, stages y tareas en curso.0.2 – Primera prueba: crear un DataFrame
// Escribe estos comandos uno por uno en el spark-shell:
scala> import spark.implicits._
// ya importado automáticamente, pero útil si creas tu propia SparkSession
scala> val data = Seq(("Java", "20000"), ("Python", "100000"), ("Scala", "3000"))
// data: Seq[(String, String)] = List((Java,20000), (Python,100000), (Scala,3000))
scala> val df = data.toDF()
// df: org.apache.spark.sql.DataFrame = [_1: string, _2: string]
scala> df.show()
// +------+------+
// | _1| _2|
// +------+------+
// | Java| 20000|
// |Python|100000|
// | Scala| 3000|
// +------+------+_1 y _2 por defecto. Para darles nombres reales, usa .toDF("langage", "offres"):scala> val df = data.toDF("langage", "offres")
scala> df.show()
// +-------+------+
// |langage|offres|
// +-------+------+
// | Java| 20000|
// | Python|100000|
// | Scala| 3000|
// +-------+------+0.3 – Comandos especiales del spark-shell
: (dos puntos). Estos comandos no son Scala, son propios del REPL. Apréndelos, ¡te ahorrarán mucho tiempo!// Mostrar la ayuda completa (lista de todos los comandos especiales) scala> :help
| Comando | Descripción | Ejemplo |
|---|---|---|
:help |
Muestra la lista de todos los comandos disponibles | :help o :he |
:paste |
Modo «pegar»: permite pegar varias líneas de código de golpe. Termina con Ctrl+D. | :paste |
:load <fichero> |
Carga y ejecuta un archivo .scala línea por línea |
:load hello.scala |
:load -v <fichero> |
Carga un archivo en modo verbose (muestra cada línea ejecutada) | :load -v hello.scala |
:quit |
Salir del spark-shell correctamente | :quit o :q |
:history |
Muestra el historial de comandos escritos | :history o :history 20 |
:h? <palabra> |
Buscar una palabra en el historial | :h? toDF |
:require <jar> |
Añadir un archivo JAR al classpath durante la sesión | :require /ruta/a/mi.jar |
:type <expr> |
Muestra el tipo de una expresión sin ejecutarla | :type 1 + 2 → Int |
:imports |
Muestra todos los imports activos en la sesión | :imports |
:implicits |
Muestra los implicits disponibles | :implicits -v |
:reset |
Reinicia el REPL (borra todas las variables) | :reset |
:replay |
Reinicia y vuelve a ejecutar todos los comandos anteriores | :replay |
:save <fichero> |
Guarda la sesión en un archivo .scala |
:save mi_sesion.scala |
:sh <cmd> |
Ejecuta un comando shell (Unix/macOS únicamente) | :sh ls -la |
:silent |
Activa/desactiva la visualización automática de resultados | :silent |
:javap <clase> |
Desensambla una clase Java / Scala | :javap scala.Int |
:paste? — En el spark-shell, si pegas código multilínea directamente, el REPL intenta ejecutar cada línea por separado, lo que provoca errores. El modo :paste permite pegar un bloque entero de código y ejecutarlo como un todo.// Paso 1: escribe :paste y pulsa Intro
scala> :paste
// Entering paste mode (ctrl-D to finish)
// Paso 2: pega tu código multilínea
val noms = Seq("Alice", "Bob", "Charlie")
val rdd = sc.parallelize(noms)
val majuscules = rdd.map(_.toUpperCase)
majuscules.collect()
// Paso 3: pulsa Ctrl+D para ejecutar
// Exiting paste mode, now interpreting.
// noms: Seq[String] = List(Alice, Bob, Charlie)
// rdd: org.apache.spark.rdd.RDD[String] = ...
// majuscules: org.apache.spark.rdd.RDD[String] = ...
// res0: Array[String] = Array(ALICE, BOB, CHARLIE):paste, pulsa Ctrl+D. Si pulsas Ctrl+C, cancelas el código pegado..scala que contiene funciones o tratamientos que quieres ejecutar en el spark-shell. En lugar de copiarlo todo, usa :load.Paso 1 – Crear el archivo Scala:
# Windows (PowerShell) :
@"
println("Bonjour depuis le fichier Scala !")
val animaux = Seq("chat", "chien", "oiseau")
val rdd = sc.parallelize(animaux)
println("Nombre d'animaux : " + rdd.count())
rdd.collect().foreach(println)
"@ | Out-File -Encoding utf8 "C:\Users\user01\Desktop\SPARK\hello.scala"
# macOS / Linux :
cat > ~/Desktop/SPARK/hello.scala <<'EOF'
println("Bonjour depuis le fichier Scala !")
val animaux = Seq("chat", "chien", "oiseau")
val rdd = sc.parallelize(animaux)
println("Nombre d'animaux : " + rdd.count())
rdd.collect().foreach(println)
EOFPráctica Spark SQL — AAPL & Income
AAPL.csv) y datos de ingresos (income.csv) — utilizando case class, RDD, DataFrame y las funciones de agregación de Spark SQL.Tabla de contenidos
0. Presentación de los datos y descarga
0.1 – Archivo AAPL.csv (datos bursátiles de Apple)
AAPL.csv contiene el historial de cotizaciones de la acción de Apple (NASDAQ : AAPL). Cada línea representa un día de transacción.| Columna | Tipo | Descripción | Ejemplo |
|---|---|---|---|
dt | String | Fecha de la transacción | 1984-09-07 |
openprice | Double | Precio de apertura del día | 25.50 |
highprice | Double | Precio más alto del día | 26.10 |
lowprice | Double | Precio más bajo del día | 24.80 |
closeprice | Double | Precio de cierre del día | 25.90 |
volume | Double | Número de acciones intercambiadas | 1234567.0 |
adjcloseprice | Double | Precio de cierre ajustado (dividendos, splits) | 25.85 |
AAPL.csv — 3 métodos
Método 1 —
wget (recomendado, Windows/macOS/Linux)Descarga directamente el archivo bruto desde GitHub:
wget https://raw.githubusercontent.com/inskillflow/data/refs/heads/main/AAPL.csv
Invoke-WebRequest si wget no está disponible:# PowerShell — descargar AAPL.csv en la carpeta actual Invoke-WebRequest -Uri "https://raw.githubusercontent.com/inskillflow/data/refs/heads/main/AAPL.csv" -OutFile "AAPL.csv"
git clone (clona todo el repositorio)Clona el repositorio completo y recupera todos los archivos de datos:
# Clonar el repositorio inskillflow/data git clone https://github.com/inskillflow/data.git # El archivo AAPL.csv estará en : # data/AAPL.csv
- Abre https://github.com/inskillflow/data/blob/main/AAPL.csv
- Haz clic en el botón « Raw » en la parte superior derecha del archivo
- Pulsa Ctrl+S (o Cmd+S en Mac) para guardar la página con el nombre
AAPL.csv
https://raw.githubusercontent.com/inskillflow/data/refs/heads/main/AAPL.csv
AAPL.csv en una carpeta accesible y adapta la ruta en tu código:
- Windows :
C:\Users\TuNombre\Desktop\Spark\AAPL.csv - Linux / macOS :
/home/usuario/data/AAPL.csv - Spark Shell (ruta relativa) :
./AAPL.csv
0.2 – Archivo Income.csv (datos de ingresos)
| Columna | Tipo | Descripción |
|---|---|---|
id | Double | Identificador único |
workclass | String | Categoría de empleo (Private, Self-emp, Gov...) |
education | String | Nivel de educación |
maritalstatus | String | Estado civil |
occupation | String | Profesión |
relationship | String | Relación familiar |
race | String | Origen étnico |
gender | String | Género |
nativecountry | String | País de origen |
income | String | Tramo de ingresos (<=50K o >50K) |
age | Double | Edad del individuo |
fnlwgt | Double | Peso de ponderación estadística |
educationalnum | Double | Número de años de educación |
capitalgain | Double | Ganancias de capital |
capitalloss | Double | Pérdidas de capital |
hoursperweek | Double | Horas de trabajo por semana |
Income.csv — 3 métodos
Método 1 —
wgetwget https://raw.githubusercontent.com/inskillflow/data/refs/heads/main/Income.csv
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/inskillflow/data/refs/heads/main/Income.csv" -OutFile "Income.csv"
git clone (clona ambos archivos a la vez)# Si ya clonaste el repositorio para AAPL.csv, Income.csv ya está presente # Si no: git clone https://github.com/inskillflow/data.git # El archivo Income.csv estará en : data/Income.csv
Pattern matching y Options
Option[T] que elimina los NullPointerException, y profundizar con Either y las for-comprehensions.switch/case en Java o de un match en Python 3.10+, pero mucho más potente. Si ya conoces if/elif/else en Python, lo entenderás sin dificultad. Scala añade la posibilidad de verificar tipos, extraer datos de objetos y plantear condiciones — todo en una sintaxis clara y compacta.Objetivos pedagógicos
1. La analogía del triaje postal
Imagina un centro de triaje postal. Cada carta llega a una cinta transportadora. Un empleado mira la dirección y envía la carta a la casilla correcta: París a la izquierda, Lyon a la derecha, Marsella recto. Si la dirección no coincide con nada conocido, la carta va a una casilla «Otros».
El pattern matching funciona exactamente igual que este triaje postal: se examina un valor, se compara con varios modelos (patterns) y se ejecuta el código asociado al primer modelo que coincide.
if/else — El pattern matching es más legible, más seguro (el compilador verifica que todos los casos están cubiertos con los sealed trait) y mucho más potente, ya que puede deconstruir objetos complejos, extraer valores y combinar tipo + valor + condición en un solo case.2. La sintaxis match/case
La expresión match toma un valor y lo compara con una serie de cláusulas case. La primera cláusula que coincide se ejecuta. A diferencia del switch de Java, no hay que escribir break — Scala se detiene automáticamente en el primer caso coincidente.
match es una expresión, no una instrucción. Esto significa que siempre devuelve un valor. Por tanto, se puede escribir val x = valor match { ... }.Ejemplo 1: los días de la semana
val jour = "Mercredi"
val typeJour = jour match {
case "Lundi" | "Mardi" | "Mercredi" | "Jeudi" | "Vendredi" =>
"Jour ouvré"
case "Samedi" | "Dimanche" =>
"Week-end"
case _ =>
"Jour inconnu" // _ = la casilla "Otros" del triaje postal
}
println(typeJour) // "Jour ouvré"_ — El símbolo _ (guion bajo) coincide con «todo lo demás». Siempre debe colocarse al final, ya que lo atrapa todo. Sin él, si ningún case coincide, Scala lanza una excepción MatchError en tiempo de ejecución.Ejemplo 2: convertir una nota en mención
val note = 15
val mention = note match {
case 20 => "Parfait"
case 16 | 17 | 18 | 19 => "Très bien"
case 14 | 15 => "Bien"
case 12 | 13 => "Assez bien"
case 10 | 11 => "Passable"
case _ => "Insuffisant"
}
println(mention) // "Bien"En Java o Python, un switch o match es una instrucción: hace algo pero no devuelve un valor directamente. En Scala, match es una expresión: siempre devuelve un valor.
Lo que cambia en la práctica:
// Scala : match es una expresión, se puede asignar directamente
val categorie = age match {
case a if a < 18 => "Mineur"
case a if a < 65 => "Adulte"
case _ => "Senior"
}
// También se puede usar como argumento de una función
println(age match {
case a if a < 18 => "Mineur"
case _ => "Adulte"
})
// O en una interpolación de cadena
val message = s"Statut : ${age match {
case a if a < 18 => "Mineur"
case _ => "Adulte"
}}"// Java : el switch (antes de Java 14) no devuelve un valor
// Había que escribir :
String categorie;
switch (age) {
case ...: categorie = "Mineur"; break;
default: categorie = "Adulte";
}
// Java 14+ añadió las switch expressions para cubrir esta carenciamatch devuelve un valor, el compilador verifica que todas las ramas devuelven el mismo tipo. Si un case devuelve un String y otro un Int, Scala infiere el tipo común (Any). Suele ser señal de un error de diseño.# Python 3.10+ structural pattern matching
jour = "Mercredi"
match jour:
case "Lundi" | "Mardi" | "Mercredi" | "Jeudi" | "Vendredi":
type_jour = "Jour ouvre"
case "Samedi" | "Dimanche":
type_jour = "Week-end"
case _:
type_jour = "Jour inconnu"
# Diferencia : en Python, match es una instrucción (sin asignación directa)
# En Scala : val x = valor match { ... } <-- expresión que devuelve un valor
# En Python : debes asignar en cada rama manualmente# Python < 3.10 : sin match/case, se usa if/elif/else
jour = "Mercredi"
if jour in ("Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi"):
type_jour = "Jour ouvre"
elif jour in ("Samedi", "Dimanche"):
type_jour = "Week-end"
else:
type_jour = "Jour inconnu"Este artículo cubre los extractos más útiles — el curso completo Scala PySpark Big Data (13 capítulos, 47 lecciones, ejercicios corregidos y proyecto final) te lleva hasta el final.
./acceder-al-curso-completo curso gratuito : Dominar Claude CodeFAQ
¿Cuánto tiempo se tarda en aprender Scala PySpark Big Data?
¿Se necesitan requisitos previos?
¿Por dónde empezar concretamente?
📬 ¿Quieres recibir este tipo de guía cada semana? Suscríbete gratis — código real, cero palabrería.