PANDAS - Manipulacion de Datos con Python

Por Jose R. Zapata


Pandas es una herramienta de manipulación de datos de alto nivel desarrollada por Wes McKinney. Es construido sobre Numpy y permite el análisis de datos que cuenta con las estructuras de datos que necesitamos para limpiar los datos en bruto y que sean aptos para el análisis (por ejemplo, tablas). Como Pandas permite realizar tareas importantes, como alinear datos para su comparación, fusionar conjuntos de datos, gestión de datos perdidos, etc., se ha convertido en una librería muy importante para procesar datos a alto nivel en Python (es decir, estadísticas ). Pandas fue diseñada originalmente para gestionar datos financieros, y como alternativo al uso de hojas de cálculo (es decir, Microsoft Excel).

Los principales tipos de datos que pueden representarse con pandas son:

  • Datos tabulares con columnas de tipo heterogéneo con etiquetas en columnas y filas.
  • Series temporales

Pandas proporciona herramientas que permiten:

  • leer y escribir datos en diferentes formatos: CSV, JSON, Excel, bases SQL y formato HDF5
  • seleccionar y filtrar de manera sencilla tablas de datos en función de posición, valor o etiquetas
  • fusionar y unir datos
  • transformar datos aplicando funciones tanto en global como por ventanas
  • manipulación de series temporales
  • hacer gráficas

En pandas existen tres tipos básicos de objetos todos ellos basados a su vez en Numpy:

  • Series (listas, 1D)
  • DataFrame (tablas, 2D)

Por lo tanto, Pandas nos proporciona las estructuras de datos y funciones necesarias para el análisis de datos.

Instalar Pandas

Pandas ya esta preinstalado si se usa Google Collaboratory, si va realizar una instalacion en su computador

PIP

pip install pandas

Conda

Si instalo Anaconda, pandas ya viene preinstalado

conda install pandas

Importando Pandas

La libreria Pandas se importa de la siguiente manera

import pandas as pd # Importacion estandar de la libreria Pandas
import numpy  as np # Importacion estandar de la libreria NumPy

Series

Una serie es el primer tipo de datos de pandas y es muy similar a una matriz NumPy (de hecho está construida sobre el objeto de matriz NumPy). Lo que diferencia un arreglo NumPy de una serie, es que una serie puede tener etiquetas en los ejes, lo que significa que puede ser indexada por una etiqueta, en lugar de solo una ubicación numérica. Tampoco necesita contener datos numéricos, puede contener cualquier Objeto de Python arbitrario.

Creando una Serie

Puede convertir una lista, una matriz numpy o un diccionario en una serie, usando el metodo pd.Series:

# Crear diferentes tipos de datos
labels = ['a','b','c'] # lista de eetiquetas
my_list = [10,20,30] # lista con valores
arr = np.array([10,20,30]) # Convertir ista de valores en arreglo NumPy
d = {'a':10,'b':20,'c':30} # Creacion de un diccionario

Desde Listas

# Convertir una lista en series usando el metodo pd.Series
# observe que se crean los nombres con las posiciones de cada elemento
pd.Series(data=my_list)
0    10
1    20
2    30
dtype: int64
# Convertir una lista en series usando el metodo pd.Series
# se puede ingresar el nombre de las posiciones
pd.Series(data=my_list,index=labels)
a    10
b    20
c    30
dtype: int64
# No es necesario ingresar la palabra de 'data =''  en el argumento
pd.Series(my_list,labels)
a    10
b    20
c    30
dtype: int64

Desde Arreglos NumPy

# Convertir un arreglo en series usando el metodo pd.Series
pd.Series(arr)
0    10
1    20
2    30
dtype: int64
# Convertir un arreglo en series indicando tambien los valores del index
pd.Series(arr,labels)
a    10
b    20
c    30
dtype: int64

Desde un Diccionario

# Convertir un diccionario en series usando el metodo pd.Series
# Como el diccionario ya tiene clave entonces se le asigna como valor de la posicion
pd.Series(d)
a    10
b    20
c    30
dtype: int64

Datos en una Series

Una serie de pandas puede contener una variedad de tipos de objetos:

# Creando una serie basado solo en una lista de letras
pd.Series(data=labels)
0    a
1    b
2    c
dtype: object

Indexacion

La clave para usar una serie es entender su índice. Pandas hace uso de estos nombres o números de índice al permitir búsquedas rápidas de información (funciona como una tabla hash o diccionario).

Veamos algunos ejemplos de cómo obtener información de una serie. Vamos a crear dos series, ser1 y ser2:

# Creacion de una serie con sus labels o indices
ser1 = pd.Series([1,2,3,4],index = ['USA', 'Germany','USSR', 'Japan'])                                   
ser1
USA        1
Germany    2
USSR       3
Japan      4
dtype: int64
# Creacion de una serie con sus labels o indices
ser2 = pd.Series([1,2,5,4],index = ['USA', 'Germany','Italy', 'Japan'])                                   
ser2
USA        1
Germany    2
Italy      5
Japan      4
dtype: int64
# La busqueda en una serie es igual como en un diccionario
ser1['USA']
1
# La busqueda en una serie es igual como en un diccionario
ser2['Germany']
2

Las operaciones también se realizan según el índice:

# Observe los resultados de los paises que solo estan en una serie y no en las dos
ser1 + ser2
Germany    4.0
Italy      NaN
Japan      8.0
USA        2.0
USSR       NaN
dtype: float64

DataFrames

Los DataFrames son la estructura mas importante en pandas y están directamente inspirados en el lenguaje de programación R. Se puede pensar en un DataFrame como un conjunto de Series reunidas que comparten el mismo índice. En los DataFrame tenemos la opción de especificar tanto el index (el nombre de las filas) como columns (el nombre de las columnas).

# Importar la funcion de NumPy para crear arreglos de numeros enteros
from numpy.random import randn
np.random.seed(101) # Inicializar el generador aleatorio
# Forma rapida de crear una lista de python desde strings
'A B C D E'.split()
['A', 'B', 'C', 'D', 'E']
# Crear un dataframe con numeros aleatorios de 4 Columnas y 5 Filas
# Crear listas rapidamente usando la funcion split 'A B C D E'.split()
# Esto evita tener que escribir repetidamente las comas

df = pd.DataFrame(randn(5,4),
                  index='A B C D E'.split(),
                  columns='W X Y Z'.split())
df

W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
C -2.018168 0.740122 0.528813 -0.589001
D 0.188695 -0.758872 -0.933237 0.955057
E 0.190794 1.978757 2.605967 0.683509

Descripcion general del dataframe

Numero de Filas y Columnas

df.shape # retorna un Tuple asi: (filas, col)
(5, 4)

Informacion General de los datos

# Informacion general de los datos de cada cloumna
# Indica el numero de filas del dataset
# Muestra el numero de datos No Nulos por columna (valores validos)
# Tipo de dato de cada columna
# Tamaño total del dataset
df.info()
<class 'pandas.core.frame.DataFrame'>
Index: 5 entries, A to E
Data columns (total 4 columns):
W    5 non-null float64
X    5 non-null float64
Y    5 non-null float64
Z    5 non-null float64
dtypes: float64(4)
memory usage: 200.0+ bytes
# Tipos de datos que existen en las columnas del dataframe
df.dtypes
W    float64
X    float64
Y    float64
Z    float64
dtype: object

Resumen de estadistica descriptiva General

el metodo .describe() de los dataframes presenta un resumen de la estadistica descriptiva general de las columnas numericas del dataframe, presenta la informacion de:

  • Promedio (mean)
  • Desviacion estandard (std)
  • Valor minimo
  • Valor maximo
  • Cuartiles (25%, 50% y 75%)
df.describe() # No muestra la informacion de las columnas categoricas

W X Y Z
count 5.000000 5.000000 5.000000 5.000000
mean 0.343858 0.453764 0.452287 0.431871
std 1.681131 1.061385 1.454516 0.594708
min -2.018168 -0.758872 -0.933237 -0.589001
25% 0.188695 -0.319318 -0.848077 0.503826
50% 0.190794 0.628133 0.528813 0.605965
75% 0.651118 0.740122 0.907969 0.683509
max 2.706850 1.978757 2.605967 0.955057

Ver Primeros elementos del dataframe

df.head()

W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
C -2.018168 0.740122 0.528813 -0.589001
D 0.188695 -0.758872 -0.933237 0.955057
E 0.190794 1.978757 2.605967 0.683509

Ver Ultimos elementos del dataframe

df.tail()

W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
C -2.018168 0.740122 0.528813 -0.589001
D 0.188695 -0.758872 -0.933237 0.955057
E 0.190794 1.978757 2.605967 0.683509

Seleccion y Indexacion

Existen diversos métodos para tomar datos de un DataFrame

# Regresara todos los datos de la columna W
df['W']
A    2.706850
B    0.651118
C   -2.018168
D    0.188695
E    0.190794
Name: W, dtype: float64
# Seleccionar dos o mas columnas
# Pasar una lista con los nombres de las columnas

df[['W','Z']]

W Z
A 2.706850 0.503826
B 0.651118 0.605965
C -2.018168 -0.589001
D 0.188695 0.955057
E 0.190794 0.683509
# Seleccionar dos o mas columnas
# Pasar una lista con los nombres de las columnas
# Puedo indicar el orden de las columnas

df[['X','W','Z']] 

X W Z
A 0.628133 2.706850 0.503826
B -0.319318 0.651118 0.605965
C 0.740122 -2.018168 -0.589001
D -0.758872 0.188695 0.955057
E 1.978757 0.190794 0.683509

Las columnas de un DataFrame Columns son solo Series

type(df['W']) # Tipos de datos
pandas.core.series.Series

Creando una Nueva Columna

# Nueva columna igual a la suma de otras dos
# operacion vectorizada
df['new'] = df['W'] + df['Y']
df

W X Y Z new
A 2.706850 0.628133 0.907969 0.503826 3.614819
B 0.651118 -0.319318 -0.848077 0.605965 -0.196959
C -2.018168 0.740122 0.528813 -0.589001 -1.489355
D 0.188695 -0.758872 -0.933237 0.955057 -0.744542
E 0.190794 1.978757 2.605967 0.683509 2.796762

Eliminando Columnas

df.drop('new',axis=1) # axis = 0 elimina filas(index) axis = 1 elimina columnas

W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
C -2.018168 0.740122 0.528813 -0.589001
D 0.188695 -0.758872 -0.933237 0.955057
E 0.190794 1.978757 2.605967 0.683509
# No se aplica a el dataframe a menos que se especifique.
# Como se ve la operacion pasada no quedo grabada
df

W X Y Z new
A 2.706850 0.628133 0.907969 0.503826 3.614819
B 0.651118 -0.319318 -0.848077 0.605965 -0.196959
C -2.018168 0.740122 0.528813 -0.589001 -1.489355
D 0.188695 -0.758872 -0.933237 0.955057 -0.744542
E 0.190794 1.978757 2.605967 0.683509 2.796762
# Para que quede grabado se puede hacer de dos formas
# df = df.drop('new',axis=1) # Forma 1
df.drop('new', axis=1, inplace=True) # Forma 2
df

