Tabla de Contenidos

Pandas

Pandas es una herramienta de código abierto para la manipulación y análisis de datos.

Pandas está construido sobre NumPy. Sus estructuras de datos básicas son Series y DataFrame

Instalación

En Ubuntu se puede instalar mediante el paquete python3-pandas y en Arch Linux con python-pandas

También se puede instalar a través de pip:

pip3 install pandas

Uso

Para importar pandas:

import pandas as pd
from pandas import Series, DataFrame

El alias pd suele ser el que usa la comunidad.

Series

Series en Python es un objeto similar a un array de una dimensión.

Para crear una serie de pandas a partir de una lista:

import pandas as pd
 
helados = ["Chocolate", "Vainilla", "Fresa", "Limón"]
 
pd.Series(helados)
 
# Resultado
 
# 0    Chocolate
# 1     Vainilla
# 2        Fresa
# 3        Limón
# dtype: object

En la parte izquierda está el índice. No tiene por qué ser índice numérico.

Para crear una serie de pandas a partir de un diccionario:

import pandas as pd
 
webster = {
           "Plátano": "Fruta deliciosa",
           "Púrpura": "Un color"
           }
 
pd.Series(webster)
 
# Resultado:
 
# Plátano    Fruta deliciosa
# Púrpura           Un color
# dtype: object

Para crear una serie a partir de datos externos, por ejemplo, de un fichero CSV:

import pandas as pd
a = pd.read_csv("ruta/fichero.csv", usecols = ["Titulo1"], squeeze = True)

Atributos

Información sobre las series.

import pandas as pd
 
about_me = ["Smart", "Handsome", "Charming", "Brilliant", "Humble"]
 
s = pd.Series(about_me)

Métodos

Cálculos o modificaciones sobre la serie.

dtype: object es la forma que tiene Pandas de referirse a las cadenas de caracteres (strings)

Si queremos modificar una estructura de Pandas tras aplicarle un método, tenemos que usar el argumento inplace:

numeros = [1.3, 2.8, 10.5, 0.3]
 
numeros.sort_values(inplace = True)
 
numeros
 
# Resultado:
 
# >>> numeros
# 3     0.3
# 0     1.3
# 1     2.8
# 2    10.5
# dtype: float64

Búsqueda

Podemos usar la palabra reservada in para buscar un elemento en una serie

import pandas as pd
 
numeros = [1, 4, 19, 23]
 
n = numeros.Series(numeros)
 
1 in n.values
 
# Resultado:
 
# True

Si hacemos 1 in n buscará en los índices, no en los valores

Extracción

Se utilizan los corchetes para indicar las posiciones de los índices que queremos extraer.

import pandas as pd
 
numeros = [1, 4, 19, 23]
 
n = numeros.Series(numeros)
 
n[2]
 
# Resultado:
# 19
 
n[[0, 1, 2]]
 
# Resultado:
# >>> n[[0, 1, 2]]
# 0     1
# 1     4
# 2    19
# dtype: int64

Se puede utilizar también las etiquetas de índice para hacer las extracciones:

import pandas as pd
 
paises_ciudades = pd.read_csv("paises_ciudades.csv", index_col = "País", squeeze = True)
 
paises_ciudades
# Resultado
País
España     Madrid
Francia     París
España     Burgos
Name: Ciudad, dtype: object
 
paises_ciudades["España"]
 
# Resultado: 
# País
# España    Madrid
# España    Burgos
# Name: Ciudad, dtype: object

Filtrar datos

Si queremos quedarnos con las filas cuya columna Edad tenga un valor de 18 o más:

print(df.loc[df['Edad'] >= 18])

Podemos encadenar condiciones:

print(df.loc[(df['Edad'] >= 18) & (df['Sexo'] == "Mujer")])

DataFrame

Las series son estructuras de una dimensión (una columna de datos). Un DataFrame es una estructura bidimensional, consiste en filas y columnas, como una tabla.

