Curso de introducción a la programación con Python¶

    Autor: Luis Fernando Apáez Álvarez
    -Curso PyM-
    Clase 7 parte II: Más sobre NumPy y Pandas
    Fecha: 03 de Septiembre del 2022

Contenido¶

  • Librería NumPy (parte 2)
    • Más sobre filtros
    • Agregar y remover datos
    • Resumiendo datos
    • Operaciones vectorizadas
  • Librería Pandas (parte 2)
    • Ordenamientos
    • Filtros

En esta clase indagaremos sobre más conceptos dentro de las librerías NumPy y Pandas

Librería NumPy (parte 2) ¶


Más sobre filtros ¶

En la clase pasada vimos que podíamos realizar filtros sobre arrays utilizando máscaras booleanas. Retomenos dicha idea, para lo cual

In [1]:
# Importamos la libreria necesaria
import numpy as np

crearemos un array que represente en la primer columna un ID de estudiante y en la segunda la calificación final de éste

In [15]:
array1 = np.array([ [1, 10],
                    [2, 6],
                    [3, 7.5],
                    [4, 5],
                    [5, 9.2],
                    [6, 5.8] ])
print(array1)
[[ 1.  10. ]
 [ 2.   6. ]
 [ 3.   7.5]
 [ 4.   5. ]
 [ 5.   9.2]
 [ 6.   5.8]]

Lo que haremos ahora será filtrar el array1 para aquellos valores en la segunda columna que sean mayores iguales a 6 (es decir, obtendremos los estudiantes que aprobaron).

In [8]:
# Realizaremos un filtrado especifico sobre la segunda columna
#         seleccionamos| seleccio-| condi-
#         todas las    | namos la | ción
#         filas del    | segunda  |
#         array        | columna  |
mask = array1[:,         1]       >= 6

# Veamos el array filtrado
print(array1[mask])
[[ 1.  10. ]
 [ 2.   6. ]
 [ 3.   7.5]
 [ 5.   9.2]]

Donde al array dado:

$$ \left(\begin{array}{cc} 1 & 10 \\ 2 & 6\\ 3 & 7.5\\ 4 & 5\\ 5 & 9.2\\ 6 & 5.8 \end{array}\right) $$

al realizarle el filtro sobre la segunda columna con la condición dada obtenemos:

$$ \left(\begin{array}{cc} 1 & True \\ 2 & True\\ 3 & True\\ 4 & False\\ 5 & True\\ 6 & False \end{array}\right) \ \ \rightarrow \ \ \left(\begin{array}{cc} 1 & 10 \\ 2 & 6\\ 3 & 7.5\\ - & -\\ 5 & 9.2\\ - & - \end{array}\right) $$

De manera totalmente análoga podemos utilizar np.where() para realizar filtrados, siendo éste una alternativa de uso de las máscaras booleanas. Por ejemplo:

In [14]:
#                   condicion de filtrado
filtrado = np.where( array1[:, 1] >= 6 )

# indaguemos sobre nuestro filtro
print(filtrado)
(array([0, 1, 2, 4], dtype=int64),)

El método np.where() devuele una tupla de arrays, donde en este caso el array que se devuelve hace alusión a los índices de las filas que cumplen con la condición que específicamos

$$ \begin{array}{cc} \textrm{Índice fila}\\ 0 \\ 1\\ 2 \\ -\\ 4\\ - \end{array} \left(\begin{array}{cc} & \\ 1 & 10 \\ 2 & 6\\ 3 & 7.5\\ - & -\\ 5 & 9.2\\ - & - \end{array}\right) $$
In [17]:
# De tal modo obtenemos el array filtrado
print(array1[filtrado])
[[ 1.  10. ]
 [ 2.   6. ]
 [ 3.   7.5]
 [ 5.   9.2]]

Luego, dentro de la tupla de arrays que puede retornar np.where() están otros arrays de índices para el caso en el que estemos trabajando con arrays multidimensionales

np1.PNG

donde se nos puede regresar, por ejemplo para un array de 3 dimensiones, un array correspondiente a los índices fila y otro para los índices de profundidad. Puedes ver a los índices de profundidad, para este caso, como el índice del array de dos dimensiones dentro del array de tres dimensiones

np2.PNG

Por ejemplo, consideremos que tenemos las calificaciones de los estudiantes de tres grupos (Grupo A, B y C):

In [3]:
# Array de tres dimensiones, de 6 filas
# por 2 columnas:
array2 = np.array([ [[1, 10],
                    [2, 6],
                    [3, 7.5],    # Grupo A
                    [4, 5],
                    [5, 9.2],
                    [6, 5.8]],
                    [[1, 4],
                    [2, 6.8],
                    [3, 7],    # Grupo B
                    [4, 9.5],
                    [5, 10],
                    [6, 3]],
                    [[1, 7],
                    [2, 5],
                    [3, 5.3],    # Grupo C
                    [4, 8],
                    [5, 7.2],
                    [6, 9.8]] ])
print(array2)
[[[ 1.  10. ]
  [ 2.   6. ]
  [ 3.   7.5]
  [ 4.   5. ]
  [ 5.   9.2]
  [ 6.   5.8]]

 [[ 1.   4. ]
  [ 2.   6.8]
  [ 3.   7. ]
  [ 4.   9.5]
  [ 5.  10. ]
  [ 6.   3. ]]

 [[ 1.   7. ]
  [ 2.   5. ]
  [ 3.   5.3]
  [ 4.   8. ]
  [ 5.   7.2]
  [ 6.   9.8]]]

y queremos filtrar a aquellos (de los tres grupos) que hayan obtenido una calificación mayor a 7, esto es, de todas las profundidades (de todos los arrays 2D o de todos los grupos de estudiantes) queremos, de todas las filas, aquellos que tengan una calificación mayor a 7, donde la condición que estamos imponiendo es sobre las columnas. Así:

In [43]:
#                        -condicion de filtrado-
#                       profundidad|filas|columnas
filtrado = np.where( array2[:,       :,     1]    > 7 )

# indaguemos sobre nuestro filtro
filtrado
Out[43]:
(array([0, 0, 0, 1, 1, 2, 2, 2], dtype=int64),
 array([0, 2, 4, 3, 4, 3, 4, 5], dtype=int64))

De lo anterior tenemos dos arrays de índices, el primero corresponde a los índices de profundidad y el segundo a los índices de fila

np3.PNG

$$ \left(\begin{array}{cc} \textrm{Profundidad 0: Grupo A}\\ \textrm{Índice fila}\\ 0 \\ -\\ 2 \\ -\\ 4\\ - \end{array} \left(\begin{array}{cc} & \\ \textrm{ID} & \textrm{Cal} \\ 1 & 10 \\ - & -\\ 3 & 7.5\\ - & -\\ 5 & 9.2\\ - & - \end{array}\right)\right),\ \ \ \ \ \ \left(\begin{array}{cc} \textrm{Profundidad 1: Grupo B}\\ \textrm{Índice fila}\\ - \\ -\\ - \\ 3\\ 4\\ - \end{array} \left(\begin{array}{cc} & \\ \textrm{ID} & \textrm{Cal} \\ - & - \\ - & -\\ - & -\\ 4 & 9.5\\ 5 & 10\\ - & - \end{array}\right)\right) $$
$$ \left(\begin{array}{cc} \textrm{Profundidad 2: Grupo C}\\ \textrm{Índice fila}\\ - \\ -\\ - \\ 3\\ 4\\ 5 \end{array} \left(\begin{array}{cc} & \\ \textrm{ID} & \textrm{Cal} \\ - & - \\ - & -\\ - & -\\ 4 & 8\\ 5 & 7.2\\ 6 & 9.8 \end{array}\right)\right) $$

De tal manera, cuando obtenemos el array filtrado veremos