W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
C -2.018168 0.740122 0.528813 -0.589001
D 0.188695 -0.758872 -0.933237 0.955057
E 0.190794 1.978757 2.605967 0.683509
df

W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
C -2.018168 0.740122 0.528813 -0.589001
D 0.188695 -0.758872 -0.933237 0.955057
E 0.190794 1.978757 2.605967 0.683509

También se puede sacar filas de esta manera:

df.drop('E',axis=0)

W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
C -2.018168 0.740122 0.528813 -0.589001
D 0.188695 -0.758872 -0.933237 0.955057
df

W X Y Z
A 2.706850 0.628133 0.907969 0.503826
B 0.651118 -0.319318 -0.848077 0.605965
C -2.018168 0.740122 0.528813 -0.589001
D 0.188695 -0.758872 -0.933237 0.955057
E 0.190794 1.978757 2.605967 0.683509
# Otra manera de borrar las columnas es
del df['X'] # Esta funcion es INPLACE
df 

W Y Z
A 2.706850 0.907969 0.503826
B 0.651118 -0.848077 0.605965
C -2.018168 0.528813 -0.589001
D 0.188695 -0.933237 0.955057
E 0.190794 2.605967 0.683509

Obtener los nombres de las columnas y los indices (index):

df.columns # nombres de las columnas
Index(['W', 'Y', 'Z'], dtype='object')
df.index # nombres de los indices
Index(['A', 'B', 'C', 'D', 'E'], dtype='object')

Seleccionando Filas y Columnas

las dos formas de seleccion principal son:

  • DataFrame.loc[etiqueta_fila, etiqueta_columna] <- por etiquetas
  • DataFrame.iloc[indice_fila, indice_columna] <- por indices
# la funcion loc busca por medio de los nombres de los indices y columnas
df.loc['A'] # se selecciona todos los valores de la fila 'A'
W    2.706850
Y    0.907969
Z    0.503826
Name: A, dtype: float64

O basado en la posicion (index) en vez de usar la etiqueta

df.iloc[2] # Se seleccionan los valores de la fila con indice 2
# recordar que los index empiezan en cero
W   -2.018168
Y    0.528813
Z   -0.589001
Name: C, dtype: float64

Seleccionar un subconjunto de filas y columnas

# Mediante etiquetas
# se selecciona el elemento que esta en la fila=B Col=Y
df.loc['B','Y'] # con etiquetas
-0.8480769834036315
# Mediante etiquetas
# se selecciona un subconjunto de datos que estan entre
# filas = A, B   Cols= W, Y
df.loc[['A','B'],['W','Y']]

W Y
A 2.706850 0.907969
B 0.651118 -0.848077
df.loc[['B','A'],['Y','W']]

Y W
B -0.848077 0.651118
A 0.907969 2.706850

Seleccion Condicional o Filtros

Una característica importante de pandas es la selección condicional usando la notación de corchetes, muy similar a NumPy:

df

W Y Z
A 2.706850 0.907969 0.503826
B 0.651118 -0.848077 0.605965
C -2.018168 0.528813 -0.589001
D 0.188695 -0.933237 0.955057
E 0.190794 2.605967 0.683509
# Devuelve un dataframe con booleans
# segun si se cumple o no la condicion
df>0

W Y Z
A True True True
B True False True
C False True False
D True False True
E True True True
# Esta operacion solo mostrara los valores del dataframe que cumplen la condicion
# los que no cumplen devuelve el valor NaN
df[df>0]

W Y Z
A 2.706850 0.907969 0.503826
B 0.651118 NaN 0.605965
C NaN 0.528813 NaN
D 0.188695 NaN 0.955057
E 0.190794 2.605967 0.683509
# seleccionar todas las filas donde el valor
# que esta en la columna 'W' sea mayor que cero
df[df['W']>0]

W Y Z
A 2.706850 0.907969 0.503826
B 0.651118 -0.848077 0.605965
D 0.188695 -0.933237 0.955057
E 0.190794 2.605967 0.683509
# Seleccionar las filas donde 'W' sea mayor que cero
# y de esas filas escoger los valores de la columna 'Y'
df[df['W']>0]['Y']
A    0.907969
B   -0.848077
D   -0.933237
E    2.605967
Name: Y, dtype: float64
# Seleccionar las filas donde 'W' sea mayor que cero
# y de esas filas escoger los valores de las columna 'Y' y 'X'
df[df['W']>0][['Y','Z']]

Y Z
A 0.907969 0.503826
B -0.848077 0.605965
D -0.933237 0.955057
E 2.605967 0.683509

Para dos condiciones, se usa los booleanos de esta forma

  • | en vez de or
  • & en vez de and
  • ~ en vez de not

Por amor a Dios, recuerde usar paréntesis:

# Seleccionar las filas donde 'W' sea mayor que cero
# y tambien donde 'Y' sea mayor que 0.5
df[(df['W']>0) & (df['Y'] > 0.5)]

W Y Z
A 2.706850 0.907969 0.503826
E 0.190794 2.605967 0.683509

.query() Busqueda condicional

Los terminos de busqueda condicional o filtros se entregan al metodo como tipo ‘string’

df

W Y Z
A 2.706850 0.907969 0.503826
B 0.651118 -0.848077 0.605965
C -2.018168 0.528813 -0.589001
D 0.188695 -0.933237 0.955057
E 0.190794 2.605967 0.683509
# seleccionar todas las filas donde el valor
# que esta en la columna 'W' sea mayor que cero

#df[df['W']>0]
df.query('W>0')

W Y Z
A 2.706850 0.907969 0.503826
B 0.651118 -0.848077 0.605965
D 0.188695 -0.933237 0.955057
E 0.190794 2.605967 0.683509
# Seleccionar las filas donde 'W' sea mayor que cero
# y de esas filas escoger los valores de la columna 'Y'

#df[df['W']>0]['Y']
df.query('W>0')['Y']
A    0.907969
B   -0.848077
D   -0.933237
E    2.605967
Name: Y, dtype: float64
# Seleccionar las filas donde 'W' sea mayor que cero
# y de esas filas escoger los valores de las columna 'Y' y 'X'

#df[df['W']>0][['Y','Z']]
df.query('W>0')[['Y','Z']]

Y Z
A 0.907969 0.503826
B -0.848077 0.605965
D -0.933237 0.955057
E 2.605967 0.683509

Para dos condiciones, puede usar | = or y & = and con paréntesis:

# Seleccionar las filas donde 'W' sea mayor que cero
# y tambien donde 'Y' sea mayor que 0.5

#df[(df['W']>0) & (df['Y'] > 0.5)]
df.query('W>0 and Y>0.5')

W Y Z
A 2.706850 0.907969 0.503826
E 0.190794 2.605967 0.683509

Cambio de columna de Indexacion

Analicemos algunas características más de la indexación, incluido el restablecimiento del índice o el establecimiento de parametros.

df

W Y Z
A 2.706850 0.907969 0.503826
B 0.651118 -0.848077 0.605965
C -2.018168 0.528813 -0.589001
D 0.188695 -0.933237 0.955057
E 0.190794 2.605967 0.683509
# Reinicializar el indice a su valor por defecto 0,1...n index
df = df.reset_index()
df

index W Y Z
0 A 2.706850 0.907969 0.503826
1 B 0.651118 -0.848077 0.605965
2 C -2.018168 0.528813 -0.589001
3 D 0.188695 -0.933237 0.955057
4 E 0.190794 2.605967 0.683509
newind = 'CA NY WY OR CO'.split() # crear una lista con strings
newind
['CA', 'NY', 'WY', 'OR', 'CO']
# Agregar la lista creaada en el paso anterior al dataframe
df['States'] = newind
df

index W Y Z States
0 A 2.706850 0.907969 0.503826 CA
1 B 0.651118 -0.848077 0.605965 NY
2 C -2.018168 0.528813 -0.589001 WY
3 D 0.188695 -0.933237 0.955057 OR
4 E 0.190794 2.605967 0.683509 CO
# Redefinir la columna states como el indice
df.set_index('States')

index W Y Z
States
CA A 2.706850 0.907969 0.503826
NY B 0.651118 -0.848077 0.605965
WY C -2.018168 0.528813 -0.589001
OR D 0.188695 -0.933237 0.955057
CO E 0.190794 2.605967 0.683509
# por que no queda establecido el indice?
df

index W Y Z States
0 A 2.706850 0.907969 0.503826 CA
1 B 0.651118 -0.848077 0.605965 NY
2 C -2.018168 0.528813 -0.589001 WY
3 D 0.188695 -0.933237 0.955057 OR
4 E 0.190794 2.605967 0.683509 CO
# para establecer el indice debe ser una funcion inplace
df.set_index('States',inplace=True)
#df = df.set_index('States') # otra forma de hacerlo
df

index W Y Z
States
CA A 2.706850 0.907969 0.503826
NY B 0.651118 -0.848077 0.605965
WY C -2.018168 0.528813 -0.589001
OR D 0.188695 -0.933237 0.955057
CO E 0.190794 2.605967 0.683509

Groupby (Agrupacion por filas)

El método groupby le permite agrupar filas de datos y llamar a funciones agregadas

import pandas as pd
# Crear dataframe desde un diccionario
data = {'Company':['GOOG','GOOG','MSFT','MSFT','FB','FB'],
       'Person':['Sam','Charlie','Amy','Vanessa','Carl','Sarah'],
       'Sales':[200,120,340,124,243,350]}
data
{'Company': ['GOOG', 'GOOG', 'MSFT', 'MSFT', 'FB', 'FB'],
 'Person': ['Sam', 'Charlie', 'Amy', 'Vanessa', 'Carl', 'Sarah'],
 'Sales': [200, 120, 340, 124, 243, 350]}
#conversion del diccionario a dataframe
df = pd.DataFrame(data)
df

Company Person Sales
0 GOOG Sam 200
1 GOOG Charlie 120
2 MSFT Amy 340
3 MSFT Vanessa 124
4 FB Carl 243
5 FB Sarah 350

Se puede usar el método .groupby() para agrupar filas en función de un nombre de columna. Por ejemplo, vamos a agruparnos a partir de la Compañía. Esto creará un objeto DataFrameGroupBy:

#agrupar por Company
df.groupby('Company')
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7f059acb5128>

Se puede grabar este objeto en una nueva variable:

by_comp = df.groupby("Company")

utilizar los métodos agregados del objeto:

# Promedio de ventas por company
by_comp.mean()

Sales
Company
FB 296.5
GOOG 160.0
MSFT 232.0
# agrupar por compañia y calcular el promedio por cada una
df.groupby('Company').mean()

Sales
Company
FB 296.5
GOOG 160.0
MSFT 232.0