El tema de las dimensiones viene por el número de referencias que tenemos que dar a la hora de extraer algún valor. Por ejemplo, en las series, nos basta con el índice para indicar que queremos trabajar con el dato que hay en la posición 100. Con los DataFrames esto no es suficiente ya que además de indicar la fila, tenemos que hacer referencia a la columna para indicar unívocamente el dato de interés.

import pandas as pd

Ejemplo de DataFrame a partir de la carga de un fichero CSV:

>>> sales
                           Region               Country   Item Type Sales Channel Order Priority  Order Date   Order ID   Ship Date  Units Sold  Unit Price  Unit Cost  Total Revenue  Total Cost  Total Profit
0    Middle East and North Africa                 Libya   Cosmetics       Offline              M  10/18/2014  686800706  10/31/2014        8446      437.20     263.33     3692591.20  2224085.18    1468506.02
1                   North America                Canada  Vegetables        Online              M   11/7/2011  185941302   12/8/2011        3018      154.06      90.93      464953.08   274426.74     190526.34
2    Middle East and North Africa                 Libya   Baby Food       Offline              C  10/31/2016  246222341   12/9/2016        1517      255.28     159.42      387259.76   241840.14     145419.62
3                            Asia                 Japan      Cereal       Offline              C   4/10/2010  161442649   5/12/2010        3322      205.70     117.11      683335.40   389039.42     294295.98
4              Sub-Saharan Africa                  Chad      Fruits       Offline              H   8/16/2011  645713555   8/31/2011        9845        9.33       6.92       91853.85    68127.40      23726.45
..                            ...                   ...         ...           ...            ...         ...        ...         ...         ...         ...        ...            ...         ...           ...
995  Middle East and North Africa            Azerbaijan      Snacks       Offline              C   4/18/2010  534085166   4/25/2010        6524      152.58      97.44      995431.92   635698.56     359733.36
996                        Europe               Georgia   Baby Food       Offline              H    8/1/2011  590768182    9/7/2011         288      255.28     159.42       73520.64    45912.96      27607.68
997  Middle East and North Africa  United Arab Emirates  Vegetables        Online              C   5/12/2011  524363124   6/28/2011        9556      154.06      90.93     1472197.36   868927.08     603270.28
998                        Europe               Finland   Household       Offline              L   1/25/2016  289606320   2/14/2016        9801      668.27     502.54     6549714.27  4925394.54    1624319.73
999                        Europe              Portugal      Cereal       Offline              C   4/10/2014  811546599    5/8/2014        3528      205.70     117.11      725709.60   413164.08     312545.52

[1000 rows x 14 columns]

Si aparece NaN es la forma que tiene Pandas de indicar que falta el valor.

Ejemplo de un DataFrame creado a partir de un diccionario:

purchases = [{'Customer': 'Bob', 'Item': 'Oranges', 'Quantity': 2, 'Unit price': 2},
             {'Customer': 'Bob', 'Item': 'Apples', 'Quantity': 3, 'Unit price': 1},
             {'Customer': 'Bob', 'Item': 'Milk', 'Quantity': 1, 'Unit price': 4},
             {'Customer': 'Alice', 'Item': 'Oranges', 'Quantity': 2, 'Unit price': 2},
             {'Customer': 'Alice', 'Quantity': 2, 'Unit price': 3}]
df = DataFrame(purchases)
 
df
 
# Resultado:
 
#   Customer     Item  Quantity  Unit price
# 0      Bob  Oranges         2           2
# 1      Bob   Apples         3           1
# 2      Bob     Milk         1           4
# 3    Alice  Oranges         2           2
# 4    Alice      NaN         2           3

Métodos

Muchos son los mismos que en las series.

La mayoría de las funciones de DataFrames devuelven un objeto nuevo de pandas. Si queremos realizar una operación y que se modifique el propio objeto, debemos pasarle el argumento inplace=True)

