Clase 14: continuación con los datos¶
En esta clase vamos a continuar con el uso de pandas
. Veremos:
Consultas SQL
Qué es?
Select
Where
Join
Union
Update
Delete
Ejercicios
1. Repaso¶
Para el ejemplo de esta clase vamos a usar una pequeña base llamada tips
que tiene a disposición la librería pandas
.
total_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
5 | 25.29 | 4.71 | Male | No | Sun | Dinner | 4 |
6 | 8.77 | 2.00 | Male | No | Sun | Dinner | 2 |
7 | 26.88 | 3.12 | Male | No | Sun | Dinner | 4 |
8 | 15.04 | 1.96 | Male | No | Sun | Dinner | 2 |
9 | 14.78 | 3.23 | Male | No | Sun | Dinner | 2 |
Vamos a crear una función que nos permita visualizar información del DataFrame
#Declaramos la función y el nombre del input
def grafico1(DF):
#Definimos los datos a usar
data1 = DF[['total_bill', 'size']].groupby('size').mean()
plt.bar(data1.index, data1.total_bill)
plt.xlabel("Tamaño de la mesa")
plt.ylabel("Promedio de la cuenta")
#Llamamos la función y le damos el input
grafico1(tips)

#Declaramos la función y el nombre del input
def grafico2(DF):
#Definimos los datos
x = DF.total_bill
y = DF.tip
#Gráfico de puntos (scatter)
plt.scatter(x, y)
plt.xlabel("Total cuenta")
plt.ylabel("Propina")
#Gráfico de línea
m, b = np.polyfit(x, y, 1) #Sacar la pendiente y el intercepto de y(x)
plt.plot(x, m*x + b, color='r')
#Llamamos la función y le damos el input
grafico2(tips)

Y si la función la queremos con dos input?
#Declaramos la función y el nombre del input
def grafico2(x, y):
#Gráfico de puntos (scatter)
plt.scatter(x, y)
plt.xlabel("Total cuenta")
plt.ylabel("Propina")
#Gráfico de línea
m, b = np.polyfit(x, y, 1) #Sacar la pendiente y el intercepto de y(x)
plt.plot(x, m*x + b, color='r')
#Creamos las variables que vamos a usar como input
x = tips.total_bill
y = tips.tip
#Hacemos el gráfico
grafico2(x, y)

