A煤n no tienes acceso a esta clase

Crea una cuenta y contin煤a viendo este curso

Agrupaciones y operaciones join sobre DF

16/25
Recursos

Aportes 22

Preguntas 2

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

El tema de crear los esquemas siempre es un poco tardado, por el momento cre茅 una peque帽a funci贸n en python que imprime un string de la estructura del esquema. Las consideraciones son:

  • La funci贸n recibe dos par谩metros, un Pandas DataFrame y el nombre en el que se quiere guardar el Schema.
  • El print que devuelve la funci贸n tiene un StringType() para todas las columnas, hay que hacer el cambio manual.
  • Hay que copiar y pegar el print que devuelve la funci贸n en una nueva celda.
  • Funciona bien, cuando el csv tiene nombres correctos y sin espacios en las columnas, de lo contrario habr谩 que hacer unos peque帽os arreglos manuales.
import pandas as pd
import re

def createSchema(df, variable_name):
    variable_name = str(variable_name)
    structColumns = [re.sub(r'(\w+)',"StructField('\g<1>', StringType(), False)\n",i) for i in df.columns]
    return print(variable_name + ' = StructType(' + '[%s]' % ', '.join(map(str, structColumns)) + ')')


#Uso de la funci贸n
resultados = pd.read_csv(path + 'resultados.csv', nrows = 2)
createSchema(resultados, 'resultadosSchema') 

#Devuelve:
resultadosSchema = StructType([StructField('resultado_id', StringType(), False)
, StructField('medalla', StringType(), False)
, StructField('deportista_id', StringType(), False)
, StructField('juego_id', StringType(), False)
, StructField('evento_id', StringType(), False)
])

Espero esto le sea de utilidad a alguien 馃槃

hay un typo en la ejecucion cuando hace los joins y es raro que le sirva
escribe resultadosDF.deporitsta_id

Esta es la soluci贸n al reto de 脫scar:

resultadosDF.join(deportistaOlimpicoDF,\
                 deportistaOlimpicoDF.deportista_id == resultadosDF.deportista_id,
                 "left").join(
                 paisesDF, paisesDF.equipo_id == deportistaOlimpicoDF.equipo_id
                 ).select("medalla", "equipo","sigla").\
                 where(resultadosDF.medalla != "NA").show(20)