In [44]:
print(array2[filtrado])
[[ 1.  10. ]
 [ 3.   7.5]
 [ 5.   9.2]
 [ 4.   9.5]
 [ 5.  10. ]
 [ 4.   8. ]
 [ 5.   7.2]
 [ 6.   9.8]]

np4.PNG

los ID y la calificación de aquellos estudiantes (de los tres grupos) que sacaron más de 7.

Ahora, el verdadero poder de np.where() es que podemos extraer elementos de un array que cumplen cierta condición, como vimos antes donde extrajimos los valores de los cuales la segunda columna (axis1) fuera mayor a 7, y reemplazarlos por algún otro valor; asimismo, para los elementos del array que no cumplen con dicha condición, podemos especificar cambiar su valor.

Para ver de una manera más intuitiva cómo podemos implemenatar lo anterior, consideremos ahora el siguiente array

In [10]:
# Creamos un array de 9 filas por 9 columnas lleno de 
# puros 5
array3 = np.full((9,9), 5)
print(array3)
print()

# Creamos un array identidad de la misma dimension
# que array3
array4 = np.identity(9)
print(array4)
print()

# Sumamos dichos arrays
array_sum = array3 + array4
print(array_sum)
[[5 5 5 5 5 5 5 5 5]
 [5 5 5 5 5 5 5 5 5]
 [5 5 5 5 5 5 5 5 5]
 [5 5 5 5 5 5 5 5 5]
 [5 5 5 5 5 5 5 5 5]
 [5 5 5 5 5 5 5 5 5]
 [5 5 5 5 5 5 5 5 5]
 [5 5 5 5 5 5 5 5 5]
 [5 5 5 5 5 5 5 5 5]]

[[1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 1. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 1. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 1.]]

[[6. 5. 5. 5. 5. 5. 5. 5. 5.]
 [5. 6. 5. 5. 5. 5. 5. 5. 5.]
 [5. 5. 6. 5. 5. 5. 5. 5. 5.]
 [5. 5. 5. 6. 5. 5. 5. 5. 5.]
 [5. 5. 5. 5. 6. 5. 5. 5. 5.]
 [5. 5. 5. 5. 5. 6. 5. 5. 5.]
 [5. 5. 5. 5. 5. 5. 6. 5. 5.]
 [5. 5. 5. 5. 5. 5. 5. 6. 5.]
 [5. 5. 5. 5. 5. 5. 5. 5. 6.]]

donde en este último array todos los valores son 5, menos los valores de la diagonal (cuyos valores son el 6): Así, lo que haremos será utilizar np.where, donde la condición que implementaremos será array_sum == 6 para que se consideren todas las entradas del array array_sum que tengan asociado el valor de 6; para aquellos valores que hacen verdadera la condición anterior les asignaremos el valor de 0, es decir, cambiaremos los 6 de la diagonal al 0 y para aquellos valores que no hacen verdadera la condición les asignaremos el valor de 1, es decir, cambiaremos todos los 5 por 0. Esto es.

In [14]:
#                          condicion de |valor que     | valor que
#                          filtrado     |se sustituye  | se sustituye
#                                       |en caso de que| en caso de que
#                                       |la condicion  | la condicion
#                                       |sea verdadera | sea falso
filtrado_cambio = np.where(array_sum == 6,  0,         1)
# Veamos el array anterior
print(filtrado_cambio)
[[0 1 1 1 1 1 1 1 1]
 [1 0 1 1 1 1 1 1 1]
 [1 1 0 1 1 1 1 1 1]
 [1 1 1 0 1 1 1 1 1]
 [1 1 1 1 0 1 1 1 1]
 [1 1 1 1 1 0 1 1 1]
 [1 1 1 1 1 1 0 1 1]
 [1 1 1 1 1 1 1 0 1]
 [1 1 1 1 1 1 1 1 0]]

donde todos los elementos de la diagonal son 0 y los valores fuera de la diagonal son 1. Otro ejemplo

In [16]:
# Consideremos el array de entradas aleatorias
# de 5 filas por 5 columnas
array5 = np.random.random((5,5))
array5
Out[16]:
array([[0.40452917, 0.52698261, 0.27268398, 0.79717802, 0.94071403],
       [0.43568085, 0.6079667 , 0.80532758, 0.56770115, 0.39560365],
       [0.89077405, 0.88992148, 0.30093317, 0.89558492, 0.8672514 ],
       [0.8222073 , 0.71272785, 0.14634323, 0.88894845, 0.35668384],
       [0.2888239 , 0.14549937, 0.69602177, 0.31685999, 0.02948246]])

luego, cambiaremos los valores que son menores a 0.5 para colocar en su lugar el número 0 y cambiaremos los valores que son mayores o iguales a 0.5 para colocar en su lugar el número 1:

In [17]:
#                          condicion de  |valor que     | valor que
#                          filtrado      |se sustituye  | se sustituye
#                                        |en caso de que| en caso de que
#                                        |la condicion  | la condicion
#                                        |sea verdadera | sea falso
filtrado_cambio2 = np.where(array5 < 0.5,   0,             1)
filtrado_cambio2
Out[17]:
array([[0, 1, 0, 1, 1],
       [0, 1, 1, 1, 0],
       [1, 1, 0, 1, 1],
       [1, 1, 0, 1, 0],
       [0, 0, 1, 0, 0]])

Si observamos con atención vemos que, prácticamente, lo que hicimos fue realizar un redondeo de los números de las entradas del array array5.

El método round() aplicado a un array redondeará cada uno de los valores de las entradas de dicho array, por ejemplo

In [20]:
print('Array original:')
print(array5)
print()

print('Array redondeado con el método round():')
print(array5.round())
print()

print('Array que redondeamos mediante una condición:')
print(filtrado_cambio2)
Array original:
[[0.40452917 0.52698261 0.27268398 0.79717802 0.94071403]
 [0.43568085 0.6079667  0.80532758 0.56770115 0.39560365]
 [0.89077405 0.88992148 0.30093317 0.89558492 0.8672514 ]
 [0.8222073  0.71272785 0.14634323 0.88894845 0.35668384]
 [0.2888239  0.14549937 0.69602177 0.31685999 0.02948246]]

Array redondeado con el método round():
[[0. 1. 0. 1. 1.]
 [0. 1. 1. 1. 0.]
 [1. 1. 0. 1. 1.]
 [1. 1. 0. 1. 0.]
 [0. 0. 1. 0. 0.]]

Array que redondeamos mediante una condición:
[[0 1 0 1 1]
 [0 1 1 1 0]
 [1 1 0 1 1]
 [1 1 0 1 0]
 [0 0 1 0 0]]

Agregar y remover datos ¶

Comenzaremos primero uniendo (o concatenando) dos arrays y lo haremos de manera horizontal

npy1.PNG

de modo que es importante, en este caso, que los arrays tengan el mismo número de filas. Así

In [22]:
# Creamos dos arrays con el mismo numero de filas
array1 = np.zeros((3,3))
array2 = np.random.random((3,2))