>>> sales.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 14 columns):
 #   Column          Non-Null Count  Dtype
---  ------          --------------  -----
 0   Region          1000 non-null   object
 1   Country         1000 non-null   object
 2   Item Type       1000 non-null   object
 3   Sales Channel   1000 non-null   object
 4   Order Priority  1000 non-null   object
 5   Order Date      1000 non-null   object
 6   Order ID        1000 non-null   int64
 7   Ship Date       1000 non-null   object
 8   Units Sold      1000 non-null   int64
 9   Unit Price      1000 non-null   float64
 10  Unit Cost       1000 non-null   float64
 11  Total Revenue   1000 non-null   float64
 12  Total Cost      1000 non-null   float64
 13  Total Profit    1000 non-null   float64
dtypes: float64(5), int64(2), object(7)
memory usage: 109.5+ KB

Si queremos mostrar un resumen de operaciones habituales, pero solo con los valores que no son numéricos, pasamos las opción include con el valor O:

df.describe(include = "O")

Extraer columnas

Podemos coger una columna por su nombre:

sales.Country

Se creará una serie.

Si la columna tiene un espacio, entonces es mejor hacer referencia por la etiqueta:

sales["Client Name"]

Para extraer más de una columna:

sales[ ["Client Name", "Salary"] ]

Como extraemos más de una columna, el objeto resultante será un DataFrame y no una serie.

Añadir filas

Si queremos añadir una fila al final del DataFrame:

df.append({"Nombre": "Pepito", "Año": 2000, "Edad": 20}, ignore_index=True)

Podemos añadir un DataFrame en otro:

df2.append(df1, ignore_index=True)

Añadir columnas

sales["City"] = "Madrid"

Se creará una nueva columna llamada “City” con el valor “Madrid” en todas sus filas.

Si queremos indicar la posición de la nueva columna, utilizaremos el método insert():

sales.insert(3, column = "City", value = "Madrid")

Con el anterior código decimos que la nueva columna “City” ocupará la posición 3 (será entonces la columna 4) y todos sus valores serán “Madrid”.

También se pueden crear columnas calculadas:

sales["Salary+Bonus"] = sales["Salary"] + sales["Bonus"]

Eliminar filas

Utilizamos el método drop()

# Eliminar la fila que ocupa la posición 10:
new_sales = sales.drop(10)

Si queremos que se modifique el DataFrame en lugar de hacer una copia de él:

# Eliminar la fila que ocupa la posición 10:
sales.drop(10, inplace=True)

Eliminar columnas

Utilizamos también el método drop(), pero con el argumento axis a 1 para indicar que queremos eliminar columnas:

# Eliminar la columna que ocupa la posición 10:
sales.drop(10, axis = 1)

También podemos indicar el nombre de la columna en lugar de la posición: sales.drop("Nacionalidad", axis=1)

También podemos borrarla utilizando la función del:

del sales["Region"]

También podemos eliminarla con método pop():

sales.pop("Region")

La operación pop() es permanente, es decir, modifica el DataFrame sin necesidad del argumento inplace

Eliminar filas vacías

Utilizamos el método dropna() para eliminar las filas que contienen algún valor NaN.

sales.dropna()

Para eliminar solo las filas completamente vacías:

sales.dropna(how = "all")

Eliminar columnas vacías

Utilizamos también el método dropna() pero cambiando el eje:

sales.dropna(axis = 1)
 
# También se podría indicar así:
# sales.dropna(axis = "columns")

Podemos indicar las columnas a revisar:

sales.dropna(subset = ["Salary", "Country"])

Rellenar vacíos (NaN)

Para aquellas “celdas” donde no hay datos (y Pandas indica con NaN), podemos indicar qué valor:

# Rellenar NaN con 0:
sales.fillna(0)

Podemos ir columna a columna:

sales["Salary"].fillna(0, inplace = True)