+-------+--------------+-----+
|medalla|        equipo|sigla|
+-------+--------------+-----+
|   Gold|Denmark/Sweden|  SWE|
| Bronze|       Finland|  FIN|
| Bronze|       Finland|  FIN|
| Bronze|       Finland|  FIN|
| Bronze|       Finland|  FIN|
|   Gold|       Finland|  FIN|
|   Gold|       Finland|  FIN|
|   Gold|       Finland|  FIN|
| Bronze|       Finland|  FIN|
|   Gold|        Norway|  NOR|
|   Gold|        Norway|  NOR|
|   Gold|        Norway|  NOR|
| Silver|        Norway|  NOR|
| Bronze|        Norway|  NOR|```

Si se presenta el error: NameError: name 鈥榗ol鈥 is not defined

from pyspark.sql.functions import col
resultadoDF.filter(resultadoDF.medalla!=鈥淣A鈥)
.join(deportista1DF,deportista1DF.deportista_id == resultadoDF.deportista_id)
.join(paisDF,paisDF.pais_id == deportista1DF.equipo_id)
.select(鈥渕edalla鈥,paisDF.sigla,paisDF.equipo).show()

Reto:

from pyspark.sql.functions import *
df_athetles.join(df_results, df_results.athetle_id == df_athetles.athetle_id, 'inner') \
    .join(df_teams, df_teams.team_id == df_athetles.team_id, 'inner') \
    .select('medal', 'country').where(df_results.medal != 'NA').distinct() \
    .sort(col('country').desc()).show()

Reto:

df_athetles.join(df_teams, df_teams.team_id == df_athetles.team_id, 'inner') \
    .join(df_results, df_results.athetle_id == df_athetles.athetle_id, 'inner') \
    .select('medal', 'country', 'athetle_name', 'team').show()

Este es el c贸digo que apliqu茅 para resolver el reto

results_DF.join(
    player_DF, results_DF.player_id == player_DF.player_id, 'left'
) \
.join(
    countries_DF, player_DF.team_id == countries_DF.id, 'left'
) \
.select('medal', 'team', 'abbreviation') \
.filter(results_DF.medal != 'NA').show()

Este es el resultado

+------+--------------+------------+
| medal|          team|abbreviation|
+------+--------------+------------+
|  Gold|Denmark/Sweden|         SWE|
|Bronze|       Finland|         FIN|
|Bronze|       Finland|         FIN|
|Bronze|       Finland|         FIN|
|Bronze|       Finland|         FIN|
|  Gold|       Finland|         FIN|
|  Gold|       Finland|         FIN|
|  Gold|       Finland|         FIN|
|Bronze|       Finland|         FIN|
|  Gold|        Norway|         NOR|
|Bronze|        Norway|         NOR|
|Silver|        Norway|         NOR|
|Bronze|        Norway|         NOR|
|Silver|        Norway|         NOR|
|  Gold|        Norway|         NOR|
|  Gold|        Norway|         NOR|
|  Gold|        Norway|         NOR|
|  Gold|        Norway|         NOR|
|Silver|        Norway|         NOR|
|Bronze|   Netherlands|         NED|
+------+--------------+------------+

Comparto el resultado de la clase anterior

Hago un aporte que considero necesario y puede ahorrar dolores de cabeza.

Si tiene el .join() hecho de manera correcra y al momento de hacer un .show() demora mucho mas tiempo de lo normal (menos de 5 segundos), es muy probable que el schema de alguna de las tablas est茅 mal.

A mi me paso que por error le asigne el typo de dato int a un valor que era string, y nunca me mostraba la info. Una vez que correg铆 ese error todo funcion贸 perfecto.

Espero que les sirva. Saludos!

Mi soluci贸n al reto:

medallasDF = resultadosDF.filter(resultadosDF.medalla != "NA")

medallasDF.join(deportistaOlimpicoDF, medallasDF.deportista_id == deportistaOlimpicoDF.deportista_id, "left")\
    .join(paisesDF, paisesDF.id == deportistaOlimpicoDF.equipo_id)\
    .select(medallasDF.medalla, deportistaOlimpicoDF.nombre, paisesDF.sigla, paisesDF.equipo).show()

Mi soluci贸n al reto:

resultadosDF.join(deportistaDF, resultadosDF.deportista_id == deportistaDF.deportista_id, 'left') \
    .join(paisesDF, deportistaDF.equipo_id == paisesDF.id) \
    .select(col('medalla'), col('sigla').alias('Pa铆s'), col('equipo')) \
    .filter(resultadosDF.medalla != 'NA') \
    .show(10)
+-------+----+------+
|medalla|Pa铆s|equipo|
+-------+----+------+
| Bronze| IRI|  Iran|
| Silver| IRI|  Iran|
| Bronze| IRI|  Iran|
| Silver| IRI|  Iran|
| Silver| IRI|  Iran|
| Silver| IRI|  Iran|
|   Gold| IRI|  Iran|
| Bronze| IRI|  Iran|
| Silver| IRI|  Iran|
| Bronze| IRI|  Iran|
+-------+----+------+
only showing top 10 rows

Mi soluci贸n al reto

![](

Aqui la Salida de mi reto

Parar visualizar el diagrama en el jupyter notebook y te sea m谩s f谩cil ver los esquemas, ve a Cell > Cell Type > Markdown

Luego en la celda In [ ]: (previamente seleccionada) coloca lo siguiente:

![nombre_de_la_figura_](tu_ruta/modelo_relacional.jpg)

O cualquier figura de internet (aqu铆 desde el repositorio de rb-one)

![diagrama](https://raw.githubusercontent.com/rb-one/Cuso_Introductorio_de_Spark/master/files/modelo_relacional.jpg)

Hay que tener mucho cuidado al generar los DF desde los RDDs porque al no indicarle a Spark directamente los headers puede generar campos erroneos como:

['6', '"Speed Skating Women\'s 1', '000 metres"', '5'],

Conllevando a un error de tipos de datos.En ese caso deber铆amos hacer una limpieza adicional de la data antes de crear el data frame. Podemos evitar todo esto cargando los dataframes a trav茅s de:

sportsDF = sqlContext.read.schema(sportsSchema) \
    .option("header","true").csv(path+"evento.csv")

resultsDF = sqlContext.read.schema(resultsSchema) \
    .option("header","true").csv(path+"resultados.csv")

Me gusta ir dividiendo los Dataframes para as铆 ir visualizando lo que voy juntando. Ac谩 el Reto:

"""Debes crear un join que tenga, todas las medallas ganadoras馃帠(solo las ganadoras), unidas con el pa铆s y el equipo
al cual pertenecen estas medallas"""

ResultadosGanadoresDF=resultadoDF.filter(resultadoDF.medalla != 'NA')
ResultadosGanadoresDF.show(10)

EquiposGanadoresDF = deportistaDF.join(ResultadosGanadoresDF,"deportista_id").select("equipo_id","medalla")
EquiposGanadoresDF.show(10)

PaisesGanadoresDF = EquiposGanadoresDF.join(paisDF,EquiposGanadoresDF.equipo_id==paisDF.id).select("medalla","equipo","sigla")```