Más ejemplos de métodos agregados:

# agrupar por compañia y calcular la desviacion estandard
by_comp.std()

Sales
Company
FB 75.660426
GOOG 56.568542
MSFT 152.735065
# agrupar por compañia y calcular el minimo
by_comp.min()

Person Sales
Company
FB Carl 243
GOOG Charlie 120
MSFT Amy 124
# agrupar por compañia y calcular el maximo
by_comp.max()

Person Sales
Company
FB Sarah 350
GOOG Sam 200
MSFT Vanessa 340
# agrupar por compañia y sumar los elementos que hay excluyendo los NaN
by_comp.count()

Person Sales
Company
FB 2 2
GOOG 2 2
MSFT 2 2
# Una de las funciones mas usadas para descripcion estadistica de un dataframe
# Genera estadísticas descriptivas que resumen la tendencia central, la dispersión y la forma de la distribución de un conjunto de datos, excluyendo los valores `` NaN``.
# by_comp.describe(include = 'all') # incluir todo
by_comp.describe()

Sales
count mean std min 25% 50% 75% max
Company
FB 2.0 296.5 75.660426 243.0 269.75 296.5 323.25 350.0
GOOG 2.0 160.0 56.568542 120.0 140.00 160.0 180.00 200.0
MSFT 2.0 232.0 152.735065 124.0 178.00 232.0 286.00 340.0
# Una de las funciones mas usadas para descripcion estadistica de un dataframe
# Genera estadísticas descriptivas que resumen la tendencia central, la dispersión y la forma de la distribución de un conjunto de datos, excluyendo los valores `` NaN``.
# Transponer la descripcion
by_comp.describe().transpose()

Company FB GOOG MSFT
Sales count 2.000000 2.000000 2.000000
mean 296.500000 160.000000 232.000000
std 75.660426 56.568542 152.735065
min 243.000000 120.000000 124.000000
25% 269.750000 140.000000 178.000000
50% 296.500000 160.000000 232.000000
75% 323.250000 180.000000 286.000000
max 350.000000 200.000000 340.000000
# Descripcion estadistica de los datos de la copmañia GOOG
by_comp.describe().transpose()['GOOG']
Sales  count      2.000000
       mean     160.000000
       std       56.568542
       min      120.000000
       25%      140.000000
       50%      160.000000
       75%      180.000000
       max      200.000000
Name: GOOG, dtype: float64

Pivot Tables

La funcionlidad “Pivot_table” es muy utilizada y popular en las conocidas “hojas de cálculo” tipo, OpenOffice, LibreOffice, Excel, Lotus, etc. Esta funcionalidad nos permite agrupar, ordenar, calcular datos y manejar datos de una forma muy similar a la que se hace con las hojas de cálculo. mas informacion

La principal función del “Pivot_table” son las agrupaciones de datos a las que se les suelen aplicar funciones matemáticas como sumatorios, promedios, etc

import seaborn as sns # importar la libreria seaborn
# cargar dataset del titanic
titanic = sns.load_dataset('titanic')
titanic.head()

survived pclass sex age sibsp parch fare embarked class who adult_male deck embark_town alive alone
0 0 3 male 22.0 1 0 7.2500 S Third man True NaN Southampton no False
1 1 1 female 38.0 1 0 71.2833 C First woman False C Cherbourg yes False
2 1 3 female 26.0 0 0 7.9250 S Third woman False NaN Southampton yes True
3 1 1 female 35.0 1 0 53.1000 S First woman False C Southampton yes False
4 0 3 male 35.0 0 0 8.0500 S Third man True NaN Southampton no True

Haciendo el Pivot table a mano para obtener el promedio de personas que sobrevivieron por genero

# 1. Agrupar por genero
# 2. Obtener los sobrevivientes
# 3. Calcular el promedio
titanic.groupby('sex')[['survived']].mean()

survived
sex
female 0.742038
male 0.188908

promedio de cuantos sobrevivieron por genero divididos por clase

# 1. Agrupar por genero y clase
# 2. Obtener los sobrevivientes
# 3. Calcular el promedio
# 4. Poner el resultado como una tabla (.unstack)
titanic.groupby(['sex', 'class'])['survived'].mean().unstack()

class First Second Third
sex
female 0.968085 0.921053 0.500000
male 0.368852 0.157407 0.135447

Usando Pivot tables

titanic.pivot_table('survived', index='sex', columns='class')

class First Second Third
sex
female 0.968085 0.921053 0.500000
male 0.368852 0.157407 0.135447
titanic.pivot_table('survived', index='sex', columns='class', margins=True)

class First Second Third All
sex
female 0.968085 0.921053 0.500000 0.742038
male 0.368852 0.157407 0.135447 0.188908
All 0.629630 0.472826 0.242363 0.383838

Otro ejemplo mas simple:

data = {'A':['foo','foo','foo','bar','bar','bar'],
     'B':['one','one','two','two','one','one'],
       'C':['x','y','x','y','x','y'],
       'D':[1,3,2,5,4,1]}
df = pd.DataFrame(data)
df

A B C D
0 foo one x 1
1 foo one y 3
2 foo two x 2
3 bar two y 5
4 bar one x 4
5 bar one y 1
# pivot tables
df.pivot_table(values='D',index=['A', 'B'],columns=['C'])

C x y
A B
bar one 4.0 1.0
two NaN 5.0
foo one 1.0 3.0
two 2.0 NaN

Concatenar, Fusionar y Unir (Concatenating, Merging, Joining)

Hay 3 formas principales de combinar DataFrames: concatenar, fusionar y unir.

# DataFrames de ejemplo para concatenacion
import pandas as pd
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                        'B': ['B0', 'B1', 'B2', 'B3'],
                        'C': ['C0', 'C1', 'C2', 'C3'],
                        'D': ['D0', 'D1', 'D2', 'D3']},
                        index=[0, 1, 2, 3])
df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                        'B': ['B4', 'B5', 'B6', 'B7'],
                        'C': ['C4', 'C5', 'C6', 'C7'],
                        'D': ['D4', 'D5', 'D6', 'D7']},
                         index=[4, 5, 6, 7]) 
df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],
                        'B': ['B8', 'B9', 'B10', 'B11'],
                        'C': ['C8', 'C9', 'C10', 'C11'],
                        'D': ['D8', 'D9', 'D10', 'D11']},
                        index=[8, 9, 10, 11])
df1

A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
df2

A B C D
4 A4 B4 C4 D4
5 A5 B5 C5 D5
6 A6 B6 C6 D6
7 A7 B7 C7 D7
df3

A B C D
8 A8 B8 C8 D8
9 A9 B9 C9 D9
10 A10 B10 C10 D10
11 A11 B11 C11 D11

Concatenacion (Concatenation)

La concatenación básicamente combina DataFrames. Tenga en cuenta que las dimensiones deben coincidir a lo largo del eje con el que se está concatenando.

la concatenacion se hace con dataframes de diferentes indices

Puede usar .concat() y pasar una lista de DataFrames para concatenar juntos:

# Concatenar cada dateframe verticalmente, ya que coinciden los nombres de las columnas
pd.concat([df1,df2,df3])

A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
5 A5 B5 C5 D5
6 A6 B6 C6 D6
7 A7 B7 C7 D7
8 A8 B8 C8 D8
9 A9 B9 C9 D9
10 A10 B10 C10 D10
11 A11 B11 C11 D11
#concatenar dataframe horizontalmente, como no coinciden los index observar lo que ocurre
pd.concat([df1,df2,df3],axis=1)

A B C D A B C D A B C D
0 A0 B0 C0 D0 NaN NaN NaN NaN NaN NaN NaN NaN
1 A1 B1 C1 D1 NaN NaN NaN NaN NaN NaN NaN NaN
2 A2 B2 C2 D2 NaN NaN NaN NaN NaN NaN NaN NaN
3 A3 B3 C3 D3 NaN NaN NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN A4 B4 C4 D4 NaN NaN NaN NaN
5 NaN NaN NaN NaN A5 B5 C5 D5 NaN NaN NaN NaN
6 NaN NaN NaN NaN A6 B6 C6 D6 NaN NaN NaN NaN
7 NaN NaN NaN NaN A7 B7 C7 D7 NaN NaN NaN NaN
8 NaN NaN NaN NaN NaN NaN NaN NaN A8 B8 C8 D8
9 NaN NaN NaN NaN NaN NaN NaN NaN A9 B9 C9 D9
10 NaN NaN NaN NaN NaN NaN NaN NaN A10 B10 C10 D10
11 NaN NaN NaN NaN NaN NaN NaN NaN A11 B11 C11 D11

Fusion (Merging)

La función merge() le permite fusionar DataFrames juntos utilizando una lógica similar a la combinación de Tablas SQL. Por ejemplo:

# DataFrames de ejemplo para merging
left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                     'A': ['A0', 'A1', 'A2', 'A3'],
                     'B': ['B0', 'B1', 'B2', 'B3']})
   
right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                          'C': ['C0', 'C1', 'C2', 'C3'],
                          'D': ['D0', 'D1', 'D2', 'D3']})    
left

key A B
0 K0 A0 B0
1 K1 A1 B1
2 K2 A2 B2
3 K3 A3 B3
right

key C D
0 K0 C0 D0
1 K1 C1 D1
2 K2 C2 D2
3 K3 C3 D3
# how='inner' utilice la intersección de las claves de ambos marcos, similar a una combinación interna de SQL; 
# las keys son comunes
pd.merge(left,right,how='inner',on='key')

key A B C D
0 K0 A0 B0 C0 D0
1 K1 A1 B1 C1 D1
2 K2 A2 B2 C2 D2
3 K3 A3 B3 C3 D3

Un ejemplo mas complicado:

  • Natural join: para mantener solo las filas que coinciden con los marcos de datos, especifique el argumento how = ‘inner’.
  • Full outer join: para mantener todas las filas de ambos dataframe, especifique how = ‘OUTER’.
  • Left outer join: para incluir todas las filas de su dataframe x y solo aquellas de y que coincidan, especifique how=‘left’.
  • Right outer join: para incluir todas las filas de su dataframe y y solo aquellas de x que coincidan, especifique how=‘right’.

left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                     'key2': ['K0', 'K1', 'K0', 'K1'],
                        'A': ['A0', 'A1', 'A2', 'A3'],
                        'B': ['B0', 'B1', 'B2', 'B3']})
    
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                               'key2': ['K0', 'K0', 'K0', 'K0'],
                                  'C': ['C0', 'C1', 'C2', 'C3'],
                                  'D': ['D0', 'D1', 'D2', 'D3']})
left

key1 key2 A B
0 K0 K0 A0 B0
1 K0 K1 A1 B1
2 K1 K0 A2 B2
3 K2 K1 A3 B3
right

key1 key2 C D
0 K0 K0 C0 D0
1 K1 K0 C1 D1
2 K1 K0 C2 D2
3 K2 K0 C3 D3
# fusionando comparando las mismas claves que tengan comunes
pd.merge(left, right, on=['key1', 'key2'])