inplace indica si el objeto al que se aplica el método se modificará.

Reemplazar

Para sustituir un valor por otro, utilizamos el método replace():

sales.replace("Espana", "España")

A este método se ls puede pasar un diccionario para realice diferentes sustituciones a la vez:

sales.replace({"Espana": "España", "madrid": "Madrid"})

Cambiar tipos de datos

Para ver el tipo de dato de cada columna, utilizamos dtype():

sales.dtypes
 
# Resultado
#>>> sales.dtypes
#Region             object
#Country            object
#Item Type          object
#Sales Channel      object
#Order Priority     object
#Order Date         object
#Order ID            int64
#Ship Date          object
#Units Sold          int64
#Unit Price        float64
#Unit Cost         float64
#Total Revenue     float64
#Total Cost        float64
#Total Profit      float64
#dtype: object

Para modificar el tipo de dato que contiene cada columna se puede usar el método astype():

sales["Unit Price"] = sales["Unit Price"].astype("int")

Para poder utilizar este método, es necesario que todas las filas tengan valores, es decir, que no exista ningún NaN

Si queremos pasar una fecha al formato ISO:

sales["Date"] = sales.to_datetime(sales["Date"])

Si el formato original de fecha no es estándar o Pandas no lo coge correctamente, podemos indicárselo con la opción format:

sales["Date"] = sales.to_datetime(sales["Date"], format="%d/%m/%Y")

Ordenación

Como un DataFrame es una estructura de dos dimensiones, debemos indicar la columna por la que queremos ordenar:

sales.sort_values(by="Salary")

Estaríamos ordenando todo el DataFrame en base a los valores de la columa “Salary”.

Si queremos ordenar en base a más de 1 columna:

sales.sort_values(["Client Name", "Salary"], ascending = [True, False])

Estamos ordenando “Client Name” en orden alfabético y “Salary” descendentemente.

Filtrar datos

Podemos filtrar por varios métodos:

Si queremos quedarnos con las filas que tengan “Europe” como valor de la columna “Region”:

filtro = sales["Region"] == "Europe"
sales[filtro]
 
filtro = sales["Salary"] > 10000
sales[filtro]

Se pueden usar más de una condición para filtrar datos:

filtro1 = sales["Region"] == "Europe" 
filtro2 = sales["Salary"] > 10000
 
sales[filtro1 & filtro2]

Si vamos a combinar varias condiciones con | es recomendable utilizar el método isin:

filtro = sales["Region"].isin(["Europe", "Asia"])
sales[filtro]

Estamos buscando las filas cuya “Region” sea “Europe” o “Asia”.

Si queremos buscar por un rango de valores, utilizamos el método between:

filtro = sales["Salary"].between(20000, 50000)
sales[filtro]

Los valores límites también están incluidos en el filtro, es decir, para el ejemplo anterior, también devolvería las filas cuyo salario fuese 20000 y 50000.

También podemos filtrar utilizando el método where():

filtro = sales["Salary"].between(20000, 50000)
sales.where(filtro)

La diferencia es que devuelve el DataFrame entero, pero solo están cubiertas las filas que cumplen la condición, el resto contienen NaN

Por último, el método query() se supone que es más eficiente para los filtrados:

sales.query("Country == 'Canada'")

Otro ejemplo:

sales.query("Country in ['Canada', 'Japan']")

Si queremos combinar condiciones:

sales.query("Country == 'Canada' and Salary > 10000")

Para poder usar el método query() las columnas no deben contener espacios.

Vacíos

Para filtrar por vacíos:

filtro = sales["Region"].isnull()
 
# Devuelve todas las filas donde "Region" esté vacío (NaN)
sales[filtro]

Lo contrario se haría con notnull():

filtro = sales["Region"].notnull()
 
# Devuelve todas las filas donde "Region" no esté vacío:
sales[filtro]

Duplicados

El método drop_duplicates() se usa para eliminar duplicados:

# Quedarnos con los valores únicos:
sales.drop_duplicates(subset = ["Item Type"], keep = "first")

Para contar los valores únicos, utilizamos el método unique():

sales["Region"].unique()
 
# Ejemplo de salida:
#array(['Middle East and North Africa', 'North America', 'Asia',
#       'Sub-Saharan Africa', 'Europe',
#       'Central America and the Caribbean', 'Australia and Oceania'],
#      dtype=object)

Para contarlos, utilizamos el método nunique:

sales["Region"].nunique(dropna = False)
 
# Resultado:
# 7

Extracción

Por posición del íncide

Utilizamos el método iloc():

# Obtener las filas desde el índice 0 al 9
sales.iloc[0:10]
 
# Obtener las filas del índice 0 y del 2
sales.iloc[[0,2]]

Podemos hacer la intersección con el segundo argumento:

sales.iloc[14, 2]
 
# Devuelve el contenido del índice 14 en su tercera (posición 2) columna.

Por etiqueta del índice

Si queremos establecer los valores de cierta columna como índice del DataFrame:

sales.set_index("Order ID", inplace = True)

Si queremos volver a dejar los índices por defecto:

sales.reset_index(inplace = True)

Ahora podemos extraer datos en base a la etiqueta del índice:

sales.set_index("Region", inplace = True)
sales.loc["Europe"]

Podemos hacer la intersección indicando un segundo argumento al método loc():

sales.loc["Europe", "Item Type"]
 
# Devuelve las filas cuya "Region" sea "Europe" y su valor de "Item Type"

Extracción al azar

Para extraer filas al azar, se puede utilizar el método sample():

# Extrae una fila al azar:
sales.sample()

Podemos indicar el número de filas a extraer:

# Extraer 10 muestras al azar:
sales.sample(n = 10)

Incluso podríamos extraer por fracciones del total:

# Extraer una muestra del 25 % del total:
sales.sample(frac = .25)

Si quisiéramos extraer al azar columnas en lugar de filas, añadimos el argument axis con el valor 1 o columns:

# Extraer 3 columnas al azar:
sales.sample(n = 3, axis = "columns")

Máximos

Para extraer los N valores más grandes, utilizamos el método nlargest():

# Las 3 filas con los valores de la columna "Units Sold" más grandes:
sales.nlargest(3, columns = "Units Sold")

Otra forma:

sales["Units Sold"].nlargest(3)

Mínimos

Para extraer los N valores más pequeños, utilizamos el método nsmallest():

# Las 2 filas con los valores de la columna "Units Sold" más pequeños:
sales.nsmallest(2, columns = "Units Sold")

Otra forma:

sales["Units Sold"].nsmallest(2)

Modificar valores

sales.iloc[10, 2] = "Hola"

Cambiamos el valor que ya en la fila 10, columna 2 por el texto “Hola”.

Podemos cambiar una serie de valores. Por ejemplo, donde “Region” sea “Europa”, quiero que ahora valga “Europa”:

es_europa = sales["Region"] == "Europe"
 
sales.loc[es_europa, "Region"] = "Europa"

Trabajando con texto

Modificando cadenas con str.replace():

sales["Region"] = sales["Region"].str.replace("Europe", "Europa")
 
# Elimina el símbolo '€' y cambia el tipo de dato de la columna 'Salary' a decimal.
sales["Salary"] = sales["Salary"].str.replace("€", "").astype("float")

Eliminando espacios:

# Elimina espacios a la derecha
sales["Region"] = sales["Region"].str.rstrip()
 
# Elimina espacios a la izquierda
sales["Region"] = sales["Region"].str.lstrip()
 
# Elimina espacios a los dos lados:
sales["Region"] = sales["Region"].str.strip()

Filtrando por texto

# Devuelve todos los valores de "Region" que contengan 'rope'
filtro = sales["Region"].str.lower().str.contains("eur")
sales[filtro]
 