Si queremos guardar la diferencia entre las filas de una variable del set de datos, podemos por ejemplo usar un for
#Definimos la variable a utilizar
var = tips.total_bill
#Creamos la lista donde vamos a guardar los datos
lista = []
#Realizamos el lopp: desde el segundo valor hasta el último (1, n)
for i in range(1, len(var)):
lista.append(var[i]-var[i-1]) #Sacamos la diferencia
print(var[0:10])
print(lista[0:10])
Otra forma es usar la función diff
. El siguiente link muestra en detalle cómo usar la función:
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.diff.html
#si queremos sacar la diferencia de una variable definimos el DataFrame.nombre_variable.diff()
print(tips.total_bill.diff().head())
#Tambien podemos especificar los periodos para hacer la diferencia
print(tips.total_bill.diff(periods=3).head())
#Podemos cambiar el sentido de la diferencia (ascendente o descendente)
print(tips.total_bill.diff(periods=-3).head())
2. Consultas SQL¶
SQL (por su nombre en inglés) es un lenguaje de programación utilizado para trabajar con bases relacionales
. Este lenguaje nos permite recuperar de forma simple información de bases de datos donde tenemos bases que pueden estar relacionadas mediante alguna variable. Por ejemplo:
Podemos tener información de diferentes fuentes, planillas de costos, ingresos, compras, etc. y buscar vincular esta información para hacer análisis, presentar información o realizar cálculos específico.
El objetivo de esta clase no es SQL, sino la forma de trabajar este lenguaje. En python podemos usar pandas
para replicar el trabajo con bases de datos relacionales.
Select¶
El objetivo es seleccionar un set de información específico
total_bill | tip | smoker | time | |
---|---|---|---|---|
0 | 16.99 | 1.01 | No | Dinner |
1 | 10.34 | 1.66 | No | Dinner |
2 | 21.01 | 3.50 | No | Dinner |
3 | 23.68 | 3.31 | No | Dinner |
4 | 24.59 | 3.61 | No | Dinner |
Para agregar un nueva variable según un ratio podemos usar DataFrame.assign()
total_bill | tip | sex | smoker | day | time | size | tip_rate | |
---|---|---|---|---|---|---|---|---|
0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2 | 0.059447 |
1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3 | 0.160542 |
2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3 | 0.166587 |
3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2 | 0.139780 |
4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4 | 0.146808 |
Where¶
Usamos este tipo de consulta para seleccionar una información en específico, por ejemplo cuando la variable time
es igual a Diner
total_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
Podemos ver si se cumple una condición como verdadero/falso y podemos usar la función value_counts()
para ver cuántas veces se cumple o no
Luego, podemos revisar el DataFrame donde se cumpla la condición que establecimos previamente.
total_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
Podemos seleccionar más de una condición usando &
(and) or |
(or)
Por ejemplo, seleccionamos cuando time=Dinner y cuando tip>5.
total_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
23 | 39.42 | 7.58 | Male | No | Sat | Dinner | 4 |
44 | 30.40 | 5.60 | Male | No | Sun | Dinner | 4 |
47 | 32.40 | 6.00 | Male | No | Sun | Dinner | 4 |
52 | 34.81 | 5.20 | Female | No | Sun | Dinner | 4 |
59 | 48.27 | 6.73 | Male | No | Sat | Dinner | 4 |
116 | 29.93 | 5.07 | Male | No | Sun | Dinner | 4 |
155 | 29.85 | 5.14 | Female | No | Sun | Dinner | 5 |
170 | 50.81 | 10.00 | Male | Yes | Sat | Dinner | 3 |
172 | 7.25 | 5.15 | Male | Yes | Sun | Dinner | 2 |
181 | 23.33 | 5.65 | Male | Yes | Sun | Dinner | 2 |
183 | 23.17 | 6.50 | Male | Yes | Sun | Dinner | 4 |
211 | 25.89 | 5.16 | Male | Yes | Sat | Dinner | 4 |
212 | 48.33 | 9.00 | Male | No | Sat | Dinner | 4 |
214 | 28.17 | 6.50 | Female | Yes | Sat | Dinner | 3 |
239 | 29.03 | 5.92 | Male | No | Sat | Dinner | 3 |
total_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
59 | 48.27 | 6.73 | Male | No | Sat | Dinner | 4 |
125 | 29.80 | 4.20 | Female | No | Thur | Lunch | 6 |
141 | 34.30 | 6.70 | Male | No | Thur | Lunch | 6 |
142 | 41.19 | 5.00 | Male | No | Thur | Lunch | 5 |
143 | 27.05 | 5.00 | Female | No | Thur | Lunch | 6 |
155 | 29.85 | 5.14 | Female | No | Sun | Dinner | 5 |
156 | 48.17 | 5.00 | Male | No | Sun | Dinner | 6 |
170 | 50.81 | 10.00 | Male | Yes | Sat | Dinner | 3 |
182 | 45.35 | 3.50 | Male | Yes | Sun | Dinner | 3 |
185 | 20.69 | 5.00 | Male | No | Sun | Dinner | 5 |
187 | 30.46 | 2.00 | Male | Yes | Sun | Dinner | 5 |
212 | 48.33 | 9.00 | Male | No | Sat | Dinner | 4 |
216 | 28.15 | 3.00 | Male | Yes | Sat | Dinner | 5 |
Muchas veces los datos vienen con información vacía o nula. En pandas
existe el tipo NaN
que significa Not a Number
(valores faltantes). Para seleccionar este tipo de datos (o excluirlos) podemos usar isna()
(o notna()
).
Para ejemplificar lo anterio vamos a crear un pequeño dataframe con este tipo de datos con np.NaN
.
col1 | col2 | |
---|---|---|
0 | A | F |
1 | B | NaN |
2 | NaN | G |
3 | C | H |
4 | D | I |
Seleccionamos el dataframe cuando la columna 2 tiene valores del tipo NaN
O cuando la columna 1 no tiene valores del tipo NaN
Group by¶
Las clases anteriores vimos algunos ejemplos de como usar la función groupby(). Por ejemplo, si queremos agrupar por sexo y saber el número de tips podemos hacer lo siguiente
Una diferencia importante entre estos dos métodos (count() vs size()) es que el count() se aplica sobre todas las variables y no incluye los not null
, mientras que size() da el total. Si usamos el dataframe del ejemplo anterior:
Podemos hacer multiples operaciones usando la función agg()
. Por ejemplo podemos agrupar por día, y que realice el promedio ‘tip’, junto con la cantidad de días.
La sintaxis es DataFrame.groupby(“Variable a agrupar).agg({“variable1”:operacion, “variable2”:operacion})
tip | day | |
---|---|---|
day | ||
Fri | 2.734737 | 19 |
Sat | 2.993103 | 87 |
Sun | 3.255132 | 76 |
Thur | 2.771452 | 62 |
Para agrupar por mas de una variable usamos una lista dentro del groupby
y luego la operación que queremos con agg()
.
Join¶
Una función del tipo join
se utiliza para juntar bases de datos mediante alguna variable en común.
Los tipos de join más usados son:
Para nuestro ejemplo vamos a crear dos DataFrame que van a compartir informacion y que vamos a ir vinculando según los diferentes tipos de join.
Inner Join¶
Juntamos dos Bases usando la llave en ambas tablas. En nuestro ejemplo la llave (key) que se encuentra en ambas tablas corresponden a: B y D. Entonces vamos a excluir A, C y E.
Sin embargo, en la tabla 2 la llave D está dos veces, por lo que nuestra tabla final va a incluir este resultado la cantidad de veces que se encuentre en la tabla 1 y tabla 2.
Left outher join¶
Este tipo de consulta se usa cuando queremos mostrar toda la información de una tabla y sólo la información de la segunda tabla cuando se condicen las llaves
Right Join¶
Nos muestra todo lo de la tabla de la derecha y sólo los valores de la izquierda cuando coincide la llave.
Full Join¶
Cuando queremos mostrar todos los datos de ambos dataframe
Union¶
Usamos esta consulta cuando queremos agregar dos tablas o bases de datos.
Por ejemplo, si creamos dos DataFrames con ciudad y ranking en calidad de vida
Los podemos unir usando la función concat
ciudad | rank | |
---|---|---|
0 | Valdivia | 1 |
1 | Santiago | 2 |
2 | Valparaiso | 3 |
0 | Iquique | 5 |
1 | Puerto Montt | 4 |
2 | Valdivia | 1 |
Para eliminar los duplicados podemos usar drop_duplicates
Update¶
Cuando queremos actualizar una variable debemos definir una condición y un nuevo valor. Esto lo podemos hacer para variables numéricas o variables de texto. Para esto usamos la función loc
Delete¶
Para eliminar un valor también vamos a usar la función loc
. Vamos a definir una condición que no se cumple (!=
) y con ella excluir un valor en particular. Por ejemplo, podemos sacar de la tabla cuando la ciudad es Iquique.
3. Ejercicios¶
Seleccionar del dataframe nombre cuando es igual a Valentina. Guardar el id en una variable
id_valentina
.
Usando el dataframe de almuerzo agrupar por día=lunes y ver hora promedio de almuerzo.
hora | |
---|---|
dia | |
Lunes | 12.75 |
Graficar el promedio de hora de almuerzo por día. Usar un gráfico de barras.