key1 key2 A B C D
0 K0 K0 A0 B0 C0 D0
1 K1 K0 A2 B2 C1 D1
2 K1 K0 A2 B2 C2 D2
# fusionando totalmente las dos tablas con las claves
pd.merge(left, right, how='outer', on=['key1', 'key2'])

key1 key2 A B C D
0 K0 K0 A0 B0 C0 D0
1 K0 K1 A1 B1 NaN NaN
2 K1 K0 A2 B2 C1 D1
3 K1 K0 A2 B2 C2 D2
4 K2 K1 A3 B3 NaN NaN
5 K2 K0 NaN NaN C3 D3
# fusionando usando las claves de la tabla right
pd.merge(left, right, how='right', on=['key1', 'key2'])

key1 key2 A B C D
0 K0 K0 A0 B0 C0 D0
1 K1 K0 A2 B2 C1 D1
2 K1 K0 A2 B2 C2 D2
3 K2 K0 NaN NaN C3 D3
# fusionando usando las claves de la tabla left
pd.merge(left, right, how='left', on=['key1', 'key2'])

key1 key2 A B C D
0 K0 K0 A0 B0 C0 D0
1 K0 K1 A1 B1 NaN NaN
2 K1 K0 A2 B2 C1 D1
3 K1 K0 A2 B2 C2 D2
4 K2 K1 A3 B3 NaN NaN

Unir (Joining)

Unir (join) es un método conveniente para combinar las columnas de dos DataFrames potencialmente indexados de forma diferente en un solo DataFrame. Join hace uniones de índices sobre índices o de índices sobre columnas

left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
                     'B': ['B0', 'B1', 'B2']},
                      index=['K0', 'K1', 'K2']) 

right = pd.DataFrame({'C': ['C0', 'C2', 'C3'],
                    'D': ['D0', 'D2', 'D3']},
                      index=['K0', 'K2', 'K3'])
left

A B
K0 A0 B0
K1 A1 B1
K2 A2 B2
right

C D
K0 C0 D0
K2 C2 D2
K3 C3 D3
# unir el dataframe 'right' a el dataframe 'left'
left.join(right)

A B C D
K0 A0 B0 C0 D0
K1 A1 B1 NaN NaN
K2 A2 B2 C2 D2
# unir el dataframe 'left' a el dataframe 'right'
right.join(left)

C D A B
K0 C0 D0 A0 B0
K2 C2 D2 A2 B2
K3 C3 D3 NaN NaN
# unir el dataframe 'left' a el dataframe 'rigth'
#how = outer
left.join(right, how='outer')

A B C D
K0 A0 B0 C0 D0
K1 A1 B1 NaN NaN
K2 A2 B2 C2 D2
K3 NaN NaN C3 D3

Datos Categoricos

  • La busqueda en datos categoricos es mucho mas rapida
  • Ocupan Menos memoria que si los datos estan como string
  • Se pueden tener datos categoricos Ordinales

Mas informacion de datos categoricos:

https://pandas.pydata.org/pandas-docs/stable/user_guide/categorical.html

Creacion

# Creacion de una serie de datos categoricos
cate = pd.Series(["manzana", "banano", "corozo", "manzana","pera"], dtype="category")
cate
0    manzana
1     banano
2     corozo
3    manzana
4       pera
dtype: category
Categories (4, object): [banano, corozo, manzana, pera]
cate.dtypes
CategoricalDtype(categories=['banano', 'corozo', 'manzana', 'pera'], ordered=False)
cate.describe()
count           5
unique          4
top       manzana
freq            2
dtype: object
# Creando primero los datos y luego convirtiendolos en categoricos
df_cate = pd.DataFrame({"Fruta":["manzana", "banano", "corozo", "manzana","pera"]})
df_cate

Fruta
0 manzana
1 banano
2 corozo
3 manzana
4 pera
# Observar los tipos de datos en el data frame
df_cate.dtypes
Fruta    object
dtype: object
df_cate["Fruta2"] = df_cate["Fruta"].astype('category')
df_cate

Fruta Fruta2
0 manzana manzana
1 banano banano
2 corozo corozo
3 manzana manzana
4 pera pera
# Observar los tipos de datos en el dataframe
df_cate.dtypes
Fruta       object
Fruta2    category
dtype: object
# Crear los datos categoricos desde a declaracion de los datos
df_cate = pd.DataFrame({'A': list('abca'), 'B': list('bccd')}, dtype="category")
df_cate

A B
0 a b
1 b c
2 c c
3 a d
df_cate.dtypes
A    category
B    category
dtype: object
df_cate.describe()

A B
count 4 4
unique 3 3
top a c
freq 2 2

Categoricos Ordinales

from pandas.api.types import CategoricalDtype
# creacion de dataframe con datos
df_cate = pd.DataFrame({'A': list('abca'), 'B': list('bccd')})
df_cate

A B
0 a b
1 b c
2 c c
3 a d
df_cate.dtypes
A    object
B    object
dtype: object
# Definicion de los tipos de datos y que estan en orden
df_cate["A"] = df_cate["A"].astype(CategoricalDtype(['a','b','c','d'], ordered=True))
df_cate

A B
0 a b
1 b c
2 c c
3 a d
df_cate["A"]
0    a
1    b
2    c
3    a
Name: A, dtype: category
Categories (4, object): [a < b < c < d]
# Los datos no tienen que ser strngs para qeu sean categoricos
s = pd.Series([1, 2, 3, 1], dtype="category")
s
0    1
1    2
2    3
3    1
dtype: category
Categories (3, int64): [1, 2, 3]
s = s.cat.set_categories([2, 3, 1], ordered=True)
s
0    1
1    2
2    3
3    1
dtype: category
Categories (3, int64): [2 < 3 < 1]

Datos Faltantes (Missing data)

Métodos para Manejar datos faltantes en pandas:

# Declaracion de data frame con algunos datos faltantes
# NaN = Not a Number
df = pd.DataFrame({'A':[1,2,np.nan],
                  'B':[5,np.nan,np.nan],
                  'C':[1,2,3]})
df

A B C
0 1.0 5.0 1
1 2.0 NaN 2
2 NaN NaN 3

Detectar si Faltan datos

# verificar cuales valores son NaN o nulos (Null)
df.isna()

A B C
0 False False False
1 False True False
2 True True False
# verificar cuales valores son na
# el metodo .isnull() es igual a .isna()
df.isnull()

A B C
0 False False False
1 False True False
2 True True False
# Verificar si hay datos faltantes por columna
df.isnull().any()
A     True
B     True
C    False
dtype: bool

Numero de datos faltantes

Calcular el numero de datos nulos que hay por columna

# Numero de datos faltantes por columna
df.isnull().sum()
A    1
B    2
C    0
dtype: int64

Eliminar datos Faltantes

# Eliminar todas las filas que tengan datos faltantes
df.dropna(axis=0) # cuando son filas no es neceario escribir axis=0

A B C
0 1.0 5.0 1
# Eliminar todas las columnas que tengan datos faltantes
df.dropna(axis=1)

C
0 1
1 2
2 3
# eliminar las filas que tengas 2 o mas valores NaN
df.dropna(thresh=2)

A B C
0 1.0 5.0 1
1 2.0 NaN 2

Reemplazar los datos faltantes

# Llenar los datos faltantes con el dato que nos interese
df.fillna(value='FILL VALUE') # llenar los espacios con un string
                              # puede ser una palabra, numero , etc

A B C
0 1 5 1
1 2 FILL VALUE 2
2 FILL VALUE FILL VALUE 3
# Llenar los datos faltantes con el dato que nos interese
df.fillna(value=99) # llenar los espacios con un numero

A B C
0 1.0 5.0 1
1 2.0 99.0 2
2 99.0 99.0 3
# Llenar los datos faltantes con el promedio de esa columna
df['A'].fillna(value=df['A'].mean())
0    1.0
1    2.0
2    1.5
Name: A, dtype: float64
# Llenar los datos faltantes con el promedio de cada columna
df.fillna(value=df.mean())

A B C
0 1.0 5.0 1
1 2.0 5.0 2
2 1.5 5.0 3

Datos unicos (Unique Values)

import pandas as pd
# crear un dataframe
df = pd.DataFrame({'col1':[1,2,3,4],'col2':[444,555,666,444],'col3':['abc','def','ghi','xyz']})
df.head() # solamente mostrar los primeros elementos del dataframe

col1 col2 col3
0 1 444 abc
1 2 555 def
2 3 666 ghi
3 4 444 xyz
# valores unicos de la columna col2
df['col2'].unique()
array([444, 555, 666])
# Numero de valores unicos en el dataframe
df['col2'].nunique()
3
# contar cuanto se repiten cada uno de los valores
df['col2'].value_counts()
444    2
555    1
666    1
Name: col2, dtype: int64

Datos Duplicados

Se puede borrar los registros que son exactamente iguales en todos los valores de las columnas

import pandas as pd
datos = {'name': ['James', 'Jason', 'Rogers', 'Jason'], 'age': [18, 20, 22, 20], 'job': ['Assistant', 'Manager', 'Clerk', 'Manager']}
df_dup = pd.DataFrame(datos)
df_dup

name age job
0 James 18 Assistant
1 Jason 20 Manager
2 Rogers 22 Clerk
3 Jason 20 Manager
# Metodo para detectar los datos duplicados
# me sirve para ver si existen registros duplicados
df_dup.duplicated()
0    False
1    False
2    False
3     True
dtype: bool
# Contar cuantos datos duplicados existen
df_dup.duplicated().sum()
1
# Para remover los datos duplicados
df_dup.drop_duplicates()

name age job
0 James 18 Assistant
1 Jason 20 Manager
2 Rogers 22 Clerk
# El metodo drop_duplicates entrega el data frame sin duplicados
# Pero la funcion no es inplace, osea que el dataframe original sigue igual
df_dup

name age job
0 James 18 Assistant
1 Jason 20 Manager
2 Rogers 22 Clerk
3 Jason 20 Manager
df_dup.drop_duplicates(inplace=True)
df_dup

name age job
0 James 18 Assistant
1 Jason 20 Manager
2 Rogers 22 Clerk

Duplicados por Columna

Se pueden borrar los valores que se repitan solamente verificando la columna

frame_datos = {'name': ['James', 'Jason', 'Rogers', 'Jason'], 'age': [18, 20, 22, 21], 'job': ['Assistant', 'Manager', 'Clerk', 'Employee']}
df_dup = pd.DataFrame(frame_datos)
df_dup

name age job
0 James 18 Assistant
1 Jason 20 Manager
2 Rogers 22 Clerk
3 Jason 21 Employee

el valor de jason esta duplicado en la columna name

# recordar que estas funciones no son inplace
df_dup.drop_duplicates(['name'])