# Imprimimos los arrays anteriores
print(array1)
print()
print(array2)
[[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]
[[0.60525993 0.7719087 ]
 [0.49584214 0.81364018]
 [0.55926231 0.54962566]]

Para concatenar dos arrays de manera horizontal utilizaremos el método np.concatenate(), donde como parémetro debemos asignar una tupla con los arrays que queremos unir. Por ejemplo, para unir los arrays array1 y array2 horizontalmente escribimos

In [24]:
# array concatenado por columnas
array_concat = np.concatenate((array1, array2), axis=1)
array_concat
Out[24]:
array([[0.        , 0.        , 0.        , 0.60525993, 0.7719087 ],
       [0.        , 0.        , 0.        , 0.49584214, 0.81364018],
       [0.        , 0.        , 0.        , 0.55926231, 0.54962566]])

que al especificar axis=1 estamos indicando que la unión la haremos por columnas. En otras palabras, la unión horizontal no es más que unir las columnas de ambos arrays. Recordemos que, para realizar la unión horizontal, los arrays deben tener el mismo número de filas. Si queremos ahora realizar una unión vertical de arrays, es decir, unir las filas de dos arrays en uno solo

npy2.PNG

los arrays deben tener el mismo número de columnas. Y para ello configuraremos axis=0 para especificar que la unión ahora es por filas:

In [25]:
# Creamos dos arrays con el mismo numero de columnas
array1 = np.ones((3,3))
array2 = np.random.random((2,3))

# Imprimimos los arrays anteriores
print(array1)
print()
print(array2)
[[1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]

[[0.31947663 0.55342233 0.87498701]
 [0.59711402 0.99892375 0.20750137]]
In [26]:
# array concatenado por filas
array_concat = np.concatenate((array1, array2), axis=0)
array_concat
Out[26]:
array([[1.        , 1.        , 1.        ],
       [1.        , 1.        , 1.        ],
       [1.        , 1.        , 1.        ],
       [0.31947663, 0.55342233, 0.87498701],
       [0.59711402, 0.99892375, 0.20750137]])

De nuevo, recuerda que las uniones que hemos visto antes sólo se pueden aplicar si las formas de los arrays involucrados son compatibles (como se mencionó antes).

Otro ejemplo, concatenemos dos arrays, donde uno de ellos tiene solo una columna

In [31]:
# Creamos dos arrays con el mismo numero de filas
array1 = np.zeros((3,3))
array2 = np.array([1,
                   2,
                   3])

# Imprimimos los arrays anteriores
print(array1)
print()
print(array2)
[[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]

[1 2 3]

npy3.PNG

Pero, si intentamos concatenarlos obtendremos un error:

In [30]:
# array concatenado por columnas
array_concat = np.concatenate((array1, array2), axis=1)
array_concat
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [30], in <cell line: 2>()
      1 # array concatenado por filas
----> 2 array_concat = np.concatenate((array1, array2), axis=0)
      3 array_concat

File <__array_function__ internals>:180, in concatenate(*args, **kwargs)

ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)

Podemos entender el error anterior si observamos las formas de ambos arrays:

In [29]:
print(array1.shape)
print(array2.shape)
(3, 3)
(3,)

Pues array2 es de una sola dimensión por lo que no tiene asociado un valor para las columnas, es decir, prácticamente se puede decir que array2 no tiene columnas, entonces el error radica en intentar unir dos arrays por columnas, donde uno de dichos arrays no tiene columnas. Para arreglar el problema anterior escribimos

In [34]:
#        array de 3 filas por 1 columna
array2 = array2.reshape((3,1)) 
array2
Out[34]:
array([[1],
       [2],
       [3]])

Y ahora sí podemos unir los arrays

In [36]:
# array concatenado por columnas
array_concat = np.concatenate((array1, array2), axis=1)
array_concat
Out[36]:
array([[0., 0., 0., 1.],
       [0., 0., 0., 2.],
       [0., 0., 0., 3.]])

Por otro lado, podemos eliminar filas y/o columnas completas de un array mediante el método np.delete(), donde tendremos tres parámetros dentro de este método:

  • Array desde el cual se hará la eliminación
  • Segmento, índice o array de índices que se eliminará
  • Manera de eliminar, ya sea por fila (axis 0) o por columna (axis 1).

Por ejemplo, del array array_concat podemos eliminar completa la fila de índice 1 (la cual sería [0., 0., 0., 2.]):

In [37]:
#                    fila a  | forma de eliminacion
#                    eliminar| por filas
np.delete(array_concat, 1,    axis=0)
Out[37]:
array([[0., 0., 0., 1.],
       [0., 0., 0., 3.]])
In [38]:
# O tambien eliminar la columna de indice 3
# del array original array_concat
np.delete(array_concat, 3, axis=1)
Out[38]:
array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])

Si no especificamos el axis, entonces nuestra array será aplanado en un array de una dimensión. Luego, si consideramos por ejemplo np.delete(array_concat, 3) (donde omitimos el parámetro para especificar el axis), entonces el array

array([[0., 0., 0., 1.],
       [0., 0., 0., 2.],
       [0., 0., 0., 3.]])

será aplanado al array

array([0., 0., 0., 1., 0., 0., 0., 2., 0., 0., 0., 3.])

y como especificamos el número 3 en np.delete(array_concat, 3), entonces se eliminará el elemento de índice 3 del array aplanado. El elemento en la posición 3 del array aplanado es el número 1 por lo cual al escribir

In [40]:
#                    fila a  | forma de eliminacion
#                    eliminar| por filas
np.delete(array_concat, 3)
Out[40]:
array([0., 0., 0., 0., 0., 0., 2., 0., 0., 0., 3.])

ya no vemos el número 1 dentro de dicho array.

Resumiendo datos ¶

En la clase pasada abordamos ya algunas formas de obtener información relevante sobre nuestros arrays. Por ejemplo

In [44]:
# Dado el array
array1 = np.random.random((4,3))
array1
Out[44]:
array([[0.27696186, 0.27019666, 0.29809603],
       [0.17344493, 0.59770748, 0.03401392],
       [0.25985741, 0.69146663, 0.4815255 ],
       [0.97097828, 0.61004301, 0.13910545]])
In [47]:
# Obtenemos el valor maximo almacenado dentro de
# nuestro array
print(f'Valor máximo dentro de array1: {array1.max()}')
print()

# Obtenemos el valor minimo almacenado dentro de
# nuestro array
print(f'Valor mínimo dentro de array1: {array1.min()}')
Valor máximo dentro de array1: 0.9709782760399337

Valor mínimo dentro de array1: 0.034013922802112906

Asimismo, podemos obtener la suma de todas las entradas de nuestro array

In [48]:
# Obtenemos la suma de todos los valores
# almacenados en nuestro array
print(f'Suma de todos los valores en array1: {array1.sum()}')
Suma de todos los valores en array1: 4.803397158051567

o también el promedio de los valores almacenados en nuestro array

In [49]:
print(f'Promedio de los valores en array1: {array1.mean()}')
Promedio de los valores en array1: 0.4002830965042972

De manera más particular, por ejemplo, podemos obtener la suma de todos los valores de cada columna:

In [50]:
# Para sumar por columna configuramos axis=0
array1.sum(axis=0)
Out[50]:
array([1.68124247, 2.16941379, 0.9527409 ])

O también podemos sumar todos los valores de cada fila

In [51]:
# Para sumar por fila configuramos axis=1
array1.sum(axis=1)
Out[51]:
array([0.84525456, 0.80516633, 1.43284954, 1.72012673])

npy5.PNG


Notemos de la suma por fila que hicimos antes, que el resultado nos gustaría verlo como un array vertical (como se muestra en la imagen) y no uno horizontal como el que obtuvimos (array([0.84525456, 0.80516633, 1.43284954, 1.72012673])). En este caso, para que se respete la forma del array escribimos

In [52]:
# Para sumar por fila configuramos axis=1
# Para que se respete la forma 
# escribimos keepdims=true
array1.sum(axis=1, keepdims=True)
Out[52]:
array([[0.84525456],
       [0.80516633],
       [1.43284954],
       [1.72012673]])

Operaciones vectorizadas ¶

Las operaciones vectorizadas no son otra cosa más que las operaciones entrada a entrada que efectuabamos entre los arrays. Por ejemplo, podemos sumar cada entrada de un array con un número dado

In [53]:
# Creamos un array
array1 = np.full((2,4), 5)
array1
Out[53]:
array([[5, 5, 5, 5],
       [5, 5, 5, 5]])
In [54]:
# sumamos el array anterior con el numero 5
array1 + 5
Out[54]:
array([[10, 10, 10, 10],
       [10, 10, 10, 10]])

donde se ha operado de la siguiente manera:

$$ \left(\begin{array}{cccc} 5 & 5 & 5 & 5\\ 5 & 5 & 5 & 5 \end{array}\right) + 5 = \left(\begin{array}{cccc} 5+5 & 5+5 & 5+5 & 5+5\\ 5+5 & 5+5 & 5+5 & 5+5 \end{array}\right) = \left(\begin{array}{cccc} 10 & 10 & 10 & 10 \\ 10 & 10 & 10 & 10 \end{array}\right) $$

Otros ejemplos que bien conocemos son los siguientes:

In [56]:
# Creamos otro array de la MISMA DIMENSION
# que el array1
array2 = np.random.random(array1.shape)
array2
Out[56]:
array([[0.82826947, 0.29250252, 0.52894471, 0.58304645],
       [0.13864003, 0.07804048, 0.10649987, 0.2055587 ]])
In [57]:
# Los multiplicamos entrada a entrada
array1 * array2
Out[57]:
array([[4.14134734, 1.46251258, 2.64472354, 2.91523227],
       [0.69320017, 0.39020242, 0.53249937, 1.02779349]])
In [58]:
# Los sumamos entradada a entrada
array1 + array2
Out[58]:
array([[5.82826947, 5.29250252, 5.52894471, 5.58304645],
       [5.13864003, 5.07804048, 5.10649987, 5.2055587 ]])

etcétera. Cabe resaltar que las operaciones entre dos (o más) arrays se pueden efectuar siempre y cuando éstos tengan la misma forma.

Pero, en realidad, podemos realizar operaciones entre arrays aún cuando éstos no sean de la misma forma. Por ejemplo, cuando realizamos la operación array1 + 5 y obtuvimos

array([[10, 10, 10, 10],
       [10, 10, 10, 10]])

lo que en realidad pasó fue que se creó internamente un array de la misma dimensión de array1 donde todas sus entradas tenía el valor de 5. Esto es:

npy6.PNG

Así, podemos generalizar lo anterior para cualquier par (o más) de arrays, donde necesitaremos que al menos un valor de la forma (shape) coincida en ambos (o más) arrays, esto es, que los arrays coincidan en el número de filas, o bien, que los arrays coincidan en el número de columnas

Por ejemplo:

In [63]:
print(array1)
print(array1.shape)
print()

# Creamos otro array
array2 = np.array([1, 2]).reshape((2,1))
print(array2)
print(array2.shape)
[[5 5 5 5]
 [5 5 5 5]]
(2, 4)

[[1]
 [2]]
(2, 1)

Vemos que ambos arrays coinciden en el número de filas, de modo que podemos sumar dichos arrays:

In [64]:
array1 + array2
Out[64]:
array([[6, 6, 6, 6],
       [7, 7, 7, 7]])

de donde ocurrió:

NPY7.PNG

que al array $$ \left(\begin{array}{c} 1 \\ 2 \end{array}\right) \hspace{2.5cm} (\star) $$

le aumentamos 3 columnas para que tuviera la misma forma que el array array1, y los valores que colocamos en esas nuevas columnas son exactamente las mismas que en $(\star)$, es decir, se creó internamente la matriz:

$$ \left(\begin{array}{cccc} 1 & 1 & 1 & 1\\ 2 & 2 & 2 & 2 \end{array}\right) $$

para que se pudieran operar ambos arrays.

Podemos observar otro ejemplo donde ahora los arrays tienen el mismo número de filas

In [72]:
array1 = np.array([2])
print(array1)
print(array1.shape)
print()

# Creamos otro array
array2 = np.array([1, 2]).reshape((2,1))
print(array2)
print(array2.shape)
[2]
(1,)

[[1]
 [2]]
(2, 1)
In [73]:
# Multiplicamos ambos arrays
array1 * array2
Out[73]:
array([[2],
       [4]])

Otro ejemplo

In [74]:
array1 = np.array([[1,2,3,4],
                   [5,7,8,9]])
print(array1.shape)
print()

# Creamos otro array
array2 = np.array([3,3,3,3])
array2 = array2.reshape((1,4))
print(array2.shape)
(2, 4)

(1, 4)
In [75]:
# Multiplicamos los arrays anteriores
array1 * array2
Out[75]:
array([[ 3,  6,  9, 12],
       [15, 21, 24, 27]])

Librería Pandas (parte 2) ¶

Ordenamientos ¶

Para trabajar en esta sección utilizaremos una base de datos sobre una encuesta realizada a estudiantes sobre un taller de matemáticas.

Así, comenzamos por importador los datos y almacenarlos en un dataframe:

In [5]:
# Importamos pandas
import pandas as pd
# Creamos el dataframe descrito anteriormente
df = pd.read_csv('https://cursopypagina.github.io/CursoPy/Encuestas.csv')
# Accedemos a las primeras 5 filas
df.head()
Out[5]:
Unnamed: 0 Marca temporal Dirección de correo electrónico Escribe el nombre del taller El lenguaje de los taller fue adecuado Se distinguió los objetivos del taller Fueron claras las instrucciones de los talleres ¿Qué tan ameno te pareció el taller? Los talleres te motivaron a seguir indagando en el tema Si tienes comentarios y/o sugerencias acerca de los talleres son bienvenidos. El lenguaje de las secuencias didácticas te pareció apropiado Se distinguió los objetivos de las secuencias didácticas Fueron claros los conceptos que se formalizaron en las secuencias didácticas ¿Qué tan complicado te pareció la formalización de los conceptos en las secuencias didácticas? ¿Qué tan apropiado fue introducir los conceptos formales a partir de los talleres? Si tienes comentarios y/o sugerencias son bienvenidos El lenguaje de los talleres fue adecuado Se distinguieron los objetivos del taller
0 0 21/07/2022 9:16:50 NaN Serpientes estocásticas y escaleras aleatorias 1.0 1.0 1 1 2 Sería bueno si pudieran sugerir bibliografía ú... Mucho Mucho Mucho Poco Poco . NaN NaN
1 1 21/07/2022 9:18:07 NaN Serpientes estocásticas y escaleras aleatorias 1.0 1.0 2 1 1 En general el taller fue ameno, la actividad d... Mucho Mucho Mucho Mucho Mucho No tengo mucho que agregar, me pareció bastant... NaN NaN
2 2 21/07/2022 9:19:09 NaN Serpientes estocásticas y escaleras aleatorias 5.0 5.0 5 5 4 No, fue agradable Mucho Mucho Mucho Mucho Mucho . NaN NaN
3 3 21/07/2022 9:20:11 NaN Serpientes estocásticas y escaleras aleatorias 1.0 1.0 1 1 1 La explicación del tema fue breve y sencillo a... Mucho Mucho Mucho Poco Mucho El taller fue mucho de mi agrado NaN NaN
4 4 21/07/2022 9:20:18 NaN Serpientes estocásticas y escaleras aleatorias 1.0 1.0 1 1 1 Me gusto mucho el juego de las serpientes esto... Mucho Mucho Mucho Poco Mucho Me gustó la parte didáctica del taller y los t... NaN NaN

donde cada fila representa a un estudiante que contestó la encuesta.

Ahora bien, en la columna El lenguaje de los taller fue adecuado el estudiante colocará 1 si el lenguaje del taller impartido fue muy adecuado, y colocará 5 si el lenguaje fue muy poco adecuado. Así, tendría sentido, por ejemplo, ordenar nuestro dataframe en orden ascendente de acuerdo a esa columna. Antes de ello indaguemos en los nombres de las columnas de nuestro dataframe

