Pandas Numpy
Pandas Numpy
md 6/1/2022
Numpy y Pandas
Introducción
Numpy:
Es muy veloz, hasta 50 veces más rápido que usar una lista de Python o C.
Optimiza el almacenamiento en memoria.
Maneja distintos tipos de datos. Es una librería muy poderosa, se pueden crear redes neuronales desde
cero.
Pandas:
import numpy as np
import pandas as pd
Numpy
Array: El array es el principal objeto de la librería. Representa datos de manera estructurada y se puede
acceder a ellos a traves del indexado, a un dato específico o un grupo de muchos datos específicos.
Ejemplo:
import numpy as np
lista = [1,2,3,4,5,6,7,8,9]
lista = np.array(lista)
matriz = [[1,2,3],[4,5,6],[7,8,9]]
matriz = np.array(matriz)
1 / 30
pandas_numpy.md 6/1/2022
Indexado:
El indexado nos permite acceder a los elementos de los array y matrices Los elementos se emepiezan a contar
desde 0.
lista[0]
# output ---> 1
lista[0] + lista[5]
# output ---> 7
Slicing:
El slicing nos permite extraer varios datos, tiene un comienzo y un final. En este ejemplo se está extrayendo
datos desde la posición 1 hasta la 5. [1:6].
lista[0:3]
# output ---> array([1, 2, 3])
matriz[1:,0:2]
# output ---> array([[4, 5],
# [7, 8]])
Tipos de datos:
Los arrays de NumPy solo pueden contener un tipo de dato, ya que esto es lo que le confiere las ventajas de
la optimización de memoria.
arr = np.array([1,2,3,4])
arr.dtype
# output ---> dtype('int64')
como las redes neuronales trabajan mejor con arreglos tipo flotante (numeros decimales) entonces
cambiaremos el formato del arreglo anterior con el siguiente codigo:
2 / 30
pandas_numpy.md 6/1/2022
arr = arr.astype(np.float64)
arr.dtype
# output ---> dtype('float64')
También se puede cambiar a tipo booleano recordando que los números diferentes de 0 se convierten en
True.
Dimensiones:
scalar: dim = 0 Un solo dato o valor
vector: dim = 1 Listas de Python
matriz: dim = 2 Hoja de cálculo
tensor: dim > 3 Series de tiempo o Imágenes
Declarando un escalar:
scalar = np.array(42)
print(scalar)
scalar.ndim
# output ---> 42
# ---> 0
3 / 30
pandas_numpy.md 6/1/2022
Declarando un Vector:
Declarando un Tensor:
tensor = np.array([[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]],[[13, 13, 15],
[16, 17, 18], [19, 20, 21], [22, 23, 24]]])
print(tensor)
tensor.ndim
# output ---> [[[ 1 2 3]
# [ 4 5 6]
# [ 7 8 9]
# [10 11 12]]
# [[13 13 15]
# [16 17 18]
# [19 20 21]
# [22 23 24]]]
# ---> 3
4 / 30
pandas_numpy.md 6/1/2022
Se pueden expandir dimensiones a los array ya existentes. Axis = 0 hace refencia a las filas, mientras que axis
= 1 a las columnas.
print(vector, vector.ndim)
vector_2 = np.squeeze(vector)
print(vector_2, vector_2.ndim)
# output ---> [[[[[[[[[[1 2 3]]]]]]]]]] 10
# ---> [1 2 3] 1
Creando Arrays:
Este métodode NumPy nos permite generar arrays sin definir previamente una lista.
np.arange(0,10)
# output ---> array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.arange(0,20,2)
# output ---> array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
np.zeros(3)
# output ---> array([0., 0., 0.])
np.zeros((10,5))
# output ---> array([[0., 0., 0., 0., 0.],
# [0., 0., 0., 0., 0.],
# [0., 0., 0., 0., 0.],
# [0., 0., 0., 0., 0.],
# [0., 0., 0., 0., 0.],
# [0., 0., 0., 0., 0.],
# [0., 0., 0., 0., 0.],
# [0., 0., 0., 0., 0.],
# [0., 0., 0., 0., 0.],
# [0., 0., 0., 0., 0.]])
5 / 30
pandas_numpy.md 6/1/2022
np.ones(3)
# output ---> array([1., 1., 1.])
np.linspace() permite generar una arrary definiendo un incio, un final y cuantas divisiones tendrá.
np.linspace(0, 10 , 10)
# output ---> array([ 0.,1.11111111,2.22222222, 3.33333333, 4.44444444,
# 5.55555556, 6.66666667, 7.77777778, 8.88888889, 10])
np.eye(4)
# output ---> array([[1., 0., 0., 0.],
# [0., 1., 0., 0.],
# [0., 0., 1., 0.],
# [0., 0., 0., 1.]])
np.random.rand()
# output --->0.37185218178880153
np.random.rand(4)
# output ---> array([0.77923054, 0.90495575, 0.12949965, 0.55974303])
np.random.rand(4,4)
# output ---> array([[0.26920153, 0.24873544, 0.02278515, 0.08250538],
# [0.16755087, 0.59570639, 0.83604996, 0.57717126],
# [0.00161574, 0.27857138, 0.33982786, 0.19693596],
# [0.69474123, 0.01208492, 0.38613157, 0.609117 ]])
NumPy nos permite tambien generar números enteros. En este caso números enteros entre el 1 y 14
6 / 30
pandas_numpy.md 6/1/2022
np.random.randint(1,15)
# output ---> 4
np.random.randint(1,15, (3,3))
# output ---> array([[ 8, 2, 6],
# [ 7, 1, 8],
# [11, 14, 4]])
Shape y Reshape
shape me indica la forma que tiene un arreglo, es decir, me indica con que estructura de datos estoy
trabajando. Reshape transforma el arreglo mientras se mantengan los elementos.
arr = np.random.randint(1,10,(3,2))
arr.shape
# output ---> (3, 2)
Reshape
array([[4, 9],
[9, 2],
[3, 4]])
# Aplicamos el Reshape
arr.reshape(1,6)
np.reshape(arr,(1,6))
# output ---> array([[4, 9, 9, 2, 3, 4]])
7 / 30
pandas_numpy.md 6/1/2022
np.reshape(arr,(2,3), 'C')
# output ---> array([[5, 6, 4],
# [6, 2, 3]])
np.reshape(arr,(2,3), 'F')
# output ---> array([[5, 2, 6],
# [4, 6, 3]])
Además existe la opción de hacer reshape según como esté optimizado nuestro computador. En este caso es
como en C.
np.reshape(arr,(2,3), 'A')
# output ---> array([[5, 6, 4],
# [6, 2, 3]])
Función max()
arr.max()
# output ---> 19
matriz.max(0)
# output ---> array([ 6, 19, 16, 12, 8])
para mostrar en que indice se encuentra el valor maximo (me muestra el indice menor)
8 / 30
pandas_numpy.md 6/1/2022
arr.argmax()
# output ---> 1
Función min()
nos entrega el menos valor, contiene las mismas funciones de max pero nos devuelve el menor valor
Función ptp()
arr.ptp()
# output ---> 18
Función percentile()
np.percentile(arr, 50)
# output ---> 7.0
Función sort()
arr.sort()
arr
# output ---> array([ 1, 4, 5, 6, 6, 8, 12, 16, 19, 19])
Función median()
np.median(arr)
# output ---> 7.0
Función std()
9 / 30
pandas_numpy.md 6/1/2022
np.std(arr)
# output ---> 6.151422599691879
Función var()
np.var(arr)
# output ---> 37.84
np.std(arr) ** 2
# output ---> 37.84
Función mean()
np.mean(arr)
# output ---> 9.6
Función concatenate()
a = np.array([[1,2],[3,4]])
b = np.array([[5,6]])
np.concatenate((a,b))
# output ---> array([[1, 2],
# [3, 4],
# [5, 6]])
Si queremos concatenarlo de manera que nos quede en una matriz 2x3 debemos trasponer la información del
array b ya que solo tiene una dimension; quedaria de la siguiente manera:
10 / 30
pandas_numpy.md 6/1/2022
np.concatenate((a,b.T), axis=1)
# output --->array([[1, 2, 5],
# [3, 4, 6]])
Existen más funciones estadisticas, para poder consultarlas dar click AQUÍ
Y más funciones matemáticas dando click AQUÍ
Copy
.copy() nos permite copiar un array de NumPy en otra variable de tal forma que al modificar el nuevo array los
cambios no se vean reflejados en array original.
Se han modificado los datos del array original porque seguía haciendo referencia a esa variable.
arr
# output ----> array([ 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10])
arr_copy = arr.copy()
arr_copy[:] = 100
arr_copy
# output ----> array([100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100])
arr
# output ----> array([ 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10])
Condiciones
son un conjunto de parametros que colocamos al hacer un slicing o un idexing dentro de un array con alguna
condición, ejemplo quiero extraer del array los numeros pares.
nos permite realizar consultas al array mas especificas que sean dificil lograr con un simple slicing.
si yo creo una vartiable con una condicion, ejemplo los numeros > a 5 del array
11 / 30
pandas_numpy.md 6/1/2022
Si yo realizo slicing al array inicial "arr" poniendo como index el "indices_cond" tenemos como resultado la
condición planteada dentro de la variable "indices_cond":
arr[indices_cond]
# output ----> array([ 6, 7, 8, 9, 10], dtype=int8)
arr[arr > 5] = 99
# output ----> array([ 1, 2, 3, 4, 5, 99, 99, 99, 99, 99], dtype=int8)
Operaciones
Cuando realizamos una multiplicacionen donde queremos aplicar el factor a cada elemento en una lista en
python, el sistema entiende que lo que queremos es duplicar los datos, ejemplo:
lista = [1,2]
lista * 2
# output ---> [1, 2, 1, 2]
arr = np.arange(0,10)
arr2 = arr.copy() # realizamos copia para no modificar el array principal
arr * 2
# output ---> array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
12 / 30
pandas_numpy.md 6/1/2022
arr + arr2
# output ---> array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
Se pueden hacer operaciones de producto punto entre vectores con las dos siguientes maneras:
np.matmul(matriz, matriz2.T)
# output ---> array([[ 30, 80],
# [ 80, 255]])
matriz @ matriz2.T
# output ---> array([[ 30, 80],
# [ 80, 255]])
Pandas
Series y Dataframes
Series: es un objeto de pandas parecido a un array unidimensional ya que puedo indexar, hacer slicing, hacer
operaciones manetaticas y admite muchos tipos de datos.
Dataframes: Son estructuras matriciales, ya que tenemos filas y columnas, las filas y las columnas tienen
indices. con este podemos tambien indexar, hacer slicing, hacer operaciones manetaticas y admite muchos
tipos de datos.
import pandas as pd
psg_players =pd.Series(['Navas','Mbappe','Neymar','Messi'],
index=[1,7,10,30])
# Output
# 1 Navas
# 7 Mbappe
# 10 Neymar
# 30 Messi
# dtype: object
13 / 30
pandas_numpy.md 6/1/2022
psg_players[1]
# Output ---> 'Navas'
psg_players[0:3]
# Output
# 1 Navas
# 7 Mbappe
# 10 Neymar
# dtype: object
En el caso del mismo ejemplo anterior, si queremos realizar un dataframe, vamos a crear un diccionario con
las caracteristicas de los jugadores:
jugadores_psg ={'Jugadores':['Navas','Mbappe','Neymar','Messi'],
'Altura':[165.0,185.0,175.0,169.0],
'Goles':[2,150,200,450]}
podemos acceder a los dataframes con indices de filas y columnas, para reconocerlos realizamos los
siguientes comandos:
df_players.columns
# Output ---> Index(['Jugadores', 'Altura', 'Goles'], dtype='object')
df_players.index
# Output ---> Int64Index([1, 7, 10, 30], dtype='int64')
Podemos leer archivos externos para convertirlos en dataframes y poder trabajar con ellos en formato de filas
y columnas:
14 / 30
pandas_numpy.md 6/1/2022
Como con pandas podemos realizar slicing e indexing tal y como se realiza con la libreria de numpy podemos
referenciar filas y columnas de la siguiente manera:
df_books[0:4]
df_books[['Name','Author']]
15 / 30
pandas_numpy.md 6/1/2022
df_books.loc[0:4, ['Name','Author']]
En la siguiente linea de codigo voy a traerme una columna que me dirá que indice tiene como autor Stephen
King:
16 / 30
pandas_numpy.md 6/1/2022
Drop columns
otra forma de borrar sin usar implace es hacer referencia a la misma variable.
Python tiene su propia función de borrado que también me sirve en este caso pero no es muy recomendado
del df_books['Price']
Drop Rows
Add Columns
creamos una columna con la funcion nan de numpy (debemos tener la libreria de Numpy activa)
Podemos añadir una nueva columna con una numeración desde 1 hasta el final del DataFrame
data = np.arange(1,df_books.shape[0] + 1)
df_books['row_number'] = data
shape me muestra la
cantidad de filas del DataFrame
todo rango que quiera añadir debe tener la misma logitud de filas del DataFrame, de lo contrario tendremos
un error.
Add Rows
df_books.append(df_books)
18 / 30
pandas_numpy.md 6/1/2022
con este codigo estamos duplicando la cantidad de datos ya que estamos añadiendo con append el mismo
DataFrame.
df.isnull()
df.isnull()*1
podemos llenar los valores nulos con un valor para ser reconocidos:
df.fillna('Missing')
19 / 30
pandas_numpy.md 6/1/2022
O tambien podemos llenar los valores numericos con una formula como la media
df.fillna(df.mean())
df.interpolate()
df.dropna()
20 / 30
pandas_numpy.md 6/1/2022
de esta manera podriamos crear muchas variables condición y juntarlas en una sola consulta de datos.
df_books[~mayor2016]
df_books.head(5)
df_books.tail(5)
df_books.info()
De las columnas numericas podría optener datos estadisticos basicos con la siguiente línea de código:
df_books.describe()
21 / 30
pandas_numpy.md 6/1/2022
Con el siguiente comando podremos ver el peso en memoria de cada una de las columnas del DataFrame,
esta información es util para ver que tanto me podria demorar en iterar las columnas pasando un For
df_books.memory_usage(deep=True)
df_books['Author'].value_counts()
df_books.drop_duplicates()
22 / 30
pandas_numpy.md 6/1/2022
Para ordenar los datos de manera descendiente realizamos la siguiente línea de código:
df_books.sort_values('Year', ascending=False)
El sort tiene por defecto el ordenamiento ascendenter por lo que si queremos ordenarlo de esta manera
podriamos omitir el ascending en el código.
Group by
Función de agrecación que nos sirve para poder visualizar elementos que se repiten en un DataFrame de
manera agregada mediante sumas, conteos, promedios etc:
df_books.groupby('Author').count()
Vemos en el resultado anterior que el título del autor quedó más abajo que el resto. Esto es porque despues
de ejecutar ese codigo autor queda como index del DataFrame consultado y pdoriamos hacer consultas por
label de la siguiente manera:
23 / 30
pandas_numpy.md 6/1/2022
df_books.groupby('Author').count().loc['William Davis']
por otra parte podemos hacer que el autor haga parte de otra columna con la siguiente línea de comando
adicional:
df_books.groupby('Author').count().reset_index()
Si quiero realizar un analisis de más de una métrica podemos realizarlo con el siguiente código:
df_books.groupby('Author').agg(['min','max'])
podemos realizar operaciones de agrecación con diferentes variables a analizar, es decir, quiero realizar la
misma agregación por autor, pero, quiero sacar el minimo y el maximo de Reviews y el promedio del Rating:
df_books.groupby('Author').agg({'Reviews':['min','max'],'User Rating':'mean'})
24 / 30
pandas_numpy.md 6/1/2022
Combinando DataFrames
Cuando queremos realizar una union entre dos dataframes ya que necesitamos información que albergan
ambos podemos realizarlo de una manera simila a como se hace desde SQL:
Concat
pd.concat([df1,df2], ignore_index=True)
25 / 30
pandas_numpy.md 6/1/2022
con el ignore_index=True reseteamos el indice del DataFrame ya que si no lo usamos mantendriamos los
mismos indices de los DataFrames iniciales.
Merge
izq.merge(der, on='key')
si por el contrario tengo columnas con diferentes nombres se deberia unir especificando en el codigo los
nombres de las columnas a unir, similar a un ON despues de un JOIN en SQL:
26 / 30
pandas_numpy.md 6/1/2022
si tengo una llave nula en el DataFrame de la derecha la manera de conservar los datos de la columna
izquierda es argumentando que quiero hacer un merge por la izquierda ya que por defecto me trae el inner
(intersección):
Join
la diferencia del join con el merge es que el join va a hacer la busqueda y el match con los indices de los
DataFrames y el merge lo realiza con columnas específicas
izq.join(der)
27 / 30
pandas_numpy.md 6/1/2022
por defecto el join me hace una unión por la izquierda (left), para poder realizar joins diferentes se debe
especificar el tipo de join en el código:
izq.join(der, how='right')
izq.join(der, how='inner')
izq.join(der, how='outer')
Pivot
Pivot transforma los valores de determinadas columnas o filas en los índices de un nuevo DataFrame, y la
intersección de estos es el valor resultante.
df_books.pivot_table(index='Author',columns='Genre',values='User Rating')
Como resultado, los valores de Author pasan a formar el índice por fila y los valores de Genre pasan a formar
parte de los índices por columna, y el User Rating se mantiene como valor.
df_books.pivot_table(index='Genre',columns='Year', values='User
Rating',aggfunc='sum')
En este caso tenemos por cada género, la suma a lo largo de los años. Esto es mucho más interesante,
¿verdad? La mejor noticia es que no solo podemos obtener la suma, también podemos obtener la media, la
desviación estándar, el conteo, la varianza, etc. Únicamente con cambiar el parámetro aggfunc que traduce
función de agrupamiento.
Melt
28 / 30
pandas_numpy.md 6/1/2022
El método melt toma las columnas del DataFrame y las pasa a filas, con dos nuevas columnas para especificar
la antigua columna y el valor que traía.
df_books[['Name','Genre']].head(5).melt()
Apply
Es un método que nos ayudará a aplicar funciones definidas previamente a los DataFrames
def two_times(value):
return value * 2
df_books['User Rating'].apply(two_times)
Esta me multiplicará por 2 cada uno de los 'User Rating' y me lo hará mucho mas rápido que un for.
29 / 30
pandas_numpy.md 6/1/2022
Si quiero realizar una función mas compleja en donde el User Rating me lo multiplique por 2 si el genero es
Fiction de lo contrario dejar el dato como está:
30 / 30