name age job
0 James 18 Assistant
1 Jason 20 Manager
2 Rogers 22 Clerk

Outliers

Una de las formas de eliminar los aoutliers es identificando cual sera el rango en el que queremos nuestros datos y limitar los datos entre ese rango

import seaborn as sns # importar la libreria seaborn
# cargar dataset del titanic
titanic = sns.load_dataset('titanic')
titanic.head()

survived pclass sex age sibsp parch fare embarked class who adult_male deck embark_town alive alone
0 0 3 male 22.0 1 0 7.2500 S Third man True NaN Southampton no False
1 1 1 female 38.0 1 0 71.2833 C First woman False C Cherbourg yes False
2 1 3 female 26.0 0 0 7.9250 S Third woman False NaN Southampton yes True
3 1 1 female 35.0 1 0 53.1000 S First woman False C Southampton yes False
4 0 3 male 35.0 0 0 8.0500 S Third man True NaN Southampton no True
edad = titanic['age']
edad
0      22.0
1      38.0
2      26.0
3      35.0
4      35.0
5       NaN
6      54.0
7       2.0
8      27.0
9      14.0
10      4.0
11     58.0
12     20.0
13     39.0
14     14.0
15     55.0
16      2.0
17      NaN
18     31.0
19      NaN
20     35.0
21     34.0
22     15.0
23     28.0
24      8.0
25     38.0
26      NaN
27     19.0
28      NaN
29      NaN
       ... 
861    21.0
862    48.0
863     NaN
864    24.0
865    42.0
866    27.0
867    31.0
868     NaN
869     4.0
870    26.0
871    47.0
872    33.0
873    47.0
874    28.0
875    15.0
876    20.0
877    19.0
878     NaN
879    56.0
880    25.0
881    33.0
882    22.0
883    28.0
884    25.0
885    39.0
886    27.0
887    19.0
888     NaN
889    26.0
890    32.0
Name: age, Length: 891, dtype: float64
# Cual es la edad maxima
edad.max()
80.0
# Cual es la edad Minima
edad.min()
0.42

Solo por hacer el ejercicio se delimitaran las edades entre 1 y 70 años

esto se puede hacer con el metodo .clip(lower = Valor mas bajo, upper = valor mas alto)

edad = edad.clip(lower=1,upper = 70)
edad.max()
70.0
edad.min()
1.0

Tablas de Contingencia (two way tables)

# Crear Datos
raw_data = {'regiment': ['Nighthawks', 'Nighthawks', 'Nighthawks', 'Nighthawks', 'Dragoons', 'Dragoons', 'Dragoons', 'Dragoons', 'Scouts', 'Scouts', 'Scouts', 'Scouts'], 
        'company': ['infantry', 'infantry', 'cavalry', 'cavalry', 'infantry', 'infantry', 'cavalry', 'cavalry','infantry', 'infantry', 'cavalry', 'cavalry'], 
        'experience': ['veteran', 'rookie', 'veteran', 'rookie', 'veteran', 'rookie', 'veteran', 'rookie','veteran', 'rookie', 'veteran', 'rookie'],
        'name': ['Miller', 'Jacobson', 'Ali', 'Milner', 'Cooze', 'Jacon', 'Ryaner', 'Sone', 'Sloan', 'Piger', 'Riani', 'Ali'], 
        'preTestScore': [4, 24, 31, 2, 3, 4, 24, 31, 2, 3, 2, 3],
        'postTestScore': [25, 94, 57, 62, 70, 25, 94, 57, 62, 70, 62, 70]}
df = pd.DataFrame(raw_data, columns = ['regiment', 'company', 'experience', 'name', 'preTestScore', 'postTestScore'])
df

regiment company experience name preTestScore postTestScore
0 Nighthawks infantry veteran Miller 4 25
1 Nighthawks infantry rookie Jacobson 24 94
2 Nighthawks cavalry veteran Ali 31 57
3 Nighthawks cavalry rookie Milner 2 62
4 Dragoons infantry veteran Cooze 3 70
5 Dragoons infantry rookie Jacon 4 25
6 Dragoons cavalry veteran Ryaner 24 94
7 Dragoons cavalry rookie Sone 31 57
8 Scouts infantry veteran Sloan 2 62
9 Scouts infantry rookie Piger 3 70
10 Scouts cavalry veteran Riani 2 62
11 Scouts cavalry rookie Ali 3 70
# Tabla de contingencia por compañía y regimiento
pd.crosstab(df['regiment'], df['company'], margins=True)

company cavalry infantry All
regiment
Dragoons 2 2 4
Nighthawks 2 2 4
Scouts 2 2 4
All 6 6 12
# Tabla de contingencia de compañia y experiencia por regimiento
pd.crosstab([df['company'], df['experience']], df['regiment'],  margins=True)

regiment Dragoons Nighthawks Scouts All
company experience
cavalry rookie 1 1 1 3
veteran 1 1 1 3
infantry rookie 1 1 1 3
veteran 1 1 1 3
All 4 4 4 12

Metodos y Funciones en Pandas

Todos los metodos de los dataframe de pandas se pueden encontrar en:

http://pandas.pydata.org/pandas-docs/stable/reference/frame.html

import pandas as pd
# crear un dataframe
df = pd.DataFrame({'col1':[1,2,3,4],'col2':[444,555,666,444],
                   'col3':['mama   ','  papa','   HIJO  ','HiJa']})
df.head() # solamente mostrar los primeros elementos del dataframe

col1 col2 col3
0 1 444 mama
1 2 555 papa
2 3 666 HIJO
3 4 444 HiJa

Metodos Basicos Pandas

Ejemplos simples de los metodos de los dataframe de pandas

Para informacion completa de los metodos de computacion y estadisticos ver:

http://pandas.pydata.org/pandas-docs/stable/reference/frame.html#computations-descriptive-stats

# Suma total de cada Columna, si es categorico no lo suma
df.sum()
col1                            10
col2                          2109
col3    mama     papa   HIJO  HiJa
dtype: object
# Metodo en una sola columna
df['col1'].sum()
10
# Metodo en varias columnas
df[['col1','col2']].sum()
col1      10
col2    2109
dtype: int64
# Valor Minimo cada Columna
df.min()
col1            1
col2          444
col3       HIJO  
dtype: object
# Valor Maximo cada Columna
df.max()
col1          4
col2        666
col3    mama   
dtype: object

Metodos de Informacion General

# Cargar la base de datos 'mpg' de la libreria seaborn
import seaborn as sns

# los datos se cargan en un dataframe
data = sns.load_dataset('mpg')
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 398 entries, 0 to 397
Data columns (total 9 columns):
mpg             398 non-null float64
cylinders       398 non-null int64
displacement    398 non-null float64
horsepower      392 non-null float64
weight          398 non-null int64
acceleration    398 non-null float64
model_year      398 non-null int64
origin          398 non-null object
name            398 non-null object
dtypes: float64(4), int64(3), object(2)
memory usage: 28.1+ KB
data.head()

mpg cylinders displacement horsepower weight acceleration model_year origin name
0 18.0 8 307.0 130.0 3504 12.0 70 usa chevrolet chevelle malibu
1 15.0 8 350.0 165.0 3693 11.5 70 usa buick skylark 320
2 18.0 8 318.0 150.0 3436 11.0 70 usa plymouth satellite
3 16.0 8 304.0 150.0 3433 12.0 70 usa amc rebel sst
4 17.0 8 302.0 140.0 3449 10.5 70 usa ford torino
data.describe() # ver datos estadisticos de las columnas numericas

mpg cylinders displacement horsepower weight acceleration model_year
count 398.000000 398.000000 398.000000 392.000000 398.000000 398.000000 398.000000
mean 23.514573 5.454774 193.425879 104.469388 2970.424623 15.568090 76.010050
std 7.815984 1.701004 104.269838 38.491160 846.841774 2.757689 3.697627
min 9.000000 3.000000 68.000000 46.000000 1613.000000 8.000000 70.000000
25% 17.500000 4.000000 104.250000 75.000000 2223.750000 13.825000 73.000000
50% 23.000000 4.000000 148.500000 93.500000 2803.500000 15.500000 76.000000
75% 29.000000 8.000000 262.000000 126.000000 3608.000000 17.175000 79.000000
max 46.600000 8.000000 455.000000 230.000000 5140.000000 24.800000 82.000000
data.describe(include = 'all') # ver todos los datos incluidos los categoricos

mpg cylinders displacement horsepower weight acceleration model_year origin name
count 398.000000 398.000000 398.000000 392.000000 398.000000 398.000000 398.000000 398 398
unique NaN NaN NaN NaN NaN NaN NaN 3 305
top NaN NaN NaN NaN NaN NaN NaN usa ford pinto
freq NaN NaN NaN NaN NaN NaN NaN 249 6
mean 23.514573 5.454774 193.425879 104.469388 2970.424623 15.568090 76.010050 NaN NaN
std 7.815984 1.701004 104.269838 38.491160 846.841774 2.757689 3.697627 NaN NaN
min 9.000000 3.000000 68.000000 46.000000 1613.000000 8.000000 70.000000 NaN NaN
25% 17.500000 4.000000 104.250000 75.000000 2223.750000 13.825000 73.000000 NaN NaN
50% 23.000000 4.000000 148.500000 93.500000 2803.500000 15.500000 76.000000 NaN NaN
75% 29.000000 8.000000 262.000000 126.000000 3608.000000 17.175000 79.000000 NaN NaN
max 46.600000 8.000000 455.000000 230.000000 5140.000000 24.800000 82.000000 NaN NaN
# Descripcion de una sola columna
data['cylinders'].describe()
count    398.000000
mean       5.454774
std        1.701004
min        3.000000
25%        4.000000
50%        4.000000
75%        8.000000
max        8.000000
Name: cylinders, dtype: float64
data['mpg'].describe()
count    398.000000
mean      23.514573
std        7.815984
min        9.000000
25%       17.500000
50%       23.000000
75%       29.000000
max       46.600000
Name: mpg, dtype: float64
data['cylinders'].dtypes
dtype('int64')

Estadistica Descriptiva

Metodos de Estadistica Descriptiva, de medida central, simetria, momentos, etc. para mas informacion: http://pandas.pydata.org/pandas-docs/stable/reference/frame.html#computations-descriptive-stats

Los calculos de las medidas estadisticas se hacen siempre en columnas, es algo predeterminado, si se quiere hacer por filas, se debe especificar dentro de los metodos el parametro axis=1.

Ejemplo:

  • Calculo de la media por columnas (predeterminado) = df.mean()
  • Calculo de la media por filas = df.mean(axis=1)

Esto funciona con los otros tipos de medidas estadisticas

# Se tomara la columna 'mpg' para realizar los calculos
X = data['mpg']
type(X)
pandas.core.series.Series

Medidas de centralizacion

estas funciones se aplican sobre un dataframe de pandas