In [7]:
df.columns
Out[7]:
Index(['Unnamed: 0', 'Marca temporal', 'Dirección de correo electrónico',
       'Escribe el nombre del taller ',
       'El lenguaje de los taller fue adecuado ',
       'Se distinguió los objetivos del taller',
       'Fueron claras las instrucciones de los talleres',
       '¿Qué tan ameno te pareció el taller?',
       'Los talleres te motivaron a seguir indagando en el tema',
       'Si tienes comentarios y/o sugerencias acerca de los talleres son bienvenidos.',
       'El lenguaje de las secuencias didácticas te pareció apropiado',
       'Se distinguió los objetivos de las secuencias didácticas',
       'Fueron claros los conceptos que se formalizaron en las secuencias didácticas',
       '¿Qué tan complicado te pareció la formalización de los conceptos en las secuencias didácticas?',
       '¿Qué tan apropiado fue introducir los conceptos formales a partir de los talleres?',
       'Si tienes comentarios y/o sugerencias son bienvenidos',
       'El lenguaje de los talleres fue adecuado ',
       'Se distinguieron los objetivos del taller'],
      dtype='object')

vemos que en realidad el nombre de la columna que nos interesa es 'El lenguaje de los taller fue adecuado ' y tiene un espacio en blanco al final, además está mal redactado el nombre de dicha columna. Entonces lo que haremos será cambiar el nombre de dicha columna, para lo cual

In [21]:
# Creamos una lista que almacene el nombre de las columnas
# de nuestro dataframe
name_columns = list(df.columns)

# Veamos dicha lista
print(name_columns)
print()

# Cambiamos el elemento del indice 4
#                Nuevo nombre de la columna de interes
name_columns[4] = 'El lenguaje de los talleres fue adecuado'

# Vemos de nuevo la lista
print(name_columns)
['Unnamed: 0', 'Marca temporal', 'Dirección de correo electrónico', 'Escribe el nombre del taller ', 'El lenguaje de los talleres fue adecuado', 'Se distinguió los objetivos del taller', 'Fueron claras las instrucciones de los talleres', '¿Qué tan ameno te pareció el taller?', 'Los talleres te motivaron a seguir indagando en el tema', 'Si tienes comentarios y/o sugerencias acerca de los talleres son bienvenidos.', 'El lenguaje de las secuencias didácticas te pareció apropiado', 'Se distinguió los objetivos de las secuencias didácticas', 'Fueron claros los conceptos que se formalizaron en las secuencias didácticas', '¿Qué tan complicado te pareció la formalización de los conceptos en las secuencias didácticas?', '¿Qué tan apropiado fue introducir los conceptos formales a partir de los talleres?', 'Si tienes comentarios y/o sugerencias son bienvenidos', 'El lenguaje de los talleres fue adecuado ', 'Se distinguieron los objetivos del taller']

['Unnamed: 0', 'Marca temporal', 'Dirección de correo electrónico', 'Escribe el nombre del taller ', 'El lenguaje de los talleres fue adecuado', 'Se distinguió los objetivos del taller', 'Fueron claras las instrucciones de los talleres', '¿Qué tan ameno te pareció el taller?', 'Los talleres te motivaron a seguir indagando en el tema', 'Si tienes comentarios y/o sugerencias acerca de los talleres son bienvenidos.', 'El lenguaje de las secuencias didácticas te pareció apropiado', 'Se distinguió los objetivos de las secuencias didácticas', 'Fueron claros los conceptos que se formalizaron en las secuencias didácticas', '¿Qué tan complicado te pareció la formalización de los conceptos en las secuencias didácticas?', '¿Qué tan apropiado fue introducir los conceptos formales a partir de los talleres?', 'Si tienes comentarios y/o sugerencias son bienvenidos', 'El lenguaje de los talleres fue adecuado ', 'Se distinguieron los objetivos del taller']

Después, configuraremos la lista creada antes como los nuevos nombres de las columnas de nuestro dataframe

In [22]:
# Accedemos a| asignamos un 
# los nombres| nuevo nombre
# de las     | a nuestras 
# columnas   | columnas
df.columns =  name_columns
# Veamos los cambios
df.columns
Out[22]:
Index(['Unnamed: 0', 'Marca temporal', 'Dirección de correo electrónico',
       'Escribe el nombre del taller ',
       'El lenguaje de los talleres fue adecuado',
       'Se distinguió los objetivos del taller',
       'Fueron claras las instrucciones de los talleres',
       '¿Qué tan ameno te pareció el taller?',
       'Los talleres te motivaron a seguir indagando en el tema',
       'Si tienes comentarios y/o sugerencias acerca de los talleres son bienvenidos.',
       'El lenguaje de las secuencias didácticas te pareció apropiado',
       'Se distinguió los objetivos de las secuencias didácticas',
       'Fueron claros los conceptos que se formalizaron en las secuencias didácticas',
       '¿Qué tan complicado te pareció la formalización de los conceptos en las secuencias didácticas?',
       '¿Qué tan apropiado fue introducir los conceptos formales a partir de los talleres?',
       'Si tienes comentarios y/o sugerencias son bienvenidos',
       'El lenguaje de los talleres fue adecuado ',
       'Se distinguieron los objetivos del taller'],
      dtype='object')

Así, colocamos un mejor nombre a la columna en cuestión respecto al nombre que tenía antes. De hecho, podríamos hacer lo mismo si quisieramos modificar el nombre de cualquier otra columna.

Continuando, si quieremos ordenar nuestro dataframe de acuerdo a una columna, utilizamos el método sort_values(), donde como parámetro va el nombre de la columna base para el ordenamiento:

In [23]:
# Vemos las primeras filas del dataframe ordenado
df.sort_values('El lenguaje de los talleres fue adecuado').head()
Out[23]:
Unnamed: 0 Marca temporal Dirección de correo electrónico Escribe el nombre del taller El lenguaje de los talleres fue adecuado Se distinguió los objetivos del taller Fueron claras las instrucciones de los talleres ¿Qué tan ameno te pareció el taller? Los talleres te motivaron a seguir indagando en el tema Si tienes comentarios y/o sugerencias acerca de los talleres son bienvenidos. El lenguaje de las secuencias didácticas te pareció apropiado Se distinguió los objetivos de las secuencias didácticas Fueron claros los conceptos que se formalizaron en las secuencias didácticas ¿Qué tan complicado te pareció la formalización de los conceptos en las secuencias didácticas? ¿Qué tan apropiado fue introducir los conceptos formales a partir de los talleres? Si tienes comentarios y/o sugerencias son bienvenidos El lenguaje de los talleres fue adecuado Se distinguieron los objetivos del taller
0 0 21/07/2022 9:16:50 NaN Serpientes estocásticas y escaleras aleatorias 1.0 1.0 1 1 2 Sería bueno si pudieran sugerir bibliografía ú... Mucho Mucho Mucho Poco Poco . NaN NaN
105 14 21/07/2022 9:57:18 NaN ¿Leonardo DiCaprio es perfecto? 1.0 1.0 1 1 1 Me pareció un taller muy interesante y útil. Mucho Mucho Mucho Poco Mucho Ninguno NaN NaN
102 11 21/07/2022 9:14:38 NaN ¿Leonardo Di caprio es perfecto? 1.0 2.0 1 1 2 Fue un taller interesante, toco temas que sola... Mucho Mucho Mucho Poco Mucho Los materiales o temas ocupados a lo largo del... NaN NaN
101 10 21/07/2022 9:13:03 NaN ¿Leonardo DiCaprio es perfecto? 1.0 1.0 1 1 1 Me gustó mucho el taller, explicaron todo muy ... Mucho Mucho Mucho Poco Mucho Las presentaciones fueron muy claras y por lo ... NaN NaN
99 8 21/07/2022 9:12:54 NaN ¿Leonardo Di Caprio es perfecto? 1.0 1.0 1 1 1 Me agradó la disposición de los instructores d... Mucho Mucho Mucho Poco Mucho Me gustó que la secuencia didactica fue muy in... NaN NaN
In [28]:
# Veamos unas filas en especifico donde podemos ver de manera
# mas visual el ordenamiento que hicimos
df.sort_values('El lenguaje de los talleres fue adecuado')[114:130]
Out[28]:
Unnamed: 0 Marca temporal Dirección de correo electrónico Escribe el nombre del taller El lenguaje de los talleres fue adecuado Se distinguió los objetivos del taller Fueron claras las instrucciones de los talleres ¿Qué tan ameno te pareció el taller? Los talleres te motivaron a seguir indagando en el tema Si tienes comentarios y/o sugerencias acerca de los talleres son bienvenidos. El lenguaje de las secuencias didácticas te pareció apropiado Se distinguió los objetivos de las secuencias didácticas Fueron claros los conceptos que se formalizaron en las secuencias didácticas ¿Qué tan complicado te pareció la formalización de los conceptos en las secuencias didácticas? ¿Qué tan apropiado fue introducir los conceptos formales a partir de los talleres? Si tienes comentarios y/o sugerencias son bienvenidos El lenguaje de los talleres fue adecuado Se distinguieron los objetivos del taller
113 7 21/07/2022 9:17:42 NaN Scrampty 2.0 2.0 1 1 1 No. Mucho Mucho Mucho Mucho Mucho No. NaN NaN
107 1 21/07/2022 9:14:57 NaN Scrampin 2.0 2.0 1 2 2 Todo bien :) Mucho Mucho Mucho Poco Mucho Todo claro NaN NaN
133 4 21/07/2022 9:14:24 NaN Toros vacas 3.0 2.0 1 2 2 por el momento no, gracias Mucho Mucho Mucho Poco Poco respondiendo a la anterior pregunta, no es ni ... NaN NaN
67 0 21/07/2022 12:04:11 NaN Un algoritmo para calcular el día del fin del ... 4.0 5.0 4 3 2 Me gustó el taller Mucho Mucho Mucho Poco Mucho Estuvo interesante conocer el concepto de indu... NaN NaN
88 9 21/07/2022 12:13:23 NaN El juego del grafimar 4.0 4.0 4 4 1 ninguno Mucho Mucho Mucho Mucho Mucho ninguno NaN NaN
74 7 21/07/2022 12:07:13 NaN Ecuación para calcular el fin del mundo 4.0 4.0 4 4 3 Todo bien, sólo hubo unas partes que no entendí. Mucho Mucho Poco Mucho Mucho Todo bien NaN NaN
76 9 21/07/2022 12:09:01 NaN Un algoritmo para calcular el día del fin del ... 4.0 5.0 4 5 5 nop :)) Mucho Mucho Poco Mucho Mucho :)) NaN NaN
112 6 21/07/2022 9:17:16 NaN Scram∅ 4.0 5.0 5 5 5 . Mucho Mucho Mucho Mucho Mucho . NaN NaN
103 12 21/07/2022 9:17:19 NaN Cursos Propedéuticos Facultad de Ciencias 4.0 4.0 4 4 4 - Mucho Mucho Mucho Mucho Mucho - NaN NaN
60 1 21/07/2022 12:19:19 NaN Cursos Propedéuticos Facultad de Ciencias 4.0 3.0 4 3 3 Todo bien Mucho Poco Mucho Mucho Poco Me ha gustado mucho el taller y la secuencia d... NaN NaN
122 5 21/07/2022 9:11:21 NaN Maquina para transformar café en teoremas 4.0 3.0 5 5 5 El taller en general me gustó bastante, pues c... Mucho Poco Mucho Poco Mucho La formalización de conceptos me ayudó a compr... NaN NaN
51 5 21/07/2022 12:16:56 NaN Los caminos del infinito 5.0 5.0 4 5 5 Que entregaran un pdf con la info del taller. Mucho Mucho Mucho Mucho Mucho - NaN NaN
114 8 21/07/2022 9:18:37 NaN scrampty 5.0 5.0 2 1 2 El taller fue muy ameno, fácil y divertido Mucho Mucho Mucho Poco Mucho Me gustó mucho jugar scrable NaN NaN
62 3 21/07/2022 12:19:51 NaN Curso Propedéutico Facultad de Ciencias 5.0 5.0 5 5 5 Me parecieron correctas las dos clases que he ... Mucho Mucho Mucho Mucho Mucho Todo esta super bien con los talleres hasta ahora NaN NaN
44 11 21/07/2022 12:22:49 NaN Carrera de Probabilidades con Mario Kart. 5.0 5.0 5 5 5 Dar bibliografia de materias de tronco comun Mucho Mucho Mucho Poco Mucho Formar los grupos con aspirantes de una misma ... NaN NaN
97 6 21/07/2022 9:12:35 NaN Propedéutico facultad de ciencias 5.0 4.0 4 5 4 Ninguno Mucho Mucho Mucho Poco Mucho Ninguno NaN NaN

Vemos que se ha realizado el ordenamiento de manera ascendente como queríamos. Cabe resaltar que nuestros datos aún no han sido limpiados, es decir, tenemos varios datos faltantes (que tienen la etiqueta NaN) en nuestras columnas. Es por ello que si queremos ver las últimas filas del dataframe ordenado veremos

In [29]:
df.sort_values('El lenguaje de los talleres fue adecuado').tail()
Out[29]:
Unnamed: 0 Marca temporal Dirección de correo electrónico Escribe el nombre del taller El lenguaje de los talleres fue adecuado Se distinguió los objetivos del taller Fueron claras las instrucciones de los talleres ¿Qué tan ameno te pareció el taller? Los talleres te motivaron a seguir indagando en el tema Si tienes comentarios y/o sugerencias acerca de los talleres son bienvenidos. El lenguaje de las secuencias didácticas te pareció apropiado Se distinguió los objetivos de las secuencias didácticas Fueron claros los conceptos que se formalizaron en las secuencias didácticas ¿Qué tan complicado te pareció la formalización de los conceptos en las secuencias didácticas? ¿Qué tan apropiado fue introducir los conceptos formales a partir de los talleres? Si tienes comentarios y/o sugerencias son bienvenidos El lenguaje de los talleres fue adecuado Se distinguieron los objetivos del taller
28 7 21/07/2022 16:22:50 NaN Juntos con conjuntos NaN NaN 1 1 1 Me gustó mucho el taller, repasé cosas que se ... Mucho Mucho Mucho Poco Mucho clases muy completas!:) 1.0 1.0
29 8 21/07/2022 16:23:05 NaN Conjuntos ? NaN NaN 1 1 1 Sofia, a veces te ponías un poco nerviosa y no... Mucho Mucho Mucho Poco Mucho Sin comentarios 1.0 1.0
30 9 21/07/2022 16:23:50 NaN Juntos con conjuntos NaN NaN 1 3 3 Creo que faltó que dieran como un "puente" por... Mucho Poco Mucho Poco Poco Ninguno 2.0 3.0
31 10 21/07/2022 16:23:59 NaN Juntos con conjuntos NaN NaN 1 2 2 considero que fue buena la explicación y el ma... Mucho Mucho Mucho Mucho Mucho todo me pareció muy bien 2.0 2.0
32 11 21/07/2022 16:24:46 NaN Juntos con conjuntos NaN NaN 1 1 1 Sólo me gustaría agradecer la labor y dinámica... Mucho Mucho Mucho Poco Mucho El material usado facilitó mucho el aprendizaj... 1.0 1.0

que se muestran los valores NaN para la columna 'El lenguaje de los talleres fue adecuado', lo cual podría compromenter nuestro análisis. De ahí la importancia de siempre realizar una "limpieza" de los datos y, por ejemplo, eliminar o modificar esos valores faltantes (NaN). No realizaremos la limpieza de los datos pues queda fuera de los objetivos de esta clase.

Continuando, podemos ordenar ahora de manera descendente para lo cual agregaremos el parámetro ascending=False como sigue:

In [31]:
df.sort_values('El lenguaje de los talleres fue adecuado', ascending=False).head()
Out[31]:
Unnamed: 0 Marca temporal Dirección de correo electrónico Escribe el nombre del taller El lenguaje de los talleres fue adecuado Se distinguió los objetivos del taller Fueron claras las instrucciones de los talleres ¿Qué tan ameno te pareció el taller? Los talleres te motivaron a seguir indagando en el tema Si tienes comentarios y/o sugerencias acerca de los talleres son bienvenidos. El lenguaje de las secuencias didácticas te pareció apropiado Se distinguió los objetivos de las secuencias didácticas Fueron claros los conceptos que se formalizaron en las secuencias didácticas ¿Qué tan complicado te pareció la formalización de los conceptos en las secuencias didácticas? ¿Qué tan apropiado fue introducir los conceptos formales a partir de los talleres? Si tienes comentarios y/o sugerencias son bienvenidos El lenguaje de los talleres fue adecuado Se distinguieron los objetivos del taller
51 5 21/07/2022 12:16:56 NaN Los caminos del infinito 5.0 5.0 4 5 5 Que entregaran un pdf con la info del taller. Mucho Mucho Mucho Mucho Mucho - NaN NaN
2 2 21/07/2022 9:19:09 NaN Serpientes estocásticas y escaleras aleatorias 5.0 5.0 5 5 4 No, fue agradable Mucho Mucho Mucho Mucho Mucho . NaN NaN
114 8 21/07/2022 9:18:37 NaN scrampty 5.0 5.0 2 1 2 El taller fue muy ameno, fácil y divertido Mucho Mucho Mucho Poco Mucho Me gustó mucho jugar scrable NaN NaN
45 12 21/07/2022 12:22:52 NaN carrera de probabilidades con Mario kart 5.0 5.0 5 5 5 todo bien Mucho Mucho Mucho Mucho Mucho todo bien NaN NaN
44 11 21/07/2022 12:22:49 NaN Carrera de Probabilidades con Mario Kart. 5.0 5.0 5 5 5 Dar bibliografia de materias de tronco comun Mucho Mucho Mucho Poco Mucho Formar los grupos con aspirantes de una misma ... NaN NaN

Podemos también realizar el ordenamiento tomando como base dos columnas en vez de una:

In [32]:
# Para ordenar con base en dos columnas requeriremos 
# escribir el nombre de dichas columnas
# dentro de una lista
df.sort_values( [ 'El lenguaje de los talleres fue adecuado',
                'Se distinguió los objetivos del taller' ],
                # configuramos el ordenamiento de manera 
                # descendente 
                ascending=False).head()
Out[32]:
Unnamed: 0 Marca temporal Dirección de correo electrónico Escribe el nombre del taller El lenguaje de los talleres fue adecuado Se distinguió los objetivos del taller Fueron claras las instrucciones de los talleres ¿Qué tan ameno te pareció el taller? Los talleres te motivaron a seguir indagando en el tema Si tienes comentarios y/o sugerencias acerca de los talleres son bienvenidos. El lenguaje de las secuencias didácticas te pareció apropiado Se distinguió los objetivos de las secuencias didácticas Fueron claros los conceptos que se formalizaron en las secuencias didácticas ¿Qué tan complicado te pareció la formalización de los conceptos en las secuencias didácticas? ¿Qué tan apropiado fue introducir los conceptos formales a partir de los talleres? Si tienes comentarios y/o sugerencias son bienvenidos El lenguaje de los talleres fue adecuado Se distinguieron los objetivos del taller
2 2 21/07/2022 9:19:09 NaN Serpientes estocásticas y escaleras aleatorias 5.0 5.0 5 5 4 No, fue agradable Mucho Mucho Mucho Mucho Mucho . NaN NaN
44 11 21/07/2022 12:22:49 NaN Carrera de Probabilidades con Mario Kart. 5.0 5.0 5 5 5 Dar bibliografia de materias de tronco comun Mucho Mucho Mucho Poco Mucho Formar los grupos con aspirantes de una misma ... NaN NaN
45 12 21/07/2022 12:22:52 NaN carrera de probabilidades con Mario kart 5.0 5.0 5 5 5 todo bien Mucho Mucho Mucho Mucho Mucho todo bien NaN NaN
51 5 21/07/2022 12:16:56 NaN Los caminos del infinito 5.0 5.0 4 5 5 Que entregaran un pdf con la info del taller. Mucho Mucho Mucho Mucho Mucho - NaN NaN
62 3 21/07/2022 12:19:51 NaN Curso Propedéutico Facultad de Ciencias 5.0 5.0 5 5 5 Me parecieron correctas las dos clases que he ... Mucho Mucho Mucho Mucho Mucho Todo esta super bien con los talleres hasta ahora NaN NaN

Asimismo, podemos configurar que una de las columnas tenga un ordenamiento de manera descendente y la otra de manera ascendente

In [33]:
df.sort_values( [ 'El lenguaje de los talleres fue adecuado',
                'Se distinguió los objetivos del taller' ],
                # configuramos el ordenamiento de manera 
                # descendente para la primer columna
                # y de manera ascendente para la 
                # segunda
                ascending=[False, True]).head()
Out[33]:
Unnamed: 0 Marca temporal Dirección de correo electrónico Escribe el nombre del taller El lenguaje de los talleres fue adecuado Se distinguió los objetivos del taller Fueron claras las instrucciones de los talleres ¿Qué tan ameno te pareció el taller? Los talleres te motivaron a seguir indagando en el tema Si tienes comentarios y/o sugerencias acerca de los talleres son bienvenidos. El lenguaje de las secuencias didácticas te pareció apropiado Se distinguió los objetivos de las secuencias didácticas Fueron claros los conceptos que se formalizaron en las secuencias didácticas ¿Qué tan complicado te pareció la formalización de los conceptos en las secuencias didácticas? ¿Qué tan apropiado fue introducir los conceptos formales a partir de los talleres? Si tienes comentarios y/o sugerencias son bienvenidos El lenguaje de los talleres fue adecuado Se distinguieron los objetivos del taller
97 6 21/07/2022 9:12:35 NaN Propedéutico facultad de ciencias 5.0 4.0 4 5 4 Ninguno Mucho Mucho Mucho Poco Mucho Ninguno NaN NaN
126 9 21/07/2022 9:12:23 NaN Máquina para transformar café en teoremas 5.0 4.0 5 5 5 Despiertan mucho el interés en aprender Mucho Mucho Mucho Poco Mucho Es muy dinámico y mantiene la atención enfocad... NaN NaN
2 2 21/07/2022 9:19:09 NaN Serpientes estocásticas y escaleras aleatorias 5.0 5.0 5 5 4 No, fue agradable Mucho Mucho Mucho Mucho Mucho . NaN NaN
44 11 21/07/2022 12:22:49 NaN Carrera de Probabilidades con Mario Kart. 5.0 5.0 5 5 5 Dar bibliografia de materias de tronco comun Mucho Mucho Mucho Poco Mucho Formar los grupos con aspirantes de una misma ... NaN NaN
45 12 21/07/2022 12:22:52 NaN carrera de probabilidades con Mario kart 5.0 5.0 5 5 5 todo bien Mucho Mucho Mucho Mucho Mucho todo bien NaN NaN

Filtros ¶

Por otro lado, así como realizabamos filtros en NumPy, podemos realizar filtros en pandas.

Antes de continuar haremos más pequeño el dataframe con el que estamos trabajando para tener mayor comodidad

In [39]:
# Vemos de nuevos los nombres de las columnas
df.columns
Out[39]:
Index(['Unnamed: 0', 'Marca temporal', 'Dirección de correo electrónico',
       'Escribe el nombre del taller ',
       'El lenguaje de los talleres fue adecuado',
       'Se distinguió los objetivos del taller',
       'Fueron claras las instrucciones de los talleres',
       '¿Qué tan ameno te pareció el taller?',
       'Los talleres te motivaron a seguir indagando en el tema',
       'Si tienes comentarios y/o sugerencias acerca de los talleres son bienvenidos.',
       'El lenguaje de las secuencias didácticas te pareció apropiado',
       'Se distinguió los objetivos de las secuencias didácticas',
       'Fueron claros los conceptos que se formalizaron en las secuencias didácticas',
       '¿Qué tan complicado te pareció la formalización de los conceptos en las secuencias didácticas?',
       '¿Qué tan apropiado fue introducir los conceptos formales a partir de los talleres?',
       'Si tienes comentarios y/o sugerencias son bienvenidos',
       'El lenguaje de los talleres fue adecuado ',
       'Se distinguieron los objetivos del taller'],
      dtype='object')