Usando las funciones del tipo join ver:
¿Qué almorzó Juan en la semana?
¿A qué hora y qué almorzó Andrea el martes?
Crear dataframe
df_total
con las variables id, Nombre, Edad, dia, hora y almuerzo.
#Inner join: Almuerzo de juan
df = pd.merge(nombre, almuerzo, on="id", how="outer")
df_juan = df[["Nombre", "almuerzo"]][df.Nombre == "Juan"]
print(df_juan)
#Andrea
df_andrea = df[["Nombre", "almuerzo"]][(df.Nombre == "Andrea") & (df.dia=="Martes")]
print(df_andrea)
#Data Frame total
df_total = pd.merge(nombre, edad, on="id", how="outer")
df_total = pd.merge(df_total, almuerzo, on="id",how="outer")
print(df_total)
Nombre almuerzo
0 Juan pastel de papas
1 Juan ensalada
2 Juan garbanzos
Nombre almuerzo
4 Andrea NaN
Nombre id Edad dia hora almuerzo
0 Juan 1 10 Lunes 12 pastel de papas
1 Juan 1 10 Martes 14 ensalada
2 Juan 1 10 Miércoles 16 garbanzos
3 Andrea 2 25 Lunes 13 porotos
4 Andrea 2 25 Martes 14 NaN
5 Andrea 2 25 Miércoles 13 cazuela
6 Ramón 3 60 Lunes 14 lentejas
7 Ramón 3 60 Martes 13 asado
8 Ramón 3 60 Miércoles 14 NaN
9 Valentina 4 55 Lunes 12 pescado
10 Valentina 4 55 Martes 15 NaN
11 Valentina 4 55 Miércoles 14 NaN
¿Cuántas observaciones tiene el
df_total
?
¿Qué variables tienen NaN y cuántos NaN hay?
#Variables que tienen NaN
#Definimos una variable que evalúe si una variable tiene NaN -> print esta variable tiene NaN
def NA(df):
if df.Nombre.isna().any() == True: #Ocupamos la función any() para comparar cada valor de la variable igual a la condición
print("Nombre tiene NaN")
elif df.id.isna().any() == True:
print("id tiene NaN")
elif df.Edad.isna().any() == True:
print("Edad tiene NaN")
elif df.id.isna().any() == True:
print("id tiene NaN")
elif df.dia.isna().any() == True:
print("dia tiene NaN")
elif df.hora.isna().any() == True:
print("hora tiene NaN")
elif df.almuerzo.isna().any() == True:
print("almuerzo tiene NaN")
#Evaluamos la función
NA(df_total)
#Cuántos NaN?
#Sabemos que sólo almuerzo tiene NaN
print("La variable almuerzo tiene " + str(df_total[df_total["almuerzo"].isna()].id.count()) + " NaN." )
Crear un nuevo dataframe excluyendo los NaN