Media
# Media Aritmetica
X.mean()
23.514572864321615
# Media aritmetica en un dataframe
data.mean()
mpg               23.514573
cylinders          5.454774
displacement     193.425879
horsepower       104.469388
weight          2970.424623
acceleration      15.568090
model_year        76.010050
dtype: float64
Mediana
# Mediana
X.median()
23.0
# Mediana en un dataframe
data.median()
mpg               23.0
cylinders          4.0
displacement     148.5
horsepower        93.5
weight          2803.5
acceleration      15.5
model_year        76.0
dtype: float64
Maximo y Minimo
# Maximo
X.max()
46.6
# Maximo en un dataframe
data.max()
mpg                         46.6
cylinders                      8
displacement                 455
horsepower                   230
weight                      5140
acceleration                24.8
model_year                    82
origin                       usa
name            vw rabbit custom
dtype: object
# Minimo
X.min()
9.0
# Minimo en un dataframe
data.min()
mpg                                   9
cylinders                             3
displacement                         68
horsepower                           46
weight                             1613
acceleration                          8
model_year                           70
origin                           europe
name            amc ambassador brougham
dtype: object
Moda
# Moda
X.mode()
0    13.0
dtype: float64
# Moda en un dataframe
data.mode()

mpg cylinders displacement horsepower weight acceleration model_year origin name
0 13.0 4.0 97.0 150.0 1985 14.5 73.0 usa ford pinto
1 NaN NaN NaN NaN 2130 NaN NaN NaN NaN
Cuartiles
# Valores de los cuartiles
X.quantile([0, .25, .5, .75, 1])
0.00     9.0
0.25    17.5
0.50    23.0
0.75    29.0
1.00    46.6
Name: mpg, dtype: float64
# Valores de los cuartiles en un dataframe
data.quantile([0, .25, .5, .75, 1])

mpg cylinders displacement horsepower weight acceleration model_year
0.00 9.0 3.0 68.00 46.0 1613.00 8.000 70.0
0.25 17.5 4.0 104.25 75.0 2223.75 13.825 73.0
0.50 23.0 4.0 148.50 93.5 2803.50 15.500 76.0
0.75 29.0 8.0 262.00 126.0 3608.00 17.175 79.0
1.00 46.6 8.0 455.00 230.0 5140.00 24.800 82.0

Medidas de dispersion

Varianza
# Varianza
X.var() #unbiased Normalized by N-1 by default.
61.089610774274405
# Varianza en un dataframe
data.var()
mpg                 61.089611
cylinders            2.893415
displacement     10872.199152
horsepower        1481.569393
weight          717140.990526
acceleration         7.604848
model_year          13.672443
dtype: float64
Desviacion Estandard
# Desviacion tipica o desviacion estandard
X.std()
7.815984312565782
# Desviacion tipica o desviacion estandard en un dataframe
data.std()
mpg               7.815984
cylinders         1.701004
displacement    104.269838
horsepower       38.491160
weight          846.841774
acceleration      2.757689
model_year        3.697627
dtype: float64
Coeficiente de Variacion
# Coeficiente de Variacion
X.std()/X.mean()
0.3323889554645019

Medidas de Asimetria

Asimetria de Fisher (skewness)

La asimetría es la medida que indica la simetría de la distribución de una variable respecto a la media aritmética, sin necesidad de hacer la representación gráfica. Los coeficientes de asimetría indican si hay el mismo número de elementos a izquierda y derecha de la media.

Existen tres tipos de curva de distribución según su asimetría:

  • Asimetría negativa: la cola de la distribución se alarga para valores inferiores a la media.
  • Simétrica: hay el mismo número de elementos a izquierda y derecha de la media. En este caso, coinciden la media, la mediana y la moda. La distribución se adapta a la forma de la campana de Gauss, o distribución normal.
  • Asimetría positiva: la cola de la distribución se alarga para valores superiores a la media.

#unbiased skew, Normalized by N-1
X.skew() 
0.45706634399491913
#unbiased skew, Normalized by N-1 en un dataframe
data.skew()
mpg             0.457066
cylinders       0.526922
displacement    0.719645
horsepower      1.087326
weight          0.531063
acceleration    0.278777
model_year      0.011535
dtype: float64
Curtosis

Esta medida determina el grado de concentración que presentan los valores en la región central de la distribución. Por medio del Coeficiente de Curtosis, podemos identificar si existe una gran concentración de valores (Leptocúrtica), una concentración normal (Mesocúrtica) ó una baja concentración (Platicúrtica).

# unbiased kurtosis over requested axis using Fisher's definition
X.kurtosis()
-0.5107812652123154
# unbiased kurtosis over requested axis using Fisher's definition
# en un dataframe
data.kurtosis()
mpg            -0.510781
cylinders      -1.376662
displacement   -0.746597
horsepower      0.696947
weight         -0.785529
acceleration    0.419497
model_year     -1.181232
dtype: float64

Covarianza

Entre Series

s1 = pd.Series(np.random.randn(1000))
s2 = pd.Series(np.random.randn(1000))
s1.cov(s2)
-0.028354705528775087
# Numpy
np.cov(s1,s2)
array([[ 1.09020966, -0.02835471],
       [-0.02835471,  1.07417272]])

Dataframe

frame = pd.DataFrame(np.random.randn(1000, 5),columns=['a', 'b', 'c', 'd', 'e'])
frame.head()

a b c d e
0 0.576828 1.814651 -0.261503 -0.254697 0.974428
1 0.030171 0.605864 0.079012 -0.172524 3.052445
2 -0.842097 -0.351725 0.628591 0.878268 -0.055329
3 -0.273158 0.049033 -0.301981 0.562631 -1.241831
4 -0.305087 0.474497 0.648280 -0.026315 0.792715
frame.cov()

a b c d e
a 1.076575 0.000666 -0.039799 -0.002462 -0.043501
b 0.000666 1.016370 -0.015872 -0.002416 -0.021047
c -0.039799 -0.015872 1.036459 -0.058312 -0.057863
d -0.002462 -0.002416 -0.058312 1.000640 0.004340
e -0.043501 -0.021047 -0.057863 0.004340 0.952529
# Con Numpy
np.cov(frame)
array([[ 0.7710721 ,  0.51639576, -0.42821644, ..., -0.23771807,
        -0.63698462,  0.44026319],
       [ 0.51639576,  1.78416315, -0.17363496, ..., -1.00370658,
        -1.14416467,  0.59572484],
       [-0.42821644, -0.17363496,  0.49727435, ...,  0.08767001,
         0.33921621, -0.06352345],
       ...,
       [-0.23771807, -1.00370658,  0.08767001, ...,  0.64880976,
         0.65597959, -0.23257827],
       [-0.63698462, -1.14416467,  0.33921621, ...,  0.65597959,
         0.90660696, -0.45814778],
       [ 0.44026319,  0.59572484, -0.06352345, ..., -0.23257827,
        -0.45814778,  0.46902464]])

Correlacion

Metodos:

  • pearson (predeterminado)
  • kendall
  • spearman
#  Creacion de dataframe con datos aleatorios
frame = pd.DataFrame(np.random.randn(1000, 5), columns=['a', 'b', 'c', 'd', 'e'])
frame.head()                     

a b c d e
0 0.302665 1.693723 -1.706086 -1.159119 -0.134841
1 0.390528 0.166905 0.184502 0.807706 0.072960
2 0.638787 0.329646 -0.497104 -0.754070 -0.943406
3 0.484752 -0.116773 1.901755 0.238127 1.996652
4 -0.993263 0.196800 -1.136645 0.000366 1.025984

Entre Series

frame['a'].corr(frame['b']) # Pearson que es el predeterminado
-0.052592953776030495
frame['a'].corr(frame['b'], method='spearman') # Metodo spearman
-0.04775690375690376
frame['a'].corr(frame['b'], method='kendall') # Metodo Kendall
-0.03213613613613614
# Con Numpy se realiza el coefficiente de Pearson
# realiza la correlacion entre dos vectores
np.corrcoef(frame['a'],frame['b'])
array([[ 1.        , -0.05259295],
       [-0.05259295,  1.        ]])

Dataframe

frame.corr()

a b c d e
a 1.000000 -0.052593 -0.039170 0.001333 -0.001645
b -0.052593 1.000000 0.084488 0.007218 0.009969
c -0.039170 0.084488 1.000000 0.080168 0.006809
d 0.001333 0.007218 0.080168 1.000000 -0.039776
e -0.001645 0.009969 0.006809 -0.039776 1.000000
# con Numpy
np.corrcoef(frame)
array([[ 1.        , -0.58501996,  0.55616525, ...,  0.26806025,
        -0.35940809, -0.00452158],
       [-0.58501996,  1.        , -0.3400534 , ...,  0.11257458,
        -0.37590609, -0.58877942],
       [ 0.55616525, -0.3400534 ,  1.        , ...,  0.70442968,
         0.13326316, -0.19220235],
       ...,
       [ 0.26806025,  0.11257458,  0.70442968, ...,  1.        ,
         0.19271014, -0.79265039],
       [-0.35940809, -0.37590609,  0.13326316, ...,  0.19271014,
         1.        ,  0.14871875],
       [-0.00452158, -0.58877942, -0.19220235, ..., -0.79265039,
         0.14871875,  1.        ]])

Funciones Agregadas

Para aplicar una o mas funciones en cada columna de los dataframe

df.agg(['sum', 'min'])

col1 col2 col3
sum 10 2109 mama papa HIJO HiJa
min 1 444 HIJO
# Aplicar los metodos en columnas especificas
df[['col1','col2']].agg(['sum', 'min'])

col1 col2
sum 10 2109
min 1 444

Aplicando Funciones a cada elemento

#definicion de funcion
def times2(x):
    return x*2
# es mas o menos lo que hace la funcion map
# aplicar la funcion times2 a cada elemento de la col1 de dataframe df
df['col1'].apply(times2)
0    2
1    4
2    6
3    8
Name: col1, dtype: int64
df['col3'].apply(len) #longitud de cada uno de los datos de la col3
0    7
1    6
2    9
3    4
Name: col3, dtype: int64
df['col1'].sum() #sumatoria total de los elementos de la col1
10

(Sorting) Ordenar un DataFrame:

df

col1 col2 col3
0 1 444 mama
1 2 555 papa
2 3 666 HIJO
3 4 444 HiJa
# ordenar el dataframe de menor a mayor basado en col2
df.sort_values(by='col2') #inplace=False por default

col1 col2 col3
0 1 444 mama
3 4 444 HiJa
1 2 555 papa
2 3 666 HIJO
df.sort_values(by='col2',ascending=False)

col1 col2 col3
2 3 666 HIJO
1 2 555 papa
0 1 444 mama
3 4 444 HiJa

Metodos de strings

Los metodos de los strings se pueden usar en pandas de forma vectorizada

https://pandas.pydata.org/pandas-docs/stable/getting_started/basics.html#vectorized-string-methods

Los metodos vectorizados de los strings son:

https://pandas.pydata.org/pandas-docs/stable/user_guide/text.html#text-string-methods

Nota: Recordar que la mayoria de los metodos NO son inplace

df

col1 col2 col3
0 1 444 mama
1 2 555 papa
2 3 666 HIJO
3 4 444 HiJa
# Estos Metodos solo funcionan por columna (Series)
# se puede verificar el error
#df.str.lower()

Algunos ejemplos de metodos en strings en las columnas

# convertir strings en minuscula
df['col3'].str.lower()
0      mama   
1         papa
2       hijo  
3         hija
Name: col3, dtype: object
# convertir strings en Mayuscula
df['col3'].str.upper()
0      MAMA   
1         PAPA
2       HIJO  
3         HIJA
Name: col3, dtype: object
# Eliminar los espacios de los strings
df['col3'].str.strip()
0    mama
1    papa
2    HIJO
3    HiJa
Name: col3, dtype: object

Transformacion de Variables

  • Crear variables Dummy: convertir de categoría a númerica
  • Discretización o Binning: convertir de número a categoría

Columnas Dummy

Convertir variables categoricas a numericas

# crear datos categoricos
raw_data = {'first_name': ['Jason', 'Molly', 'Tina', 'Jake', 'Amy'], 
        'last_name': ['Miller', 'Jacobson', 'Ali', 'Milner', 'Cooze'], 
        'sex': ['male', 'female', 'male', 'female', 'female']}
df = pd.DataFrame(raw_data, columns = ['first_name', 'last_name', 'sex'])
df

first_name last_name sex
0 Jason Miller male
1 Molly Jacobson female
2 Tina Ali male
3 Jake Milner female
4 Amy Cooze female
# Crear un set de variables dummy para la columna sex
df_sex = pd.get_dummies(df['sex'])
df_sex

female male
0 0 1
1 1 0
2 0 1
3 1 0
4 1 0
# unir los dos dataframes
df_new = df.join(df_sex)
df_new

first_name last_name sex female male
0 Jason Miller male 0 1
1 Molly Jacobson female 1 0
2 Tina Ali male 0 1
3 Jake Milner female 1 0
4 Amy Cooze female 1 0

Discretización o Binning

Conversion de Numerica a Categorica

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.cut.html

# dividir los datos en 3 rangos iguales (categorias)

pd.cut(np.array([3.5, 2.8, 1, 5, 3, 4, 0, 4.4, 2, 3]), 3)
[(3.333, 5.0], (1.667, 3.333], (-0.005, 1.667], (3.333, 5.0], (1.667, 3.333], (3.333, 5.0], (-0.005, 1.667], (3.333, 5.0], (1.667, 3.333], (1.667, 3.333]]
Categories (3, interval[float64]): [(-0.005, 1.667] < (1.667, 3.333] < (3.333, 5.0]]
# Asignar etiquetas ordenadas
pd.cut(np.array([3.5, 2.8, 1, 5, 3, 4,0, 4.4, 2, 3]),
       3, labels=["Malo", "Regular", "Bien"])
[Bien, Regular, Malo, Bien, Regular, Bien, Malo, Bien, Regular, Regular]
Categories (3, object): [Malo < Regular < Bien]
pd.cut(np.array([2, 4 , 10 , 35 , 25 , 60 , 23, 14]),
       3, labels=["Niño", "Adolescente", "Adulto"])
[Niño, Niño, Niño, Adolescente, Adolescente, Adulto, Adolescente, Niño]
Categories (3, object): [Niño < Adolescente < Adulto]

Leer y guardar Datos (Data Input and Output)

Pandas puede leer una variedad de tipos de archivos usando sus métodos pd.read_ mas informacion

  • CSV
  • Excel
  • Json
  • Html
  • SQL

CSV File (comma-separated values)

CSV Input

# Leer archivos separados por comas, extension .csv
df1 = pd.read_csv('./Data/supermarkets.csv')
df1

ID Address City State Country Name Employees
0 1 3666 21st St San Francisco CA 94114 USA Madeira 8
1 2 735 Dolores St San Francisco CA 94119 USA Bready Shop 15
2 3 332 Hill St San Francisco California 94114 USA Super River 25
3 4 3995 23rd St San Francisco CA 94114 USA Ben's Shop 10
4 5 1056 Sanchez St San Francisco California USA Sanchez 12
5 6 551 Alvarado St San Francisco CA 94114 USA Richvalley 20
# dimensiones del dataframe
df1.shape
(6, 7)
# conocer los tipos de datos de cada columna
df1.dtypes
ID            int64
Address      object
City         object
State        object
Country      object
Name         object
Employees     int64
dtype: object
# Tambien se puede cambiar el valor de la columna index
# definir la columna ID como el index
df1.set_index("ID",inplace=True) # se debe especificar que sea inplace
df1

Address City State Country Name Employees
ID
1 3666 21st St San Francisco CA 94114 USA Madeira 8
2 735 Dolores St San Francisco CA 94119 USA Bready Shop 15
3 332 Hill St San Francisco California 94114 USA Super River 25
4 3995 23rd St San Francisco CA 94114 USA Ben's Shop 10
5 1056 Sanchez St San Francisco California USA Sanchez 12
6 551 Alvarado St San Francisco CA 94114 USA Richvalley 20
# hare un cambio y luego lo grabare
# multiplicar cada elemento de la columna employees por 2
df1['Employees']= df1['Employees'].apply(lambda x: x*2)
df1

Address City State Country Name Employees
ID
1 3666 21st St San Francisco CA 94114 USA Madeira 16
2 735 Dolores St San Francisco CA 94119 USA Bready Shop 30
3 332 Hill St San Francisco California 94114 USA Super River 50
4 3995 23rd St San Francisco CA 94114 USA Ben's Shop 20
5 1056 Sanchez St San Francisco California USA Sanchez 24
6 551 Alvarado St San Francisco CA 94114 USA Richvalley 40

CSV Output

# Grabar el dataframe como archivo separado por comas
df1.to_csv('./Data/example_out.csv',index=False)

Archivo de texto separado por comas

# Leer archivos separados por comas, extension .txt o sin extension
df1 = pd.read_csv("./Data/supermarkets-commas.txt")
df1

ID Address City State Country Name Employees
0 1 3666 21st St San Francisco CA 94114 USA Madeira 8
1 2 735 Dolores St San Francisco CA 94119 USA Bready Shop 15
2 3 332 Hill St San Francisco California 94114 USA Super River 25
3 4 3995 23rd St San Francisco CA 94114 USA Ben's Shop 10
4 5 1056 Sanchez St San Francisco California USA Sanchez 12
5 6 551 Alvarado St San Francisco CA 94114 USA Richvalley 20

Archivo de texto separado por otro caracter

# este archivo los valores estan separados por ;
df1 = pd.read_csv("./Data/supermarkets-semi-colons.txt",sep=';')
df1

ID Address City State Country Name Employees
0 1 3666 21st St San Francisco CA 94114 USA Madeira 8
1 2 735 Dolores St San Francisco CA 94119 USA Bready Shop 15
2 3 332 Hill St San Francisco California 94114 USA Super River 25
3 4 3995 23rd St San Francisco CA 94114 USA Ben's Shop 10
4 5 1056 Sanchez St San Francisco California USA Sanchez 12
5 6 551 Alvarado St San Francisco CA 94114 USA Richvalley 20

Excel

Pandas puede leer y escribir archivos de Excel, tenga en cuenta que esto solo importa datos. No fórmulas o imágenes, que tengan imágenes o macros pueden hacer que este método read_excel se bloquee.

Excel Input

# leer un archivo de excel
df2 = pd.read_excel("./Data/supermarkets.xlsx",sheet_name=0) #leer la primera hoja del archivo
df2

ID Address City State Country Supermarket Name Number of Employees
0 1 3666 21st St San Francisco CA 94114 USA Madeira 8
1 2 735 Dolores St San Francisco CA 94119 USA Bready Shop 15
2 3 332 Hill St San Francisco California 94114 USA Super River 25
3 4 3995 23rd St San Francisco CA 94114 USA Ben's Shop 10
4 5 1056 Sanchez St San Francisco California USA Sanchez 12
5 6 551 Alvarado St San Francisco CA 94114 USA Richvalley 20
# tambien podemos cambiar la columna del index
df2.set_index('ID')
df2

ID Address City State Country Supermarket Name Number of Employees
0 1 3666 21st St San Francisco CA 94114 USA Madeira 8
1 2 735 Dolores St San Francisco CA 94119 USA Bready Shop 15
2 3 332 Hill St San Francisco California 94114 USA Super River 25
3 4 3995 23rd St San Francisco CA 94114 USA Ben's Shop 10
4 5 1056 Sanchez St San Francisco California USA Sanchez 12
5 6 551 Alvarado St San Francisco CA 94114 USA Richvalley 20

Excel Output

# sumar cada elemento del data frame por 4
df2['Number of Employees'] = df2['Number of Employees'].apply(lambda x: x+4)
df2

ID Address City State Country Supermarket Name Number of Employees
0 1 3666 21st St San Francisco CA 94114 USA Madeira 12
1 2 735 Dolores St San Francisco CA 94119 USA Bready Shop 19
2 3 332 Hill St San Francisco California 94114 USA Super River 29
3 4 3995 23rd St San Francisco CA 94114 USA Ben's Shop 14
4 5 1056 Sanchez St San Francisco California USA Sanchez 16
5 6 551 Alvarado St San Francisco CA 94114 USA Richvalley 24
df2.to_excel('./Data/Excel_Sample_out.xlsx',sheet_name='Hoja1')

JSON

JSON (JavaScript Object Notation - Notación de Objetos de JavaScript) es un formato ligero de intercambio de datos. Leerlo y escribirlo es simple para humanos, mientras que para las máquinas es simple interpretarlo y generarlo.

Json Input

# los archivos pueden estar en un link de internet
df4 = pd.read_json("http://pythonhow.com/supermarkets.json")
df4

Address City Country Employees ID Name State
0 3666 21st St San Francisco USA 8 1 Madeira CA 94114
1 735 Dolores St San Francisco USA 15 2 Bready Shop CA 94119
2 332 Hill St San Francisco USA 25 3 Super River California 94114
3 3995 23rd St San Francisco USA 10 4 Ben's Shop CA 94114
4 1056 Sanchez St San Francisco USA 12 5 Sanchez California
5 551 Alvarado St San Francisco USA 20 6 Richvalley CA 94114

Json output

#Para grabar
df4.to_json("./Data/Salida.json")

WEKA (arff)

from scipy.io import arff # libreria para importar archivos de weka
# principalmente importa datos numericos
data = arff.loadarff('./Data/yeast-train.arff')
df5 = pd.DataFrame(data[0])
df5.head()