# Devuelve todos los valores de "Region" que empiecen por 'eur'
filtro = sales["Region"].str.lower().str.startswith("eur")
sales[filtro]

Unión de DataFrames

# Unión de dos DataFrame que comparten estructura:
clientes = pd.concat(objs = [cliente1, cliente2], ignore_index = True)

ignore_index por defecto es False, así que cogerá los índices originales de cada DataFrame concatenado

Para realizar inner joins:

cliente1.merge(cliente2, how = "inner", on = "Customer ID")

Para los left joins:

cliente1.merge(cliente2, how = "left", on = "Customer ID")

Agrupar

dfg = df.groupby("Region")

Esto creará un objeto DataFrameGroupBy y podremos usar en él los métodos típicos:

Se puede agrupar por más de un campo poniéndolos entre corchetes:

dfg = df.groupby(["Region", "Country"])

Fechas

Cuando cargamos un fichero a un DataFrame y contiene alguna fecha, lo indicamos con el argumento parse_dates para poder así luego operar con objetos de tipo fecha en lugar de strings:

pd.read_csv("ventas.csv", index_col = "ID", parse_dates = ["fecha_pedido", "fecha_envio"])

Timestamp

pd.Timestamp("2020-12-31 00:01:59")
 
pd.Timestamp("2020/12/31 00:01:59")
 
pd.Timestamp(2020, 12, 31, 0, 1, 59)

date_range()

Genera fechas dentro de un rango:

pd.date_range(start = "2020-12-01", end = "2020-12-31", freq = "D")
 
# Resultado
#DatetimeIndex(['2020-12-01', '2020-12-02', '2020-12-03', '2020-12-04',
#               '2020-12-05', '2020-12-06', '2020-12-07', '2020-12-08',
#               '2020-12-09', '2020-12-10', '2020-12-11', '2020-12-12',
#               '2020-12-13', '2020-12-14', '2020-12-15', '2020-12-16',
#               '2020-12-17', '2020-12-18', '2020-12-19', '2020-12-20',
#               '2020-12-21', '2020-12-22', '2020-12-23', '2020-12-24',
#               '2020-12-25', '2020-12-26', '2020-12-27', '2020-12-28',
#               '2020-12-29', '2020-12-30', '2020-12-31'],
#              dtype='datetime64[ns]', freq='D')

Podemos especificar la cantidad de fechas con la opción periods:

# Generar 10 fechas desde el 2020-12-01
pd.date_range(start = "2020-12-01", periods = 10, freq = "D"

Timedelta

Medida de tiempo, es un momento en el tiempo, como una fecha.

time_a = pd.Timestamp("2020-12-10 04:35:06")
 
time_b = pd.Timestamp("2020-12-01 12:22:58")
 
time_a - time_b
 
# Resultado:
# Timedelta('8 days 16:12:08')

Para crear un objeto de este tipo:

pd.Timedelta(days = 3, hours = 12, minutes = 45)
 
# Resultado
# Timedelta('3 days 12:45:00')

Entrada de datos

CSV

Podemos cargar también desde una URL:

url = "direccion/fichero.csv"
pd.read_csv(url)

Si no queremos coger la cabecera del fichero (normalmente contendrá el nombre de los campos/columnas):

pd.read_csv("fichero.csv", header = None)

Si los datos están separados por otro caracter que no sea la coma, lo indicamos como parámetro:

pd.read_csv("fichero.csv", sep = ';')

Si estuviesen separados por espacios, pero no sabemos cuántos, utilizamos una expresión regular:

pd.read_csv("fichero.csv", sep = '\s+')

Excel

Para la lectura de ficheros de Excel es necesario el módulo xlrd:

pip3 install xlrd

Si vamos a leer un fichero que no sea .xls (.xlsx, por ejemplo), será mejor utilizar openpyxl ya que en últimas versiones de xlrd van a dejar de dar soporte a formatos que no sean ''.xls''.

pd.read_excel("fichero.xlsx")

Si queremos leerlo con openpyxl:

pd.read_excel("fichero.xlsx", engine="openpyxl")

Si tuviésemos más de una hoja, podríamos cargar solo la que quisiéramos:

pd.read_excel("fichero.xlsx", sheet_name = "Hoja 2")

Si de una hoja solo queremos ciertas columnas:

pd.read_excel("fichero.xlsx", sheet_name = "Hoja 2", usecols = "A,L,M:AA")

En el ejemplo anterior solo leería las columnas A, L y de la M hasta la AA, ambas incluidas.

Si quisiéramos cargar varias hojas a la vez, el resultado sería un diccionario donde cada clave apuntaría a un dataframe, uno por hoja.

Saltar filas

Si a la hora de leer un fichero Excel queremos descartar ciertas filas:

# Cargamos un fichero Excel como un DataFrame de Pandas, 
# saltándonos las 3 primeras filas
pd.read_excel("fichero.xlsx", skiprows=[0,1,2]

Salida de datos

CSV

pd.to_csv("salida.csv", index = False)

Podemos indicar qué columnas exportar:

pd.to_csv("salida.csv", index = False, columns = ["Nombre", "Apellidos", "Edad"])

Si queremos forzar la codificación, utilizamos el parámetro encoding:

pd.to_csv("salida.csv", index = False, encoding = "utf-8")

Si queremos cambiar el separador de campos (por defecto es una coma):

pd.to_csv("salida.csv", sep=";")

Si vamos a guardar datos con decimales, podemos indicar la precisión (número de decimales) con la que queremos que se guarden:

pd.to_csv("salida.csv", index=False, float_format="%0.4f")

Con el código anterior, indicamos que los números decimales tengan 4 decimales.

Excel

Para la escritura de ficheros de Excel es necesario el módulo openpyxl:

pip3 install openpyxl
# Creamos un contenedor para poder guardar finalmente un fichero Excel
output = pd.ExcelWriter("salida.xlsx")
 
# Escribimos el DataFrame en el contenedor Excel
ventas.to_excel(output, sheet_name = "Ventas", index = False)
 
# Escribimos el fichero
output.save()

Podríamos elegir qué columnas grabar:

ventas.to_excel(output, sheet_name = "Ventas", index = False, columns = ["Fecha", "Precio"])

Opciones

Número de resultados

Filas a mostrar:

import pandas as pd
 
# Número de filas que mostrará Pandas de un DataFrame:
pd.options.display.max_rows
 
# Establecer el número de filas a mostrar:
pd.options.display.max_rows = 10

Columnas a mostrar:

import pandas as pd
 
# Número de columnas que mostrará Pandas de un DataFrame:
pd.options.display.max_columns
 
# Establecer el número de columnas a mostrar:
pd.options.display.max_columns= 3

También podemos modificar las opciones utilizando métodos en lugar de atributos:

# Obtener el valor de las opciones
pd.get_option("max_rows")
 
pd.get_option("max_columns")
 
# Modificar las opciones
pd.set_option("max_rows", 10)
pd.set_option("max_columns", 3)

Para reiniciar las opciones a sus valores iniciales:

pd.reset_option("max_rows")
 
pd.reset_option("max_columns")

Podemos saber más acerca de una opción mediante el método describe_option(). Por ejemplo, pd.describe_option("max_columns")

Precisión numérica

Por precisión nos referimos al número de decimales después del separador de decimales.

Por defecto, Pandas muestra 6 decimales.

pd.get_option("precision")
 
# Resultado:
# 6

Para establecer otra precisión:

pd.set_option("precision", 2)

Ejemplos

Combinar ficheros Excel

El siguiente fragmento de código coge todos los ficheros .xlsx que hay en el directorio de trabajo y los une en un único documento llamado final.xlsx que será la unión de todos ellos:

import pandas as pd
import glob
 
all_data = pd.DataFrame()
 
for f in glob.glob("*.xlsx"):
    df = pd.read_excel(f)
    all_data = all_data.append(df, ignore_index=True)
 
# Volcamos el DataFrame resultante en un documento Excel
all_data.to_excel("final.xlsx", index=False)

Filtrar registros Excel

El siguiente código abre el documento demo.xlsx, filtra los registros por los valores de dos columnas y vuelca el resultado en el fichero demo_mod.xlsx:

import os
import pandas as pd
 
df = pd.read_excel("demo.xlsx")
 
# Filtrado por columna
output = df.loc[(df['Age'] >= 50) & (df['Country'] == "United States")]
 
output.to_excel("demo_mod.xlsx", index=False)

Titanic

Partiendo de un CSV con información sobre pasajeros:

import pandas as pd
 
fname = '~/data/titanic/train.csv'
 
data = pd.read_csv(fname)

Ver si hay campos vacíos:

data.count()

Valores mínimos y máximos de edad:

data['Age'].min(), data['Age'].max()

Distribución de valores de supervivientes:

data['Survived'].value_counts()

En términos porcentuales:

data['Survived'].value_counts() * 100 / len(data)

Distribución por sexo:

data['Sex'].value_counts()

Distribución por tipo de pasajero:

data['Pclass'].value_counts()

Representación gráfica (en notebook de Jupyter):

%matplotlib inline
 
alpha_color = 0.5
 
# Distribución se supervivientes
data['Survived'].value_counts().plot(kind='bar')

Distribución gráfica por sexo:

data['Sex'].value_counts().plot(kind='bar',
                                color=['b', 'r'],
                                alpha=alpha_color)

Distribución gráfica por clase de pasajeros:

data['Pclass'].value_counts().sort_index().plot(kind='bar',
                                                alpha=alpha_color)

Comparando gráficamente supervivientes con edades:

data.plot(kind='scatter', x='Survived', y='Age')

Comparando gráficamente supervivientes con tramos de edades:

bins = [0, 10, 20, 30, 40, 50, 60, 70, 80]
 
data['AgeBin'] = pd.cut(data['Age'], bins)
 
data[data['Survived'] == 1]['AgeBin'].value_counts().sort_index().plot(kind='bar')

Gráficamente los que no sobrevivieron:

data[data['Survived'] == 0]['AgeBin'].value_counts().sort_index().plot(kind='bar')
data['AgeBin'].value_counts().sort_index().plot(kind='bar')

Pasajeros de primera clase que sobrevivieron:

data[data['Pclass'] == 1]['Survived'].value_counts().plot(kind='bar')

Pasajeros de tercera clase que sobrevivieron:

data[data['Pclass'] == 3]['Survived'].value_counts().plot(kind='bar')

Pasajeros de género masculino que sobrevivieron:

data[data['Sex'] == 'male']['Survived'].value_counts().plot(kind='bar')

Pasajeros de género femenino que sobrevivieron:

data[data['Sex'] == 'female']['Survived'].value_counts().plot(kind='bar')

Pasajeros de género masculino y primera clase que sobrevivieron:

data[(data['Sex'] == 'male') & (data['Pclass'] == 1)]['Survived'].value_counts().plot(kind='bar')

Pasajeros de género masculino y tercera clase que sobrevivieron:

data[(data['Sex'] == 'male') & (data['Pclass'] == 3)]['Survived'].value_counts().plot(kind='bar')

Pasajeros de género femenino y primera clase que sobrevivieron:

data[(data['Sex'] == 'female') & (data['Pclass'] == 1)]['Survived'].value_counts().plot(kind='bar')

Pasajeros de género femenino y tercera clase que sobrevivieron:

data[(data['Sex'] == 'female') & (data['Pclass'] == 3)]['Survived'].value_counts().plot(kind='bar')

Recursos