In [40]:
# Nos quedaremos solo con 3 columnas
df2 = df[['Escribe el nombre del taller ', 
          'El lenguaje de los talleres fue adecuado',
          'Se distinguió los objetivos del taller']]
df2.head()
Out[40]:
Escribe el nombre del taller El lenguaje de los talleres fue adecuado Se distinguió los objetivos del taller
0 Serpientes estocásticas y escaleras aleatorias 1.0 1.0
1 Serpientes estocásticas y escaleras aleatorias 1.0 1.0
2 Serpientes estocásticas y escaleras aleatorias 5.0 5.0
3 Serpientes estocásticas y escaleras aleatorias 1.0 1.0
4 Serpientes estocásticas y escaleras aleatorias 1.0 1.0

De tal manera, podemos crear un primer filtro

In [41]:
# Filtro: Valores de la columna 
# 'El lenguaje de los talleres fue adecuado'
# que sean mayores o iguales a 4:
df2['El lenguaje de los talleres fue adecuado'] >= 4
Out[41]:
0      False
1      False
2       True
3      False
4      False
       ...  
140    False
141    False
142    False
143    False
144    False
Name: El lenguaje de los talleres fue adecuado, Length: 145, dtype: bool

Vemos que obtenemos una tabla con entradas booleanas, donde True indica que el valor en dicha entrada cumple con la condición que especificamos y False caso contrario. Luego, para obtener explícitamente las filas del dataframe que cumplen con la condición, escribimos:

In [42]:
df2[ df2['El lenguaje de los talleres fue adecuado'] >= 4 ]
Out[42]:
Escribe el nombre del taller El lenguaje de los talleres fue adecuado Se distinguió los objetivos del taller
2 Serpientes estocásticas y escaleras aleatorias 5.0 5.0
44 Carrera de Probabilidades con Mario Kart. 5.0 5.0
45 carrera de probabilidades con Mario kart 5.0 5.0
51 Los caminos del infinito 5.0 5.0
60 Cursos Propedéuticos Facultad de Ciencias 4.0 3.0
62 Curso Propedéutico Facultad de Ciencias 5.0 5.0
67 Un algoritmo para calcular el día del fin del ... 4.0 5.0
74 Ecuación para calcular el fin del mundo 4.0 4.0
76 Un algoritmo para calcular el día del fin del ... 4.0 5.0
88 El juego del grafimar 4.0 4.0
97 Propedéutico facultad de ciencias 5.0 4.0
103 Cursos Propedéuticos Facultad de Ciencias 4.0 4.0
112 Scram∅ 4.0 5.0
114 scrampty 5.0 5.0
122 Maquina para transformar café en teoremas 4.0 3.0
126 Máquina para transformar café en teoremas 5.0 4.0

Veamos ahora a aquellos estudiantes que calificaron con un valor menor o igual a 2 respecto a la pregunta de la columna 'El lenguaje de los talleres fue adecuado'

In [44]:
#    ---------------condicion de filtrado----------------  
df2[ df2['El lenguaje de los talleres fue adecuado'] <= 2 ]
Out[44]:
Escribe el nombre del taller El lenguaje de los talleres fue adecuado Se distinguió los objetivos del taller
0 Serpientes estocásticas y escaleras aleatorias 1.0 1.0
1 Serpientes estocásticas y escaleras aleatorias 1.0 1.0
3 Serpientes estocásticas y escaleras aleatorias 1.0 1.0
4 Serpientes estocásticas y escaleras aleatorias 1.0 1.0
5 Serpientes estocásticas y escaleras aleatorias 1.0 2.0
... ... ... ...
140 Maquina para transformar cafe en teoremas 1.0 1.0
141 TOROS Y VACAS 1.0 1.0
142 maquina para transformar café en teoremas 1.0 2.0
143 Maquina para transformar café en teoremas 1.0 1.0
144 Maquina para transformar café en teoremas 1.0 1.0

116 rows × 3 columns

de modo la mayoría de las calificaciones fueron buenas (recordemos que 1 es una muy buena calificación y 5 una muy mala calificación). Podemos utilizar filtros más complejos utilizando and (&) y or (|) como sigue

In [58]:
# Condiciones de filtrado
condicion1 =  df2['El lenguaje de los talleres fue adecuado'] == 3
condicion2 =  df2['El lenguaje de los talleres fue adecuado'] == 5

# Filtro: se cumple la condicion 1 o se cumple la condicion 2
df2[ condicion1 | condicion2 ] 
Out[58]:
Escribe el nombre del taller El lenguaje de los talleres fue adecuado Se distinguió los objetivos del taller
2 Serpientes estocásticas y escaleras aleatorias 5.0 5.0
44 Carrera de Probabilidades con Mario Kart. 5.0 5.0
45 carrera de probabilidades con Mario kart 5.0 5.0
51 Los caminos del infinito 5.0 5.0
62 Curso Propedéutico Facultad de Ciencias 5.0 5.0
97 Propedéutico facultad de ciencias 5.0 4.0
114 scrampty 5.0 5.0
126 Máquina para transformar café en teoremas 5.0 4.0
133 Toros vacas 3.0 2.0

De manera similar podemos escribir

In [92]:
# Condiciones de filtrado
condicion1 =  df2['Escribe el nombre del taller '] == 'Toros vacas '
# De manera alternativa, en vez de escribir == 3 como se ve abajo, 
# podemos usar df2['El lenguaje de los talleres fue adecuado'].eq(3)
condicion2 =  df2['El lenguaje de los talleres fue adecuado'] == 3

# Filtro: se cumple la condicion 1 y se cumple la condicion 2
df2[ condicion1 & condicion2 ] 
Out[92]:
Escribe el nombre del taller El lenguaje de los talleres fue adecuado Se distinguió los objetivos del taller
133 Toros vacas 3.0 2.0

Notamos otro punto importante, es necesario hacer limpieza a nuestros datos pues vemos que un estudiante ha ingresado el nombre del taller 'Toros vacas ' colocando un espacio en blanco al final.

Otra manera de filtrar puede ser:

In [95]:
# Condicion de filtrado:
#                  Columna de interes                     valores posibles
cond = df2['El lenguaje de los talleres fue adecuado'].isin( [0, 4] )

# Consideraremos las entradas de nuestro dataframe donde los valores
# de la columna 'El lenguaje de los talleres fue adecuado' sean el 0
# o el 4
df2[cond]
Out[95]:
Escribe el nombre del taller El lenguaje de los talleres fue adecuado Se distinguió los objetivos del taller
60 Cursos Propedéuticos Facultad de Ciencias 4.0 3.0
67 Un algoritmo para calcular el día del fin del ... 4.0 5.0
74 Ecuación para calcular el fin del mundo 4.0 4.0
76 Un algoritmo para calcular el día del fin del ... 4.0 5.0
88 El juego del grafimar 4.0 4.0
103 Cursos Propedéuticos Facultad de Ciencias 4.0 4.0
112 Scram∅ 4.0 5.0
122 Maquina para transformar café en teoremas 4.0 3.0

esto es, con el método isin([<lista de valores>]) aplicado a una columna, estamos filtrando los valores de dicha columna que sean iguales a alguna de las posibilidades enmarcadas en la lista [<lista de valores>]. De tal manera, al escribir

df2['El lenguaje de los talleres fue adecuado'].isin( [0, 4] )

estamos considerando los valores de la columna 'El lenguaje de los talleres fue adecuado' que tengan el valor de 0 o que tengan el valor de 4 asignado