Att1 Att2 Att3 Att4 Att5 Att6 Att7 Att8 Att9 Att10 ... Class5 Class6 Class7 Class8 Class9 Class10 Class11 Class12 Class13 Class14
0 0.093700 0.139771 0.062774 0.007698 0.083873 -0.119156 0.073305 0.005510 0.027523 0.043477 ... b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'0'
1 -0.022711 -0.050504 -0.035691 -0.065434 -0.084316 -0.378560 0.038212 0.085770 0.182613 -0.055544 ... b'0' b'0' b'1' b'1' b'0' b'0' b'0' b'1' b'1' b'0'
2 -0.090407 0.021198 0.208712 0.102752 0.119315 0.041729 -0.021728 0.019603 -0.063853 -0.053756 ... b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'1' b'1' b'0'
3 -0.085235 0.009540 -0.013228 0.094063 -0.013592 -0.030719 -0.116062 -0.131674 -0.165448 -0.123053 ... b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'1' b'1' b'1'
4 -0.088765 -0.026743 0.002075 -0.043819 -0.005465 0.004306 -0.055865 -0.071484 -0.159025 -0.111348 ... b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'0'

5 rows × 117 columns

HTML

Se debe instalar htmllib5,lxml y BeautifulSoup4. En la terminal escriba

conda install lxml
conda install html5lib
conda install BeautifulSoup4

Luego reinicie el Jupyter Notebook. (o use pip install si no esta usando la distribucion de Anaconda)

Pandas puede leer tablas de html

La función pandas read_html leerá las tablas de una página web y devolverá una lista de objetos DataFrame:

data = pd.read_html('http://www.fdic.gov/bank/individual/failed/banklist.html')
data[0]

Bank Name City ST CERT Acquiring Institution Closing Date Updated Date
0 The Enloe State Bank Cooper TX 10716 Legend Bank, N. A. May 31, 2019 June 5, 2019
1 Washington Federal Bank for Savings Chicago IL 30570 Royal Savings Bank December 15, 2017 February 1, 2019
2 The Farmers and Merchants State Bank of Argonia Argonia KS 17719 Conway Bank October 13, 2017 February 21, 2018
3 Fayette County Bank Saint Elmo IL 1802 United Fidelity Bank, fsb May 26, 2017 January 29, 2019
4 Guaranty Bank, (d/b/a BestBank in Georgia & Mi... Milwaukee WI 30003 First-Citizens Bank & Trust Company May 5, 2017 March 22, 2018
5 First NBC Bank New Orleans LA 58302 Whitney Bank April 28, 2017 January 29, 2019
6 Proficio Bank Cottonwood Heights UT 35495 Cache Valley Bank March 3, 2017 January 29, 2019
7 Seaway Bank and Trust Company Chicago IL 19328 State Bank of Texas January 27, 2017 January 29, 2019
8 Harvest Community Bank Pennsville NJ 34951 First-Citizens Bank & Trust Company January 13, 2017 May 18, 2017
9 Allied Bank Mulberry AR 91 Today's Bank September 23, 2016 May 13, 2019
10 The Woodbury Banking Company Woodbury GA 11297 United Bank August 19, 2016 December 13, 2018
11 First CornerStone Bank King of Prussia PA 35312 First-Citizens Bank & Trust Company May 6, 2016 November 13, 2018
12 Trust Company Bank Memphis TN 9956 The Bank of Fayette County April 29, 2016 September 14, 2018
13 North Milwaukee State Bank Milwaukee WI 20364 First-Citizens Bank & Trust Company March 11, 2016 January 29, 2019
14 Hometown National Bank Longview WA 35156 Twin City Bank October 2, 2015 February 19, 2018
15 The Bank of Georgia Peachtree City GA 35259 Fidelity Bank October 2, 2015 July 9, 2018
16 Premier Bank Denver CO 34112 United Fidelity Bank, fsb July 10, 2015 February 20, 2018
17 Edgebrook Bank Chicago IL 57772 Republic Bank of Chicago May 8, 2015 January 29, 2019
18 Doral Bank En Español San Juan PR 32102 Banco Popular de Puerto Rico February 27, 2015 January 29, 2019
19 Capitol City Bank & Trust Company Atlanta GA 33938 First-Citizens Bank & Trust Company February 13, 2015 January 29, 2019
20 Highland Community Bank Chicago IL 20290 United Fidelity Bank, fsb January 23, 2015 November 15, 2017
21 First National Bank of Crestview Crestview FL 17557 First NBC Bank January 16, 2015 November 15, 2017
22 Northern Star Bank Mankato MN 34983 BankVista December 19, 2014 January 3, 2018
23 Frontier Bank, FSB D/B/A El Paseo Bank Palm Desert CA 34738 Bank of Southern California, N.A. November 7, 2014 November 10, 2016
24 The National Republic Bank of Chicago Chicago IL 916 State Bank of Texas October 24, 2014 January 6, 2016
25 NBRS Financial Rising Sun MD 4862 Howard Bank October 17, 2014 January 29, 2019
26 GreenChoice Bank, fsb Chicago IL 28462 Providence Bank, LLC July 25, 2014 December 12, 2016
27 Eastside Commercial Bank Conyers GA 58125 Community & Southern Bank July 18, 2014 October 6, 2017
28 The Freedom State Bank Freedom OK 12483 Alva State Bank & Trust Company June 27, 2014 February 21, 2018
29 Valley Bank Fort Lauderdale FL 21793 Landmark Bank, National Association June 20, 2014 January 29, 2019
... ... ... ... ... ... ... ...
526 ANB Financial, NA Bentonville AR 33901 Pulaski Bank and Trust Company May 9, 2008 February 1, 2019
527 Hume Bank Hume MO 1971 Security Bank March 7, 2008 January 31, 2019
528 Douglass National Bank Kansas City MO 24660 Liberty Bank and Trust Company January 25, 2008 October 26, 2012
529 Miami Valley Bank Lakeview OH 16848 The Citizens Banking Company October 4, 2007 September 12, 2016
530 NetBank Alpharetta GA 32575 ING DIRECT September 28, 2007 January 31, 2019
531 Metropolitan Savings Bank Pittsburgh PA 35353 Allegheny Valley Bank of Pittsburgh February 2, 2007 October 27, 2010
532 Bank of Ephraim Ephraim UT 1249 Far West Bank June 25, 2004 April 9, 2008
533 Reliance Bank White Plains NY 26778 Union State Bank March 19, 2004 April 9, 2008
534 Guaranty National Bank of Tallahassee Tallahassee FL 26838 Hancock Bank of Florida March 12, 2004 April 17, 2018
535 Dollar Savings Bank Newark NJ 31330 No Acquirer February 14, 2004 April 9, 2008
536 Pulaski Savings Bank Philadelphia PA 27203 Earthstar Bank November 14, 2003 October 6, 2017
537 First National Bank of Blanchardville Blanchardville WI 11639 The Park Bank May 9, 2003 June 5, 2012
538 Southern Pacific Bank Torrance CA 27094 Beal Bank February 7, 2003 October 20, 2008
539 Farmers Bank of Cheneyville Cheneyville LA 16445 Sabine State Bank & Trust December 17, 2002 October 20, 2004
540 Bank of Alamo Alamo TN 9961 No Acquirer November 8, 2002 March 18, 2005
541 AmTrade International Bank En Español Atlanta GA 33784 No Acquirer September 30, 2002 September 11, 2006
542 Universal Federal Savings Bank Chicago IL 29355 Chicago Community Bank June 27, 2002 October 6, 2017
543 Connecticut Bank of Commerce Stamford CT 19183 Hudson United Bank June 26, 2002 February 14, 2012
544 New Century Bank Shelby Township MI 34979 No Acquirer March 28, 2002 March 18, 2005
545 Net 1st National Bank Boca Raton FL 26652 Bank Leumi USA March 1, 2002 April 9, 2008
546 NextBank, NA Phoenix AZ 22314 No Acquirer February 7, 2002 February 5, 2015
547 Oakwood Deposit Bank Co. Oakwood OH 8966 The State Bank & Trust Company February 1, 2002 October 25, 2012
548 Bank of Sierra Blanca Sierra Blanca TX 22002 The Security State Bank of Pecos January 18, 2002 November 6, 2003
549 Hamilton Bank, NA En Español Miami FL 24382 Israel Discount Bank of New York January 11, 2002 September 21, 2015
550 Sinclair National Bank Gravette AR 34248 Delta Trust & Bank September 7, 2001 October 6, 2017
551 Superior Bank, FSB Hinsdale IL 32646 Superior Federal, FSB July 27, 2001 August 19, 2014
552 Malta National Bank Malta OH 6629 North Valley Bank May 3, 2001 November 18, 2002
553 First Alliance Bank & Trust Co. Manchester NH 34264 Southern New Hampshire Bank & Trust February 2, 2001 February 18, 2003
554 National State Bank of Metropolis Metropolis IL 3815 Banterra Bank of Marion December 14, 2000 March 17, 2005
555 Bank of Honolulu Honolulu HI 21029 Bank of the Orient October 13, 2000 March 17, 2005

556 rows × 7 columns


SQL

El módulo pandas.io.sql proporciona una colección de contenedores de consultas para facilitar la recuperación de datos y reducir la dependencia de la API específica de DB. La abstracción de la base de datos es proporcionada por SQLAlchemy si está instalado. Además, necesitará una biblioteca de controladores para su base de datos. Ejemplos de tales controladores son psycopg2 para PostgreSQL o pymysql para MySQL. Para SQLite esto está incluido en la biblioteca estándar de Python por defecto. Puede encontrar una descripción general de los controladores admitidos para cada lenguaje SQL en los documentos de SQLAlchemy.

Vea también algunos ejemplos de libros para algunas estrategias avanzadas.

las funciones claves son:

  • read_sql_table(table_name, con[, schema, …])
    • Read SQL database table into a DataFrame.
  • read_sql_query(sql, con[, index_col, …])
    • Read SQL query into a DataFrame.
  • read_sql(sql, con[, index_col, …])
    • Read SQL query or database table into a DataFrame.
  • DataFrame.to_sql(name, con[, flavor, …])
    • Write records stored in a DataFrame to a SQL database.
# librerias para crear un proceso de sql sencillo
from sqlalchemy import create_engine
# crear un proceso en memoria
engine = create_engine('sqlite:///:memory:')
df4.to_sql('data', engine) # grabar el dataframe en formato sql
sql_df = pd.read_sql('data',con=engine) # definir la conexion
sql_df

index Address City Country Employees ID Name State
0 0 3666 21st St San Francisco USA 8 1 Madeira CA 94114
1 1 735 Dolores St San Francisco USA 15 2 Bready Shop CA 94119
2 2 332 Hill St San Francisco USA 25 3 Super River California 94114
3 3 3995 23rd St San Francisco USA 10 4 Ben's Shop CA 94114
4 4 1056 Sanchez St San Francisco USA 12 5 Sanchez California
5 5 551 Alvarado St San Francisco USA 20 6 Richvalley CA 94114

Referencias

Phd. Jose R. Zapata