|resultado_id|medalla|deportista_id|juego_id|evento_id|
+------------+-------+-------------+--------+---------+
|           4|   Gold|            4|       2|        4|
|          38| Bronze|           15|       7|       19|
|          39| Bronze|           15|       7|       20|
|          41| Bronze|           16|      50|       14|
|          42| Bronze|           17|      17|       21|
|          43|   Gold|           17|      17|       22|
|          45|   Gold|           17|      17|       24|
|          49|   Gold|           17|      17|       28|
|          51| Bronze|           17|      19|       22|
|          61|   Gold|           20|      38|       32|
+------------+-------+-------------+--------+---------+
only showing top 10 rows

+---------+-------+
|equipo_id|medalla|
+---------+-------+
|      278|   Gold|
|      350| Bronze|
|      350| Bronze|
|      350| Bronze|
|      350| Bronze|
|      350|   Gold|
|      350|   Gold|
|      350|   Gold|
|      350| Bronze|
|      742|   Gold|
+---------+-------+
only showing top 10 rows

+-------+--------------+-----+
|medalla|        equipo|sigla|
+-------+--------------+-----+
|   Gold|Denmark/Sweden|  SWE|
| Bronze|       Finland|  FIN|
| Bronze|       Finland|  FIN|
| Bronze|       Finland|  FIN|
| Bronze|       Finland|  FIN|
|   Gold|       Finland|  FIN|
|   Gold|       Finland|  FIN|
|   Gold|       Finland|  FIN|
| Bronze|       Finland|  FIN|
|   Gold|        Norway|  NOR|
| Bronze|        Norway|  NOR|
| Silver|        Norway|  NOR|
| Bronze|        Norway|  NOR|
| Silver|        Norway|  NOR|
|   Gold|        Norway|  NOR|
|   Gold|        Norway|  NOR|
|   Gold|        Norway|  NOR|
|   Gold|        Norway|  NOR|
| Silver|        Norway|  NOR|
| Bronze|   Netherlands|  NED|
+-------+--------------+-----+
only showing top 20 rows

Hola a todos. Tengo un problema cuando intento mostrar el contenido del DF de los joins de esta clase. Por favor, si alguien me pudiera ayudar con esto, ya llevo bastante tiempo intentando arreglarlo y no encuentro informaci贸n util.

Un fragmento del error enuncia lo siguiente:

Py4JJavaError                             Traceback (most recent call last)
~/spark/python/pyspark/sql/utils.py in deco(*a, **kw)
     62         try:
---> 63             return f(*a, **kw)
     64         except py4j.protocol.Py4JJavaError as e:

~/Desktop/Intro_to_Spark/venv/lib/python3.7/site-packages/py4j/protocol.py in get_return_value(answer, gateway_client, target_id, name)
    327                     "An error occurred while calling {0}{1}{2}.\n".
--> 328                     format(target_id, ".", name), value)
    329             else:

Py4JJavaError: An error occurred while calling o536.select.

Esta es mi soluci贸n al reto:

Esta es mi soluci贸n al reto de la clase

resultadosDF.join(deportistas_OlimpicosDF,
                  on=[resultadosDF.deportista_id == deportistas_OlimpicosDF.deportista_id],
                  how='left'
                 ).join(paisesDF,
                        on=[deportistas_OlimpicosDF.equipo_id == paisesDF.id]
            ).select('medalla', 'equipo', 'sigla').filter(~(resultadosDF.medalla == 'NA')).show()
+-------+--------------+-----+
|medalla|        equipo|sigla|
+-------+--------------+-----+
|   Gold|Denmark/Sweden|  SWE|
| Bronze|       Finland|  FIN|
| Bronze|       Finland|  FIN|
| Bronze|       Finland|  FIN|
| Bronze|       Finland|  FIN|
|   Gold|       Finland|  FIN|
|   Gold|       Finland|  FIN|
|   Gold|       Finland|  FIN|
| Bronze|       Finland|  FIN|
|   Gold|        Norway|  NOR|
|   Gold|        Norway|  NOR|
|   Gold|        Norway|  NOR|
| Silver|        Norway|  NOR|
| Bronze|        Norway|  NOR|
| Silver|        Norway|  NOR|
| Bronze|        Norway|  NOR|
|   Gold|        Norway|  NOR|
|   Gold|        Norway|  NOR|
| Silver|        Norway|  NOR|
| Bronze|   Netherlands|  NED|
+-------+--------------+-----+
only showing top 20 rows

Les dejo mi soluci贸n al reto, la divid铆 en dos celdas.

Nota: tengo los nombres cambiados en algunos DF, as铆 que les dejo los esquemas que us茅.

Esquemas:

resultadosDF.printSchema()
root
 |-- resultado_id: integer (nullable = true)
 |-- medalla: string (nullable = true)
 |-- deportista_id: integer (nullable = true)
 |-- juego_id: integer (nullable = true)
 |-- evento_id: integer (nullable = true)
deportistaOlimpicoDF.printSchema()
root
 |-- deportista_id: integer (nullable = false)
 |-- nombre: string (nullable = false)
 |-- edadAlJugar: integer (nullable = false)
 |-- equipo_id: integer (nullable = false)
paisesDF.printSchema()
root
 |-- paises_id: integer (nullable = true)
 |-- equipo: string (nullable = true)
 |-- sigla: string (nullable = true)

Soluci贸n:
Primera celda -->

#Reto:
"""Debes crear un join que tenga, todas las medallas ganadoras馃帠(solo las ganadoras), unidas con el pa铆s y el equipo
al cual pertenecen estas medallas"""

"""#Primero hacemos el filter de las medallas solo ganadoras"""

resultadosGanadoresDF = resultadosDF.filter( (resultadosDF.medalla != "NA"))

#Mostarmos el resultado del filtro:
resultadosGanadoresDF.show(5)

+------------+-------+-------------+--------+---------+
|resultado_id|medalla|deportista_id|juego_id|evento_id|
+------------+-------+-------------+--------+---------+
|           4|   Gold|            4|       2|        4|
|          38| Bronze|           15|       7|       19|
|          39| Bronze|           15|       7|       20|
|          41| Bronze|           16|      50|       14|
|          42| Bronze|           17|      17|       21|
+------------+-------+-------------+--------+---------+
only showing top 5 rows

Segunda celda -->

"""Como podemos ver, el filtro funcion贸, ahora procedemos a ahcer los join"""

"""#medallas est谩n en: resultadosDF.medalla
#Pa铆s est谩 en: paisesDF.sigla
#Equipo est谩 en: paisesDF.equipo

#paises_id == equipo_id"""

retoClase16 = resultadosGanadoresDF.join(deportistaOlimpicoDF, deportistaOlimpicoDF.deportista_id == resultadosGanadoresDF.deportista_id,"left")\
    .join(paisesDF, paisesDF.paises_id == deportistaOlimpicoDF.equipo_id)\
    .select("medalla", 
        col("equipo").alias("Nombre del equipo"),
        col("sigla").alias("Pa铆s"))

retoClase16.show()

+-------+-----------------+----+
|medalla|Nombre del equipo|Pa铆s|
+-------+-----------------+----+
|   Gold|   Denmark/Sweden| SWE|
| Bronze|          Finland| FIN|
| Bronze|          Finland| FIN|
| Bronze|          Finland| FIN|
| Bronze|          Finland| FIN|
|   Gold|          Finland| FIN|
|   Gold|          Finland| FIN|
|   Gold|          Finland| FIN|
| Bronze|          Finland| FIN|
|   Gold|           Norway| NOR|
|   Gold|           Norway| NOR|
|   Gold|           Norway| NOR|
| Silver|           Norway| NOR|
| Bronze|           Norway| NOR|
| Silver|           Norway| NOR|
| Bronze|           Norway| NOR|
|   Gold|           Norway| NOR|
|   Gold|           Norway| NOR|
| Silver|           Norway| NOR|
| Bronze|      Netherlands| NED|
+-------+-----------------+----+
only showing top 20 rows

Es lo que entend铆

equiposGanadores = resultadosGanadoresDF \
	.join(deportistaOlimpicoDF,resultadosGanadoresDF.deportista_id==deportistaOlimpicoDF.deportista_id,"left") \ .join(paisesDF,paisesDF.id==deportistaOlimpicoDF.equipo_id,"left") \
	.select("medalla","sigla","equipo")

Mis resultados

+-------+-----+------+
|medalla|sigla|equipo|
+-------+-----+------+
| Bronze|  IRI|  Iran|
| Silver|  IRI|  Iran|
| Bronze|  IRI|  Iran|
| Bronze|  IRI|  Iran|
| Bronze|  IRI|  Iran|
|   Gold|  IRI|  Iran|
| Bronze|  IRI|  Iran|
| Bronze|  IRI|  Iran|
| Silver|  IRI|  Iran|
| Bronze|  IRI|  Iran|
| Bronze|  IRI|  Iran|
| Silver|  IRI|  Iran|
| Bronze|  IRI|  Iran|
| Silver|  IRI|  Iran|
| Silver|  IRI|  Iran|
| Bronze|  IRI|  Iran|
|   Gold|  IRI|  Iran|
| Silver|  IRI|  Iran|
| Bronze|  IRI|  Iran|
| Silver|  IRI|  Iran|
+-------+-----+------+
only showing top 20 rows