Obtener y filtrar datos de un dataframe¶
Existen varios métodos para seleccionar los datos requeridos de un dataframe. Cuando se maneja gran cantidad de datos es importante el método que se usa, puesto que algunos son mas eficientes que otros. Se usará un dataframe creado a partir de datos creados al azar para mostrar las diferencias entre los métodos.
In [2]:
import pandas as pd
import random
import numpy as np
import datetime as dt
In [3]:
# Se generan datos de ejemplo, un dataframe de 4 columnas y 1000 filas
rnd_1 = [random.randrange(1,20) for x in xrange(1000)]
rnd_2 = [random.randrange(1,20) for x in xrange(1000)]
rnd_3 = [random.randrange(1,20) for x in xrange(1000)]
fecha = pd.date_range('2012-4-10', '2015-1-4')
data = pd.DataFrame({'fecha':fecha, 'rnd_1': rnd_1, 'rnd_2': rnd_2, 'rnd_3': rnd_3})
Alguna información general sobre el dataframe creado
In [4]:
data.describe()
Out[4]:
rnd_1 | rnd_2 | rnd_3 | |
---|---|---|---|
count | 1000.000000 | 1000.00000 | 1000.000000 |
mean | 9.904000 | 10.04800 | 10.031000 |
std | 5.466321 | 5.48797 | 5.478691 |
min | 1.000000 | 1.00000 | 1.000000 |
25% | 5.000000 | 5.00000 | 5.000000 |
50% | 10.000000 | 10.00000 | 10.000000 |
75% | 15.000000 | 15.00000 | 15.000000 |
max | 19.000000 | 19.00000 | 19.000000 |
Filtro booleano¶
Es posible filtrar cualquier columna a partir de la comparación con un dato de referencia, por ejemplo, se filtran las filas para valores de la columna rnd_1 menores o iguales a 5.
In [5]:
data_filter = data[data['rnd_1'] <= 5]
# Se visualizan los primeros diez datos resultantes del filtro
data_filter.head(10)
Out[5]:
fecha | rnd_1 | rnd_2 | rnd_3 | |
---|---|---|---|---|
0 | 2012-04-10 | 3 | 8 | 12 |
1 | 2012-04-11 | 1 | 17 | 1 |
5 | 2012-04-15 | 1 | 2 | 7 |
13 | 2012-04-23 | 1 | 3 | 4 |
20 | 2012-04-30 | 3 | 1 | 6 |
24 | 2012-05-04 | 3 | 6 | 11 |
25 | 2012-05-05 | 2 | 14 | 17 |
29 | 2012-05-09 | 2 | 13 | 3 |
43 | 2012-05-23 | 4 | 10 | 6 |
51 | 2012-05-31 | 5 | 18 | 18 |
Se pueden realizar dos filtros simultáneos: Se seleccionan las filas cuyos valores de la columna 'rnd_2' son iguales a 2 y los valores de la columna 'rnd_3' son mayores que 15
In [6]:
data[(data['rnd_2'] == 2) & (data['rnd_3'] > 15)]
Out[6]:
fecha | rnd_1 | rnd_2 | rnd_3 | |
---|---|---|---|---|
235 | 2012-12-01 | 4 | 2 | 18 |
379 | 2013-04-24 | 18 | 2 | 19 |
642 | 2014-01-12 | 13 | 2 | 17 |
671 | 2014-02-10 | 13 | 2 | 18 |
674 | 2014-02-13 | 12 | 2 | 18 |
711 | 2014-03-22 | 16 | 2 | 19 |
750 | 2014-04-30 | 10 | 2 | 19 |
Los siguientes métodos usan el índice para seleccionar los datos, por lo que en ocasiones se requiere tomar la columna sobre la que se quiere filtrar la información y convertirla en el índice del dataframe. Para esto se usará el método set_index.
set_index
Argumentos:
keys: Nombre de la columna que se convertirá en índice. string
drop: Elimina la columna que se usará como índice. False por defecto.
append: Sirve para conservar el índice que tiene el dataframe y agregarle uno nuevo. False por defecto.
inplace: Modifica el dataframe sobre el que se trabaja, no crea copia. False por defecto.
Argumentos:
keys: Nombre de la columna que se convertirá en índice. string
drop: Elimina la columna que se usará como índice. False por defecto.
append: Sirve para conservar el índice que tiene el dataframe y agregarle uno nuevo. False por defecto.
inplace: Modifica el dataframe sobre el que se trabaja, no crea copia. False por defecto.
Método loc¶
Se seleccionan los datos del 2 al 4 en el índice y las columnas 'rnd_2' y fecha
In [7]:
data.loc[2:4, ['rnd_2', 'fecha']]
Out[7]:
rnd_2 | fecha | |
---|---|---|
2 | 12 | 2012-04-12 |
3 | 1 | 2012-04-13 |
4 | 6 | 2012-04-14 |
Para seleccionar los datos entre dos fechas determinadas
In [8]:
data_fecha = data.set_index('fecha')
data_fecha.head()
Out[8]:
rnd_1 | rnd_2 | rnd_3 | |
---|---|---|---|
fecha | |||
2012-04-10 | 3 | 8 | 12 |
2012-04-11 | 1 | 17 | 1 |
2012-04-12 | 17 | 12 | 15 |
2012-04-13 | 15 | 1 | 16 |
2012-04-14 | 9 | 6 | 14 |
Se seleccionan los datos desde el 2013-04-14 a 2013-04-18
In [23]:
# Se crean las fechas con la librería datetime
fecha_1 = dt.datetime(2013, 4, 14)
fecha_2 = dt.datetime(2013, 4, 18)
# Filtro por fecha
data_fecha.loc[fecha_1: fecha_2]
Out[23]:
rnd_1 | rnd_2 | rnd_3 | |
---|---|---|---|
fecha | |||
2013-04-14 | 6 | 14 | 2 |
2013-04-15 | 2 | 6 | 2 |
2013-04-16 | 18 | 5 | 15 |
2013-04-17 | 10 | 19 | 11 |
2013-04-18 | 5 | 7 | 11 |
Para usar este método los valores del filtro, en este caso fecha_1 y fecha_2, deben estar en el índice del dataframe
Para seleccionar un valor del dataframe
In [10]:
data_fecha.loc[fecha_1,'rnd_1']
Out[10]:
6
Método at¶
Funciona de la misma forma que el método loc, siendo at un método de acceso rápido a un dato
In [11]:
data_fecha.at[fecha_1,'rnd_1']
Out[11]:
6
In [12]:
timeit data_fecha.at[fecha_1,'rnd_1']
The slowest run took 9.44 times longer than the fastest. This could mean that an intermediate result is being cached 100000 loops, best of 3: 4.02 µs per loop
In [13]:
timeit data_fecha.loc[fecha_1,'rnd_1']
10000 loops, best of 3: 82.9 µs per loop
Método iloc¶
Con el método iloc no importan cuales sean los valores del índice, este selecciona por la posición. Por ejemplo para seleccionar los datos de la posición 10 a 15:
In [14]:
data_fecha[10: 15]
Out[14]:
rnd_1 | rnd_2 | rnd_3 | |
---|---|---|---|
fecha | |||
2012-04-20 | 11 | 5 | 17 |
2012-04-21 | 16 | 7 | 17 |
2012-04-22 | 6 | 9 | 9 |
2012-04-23 | 1 | 3 | 4 |
2012-04-24 | 17 | 17 | 4 |
Las columnas también son referidas por posición con números enteros comenzando desde el 0
In [15]:
# Se seleccionan las columnas rnd_2 y rnd_3 y se imprimen los primeros 5 datos
# En este caso los dos puntos quiere decir que se seleccionan todas las filas
data_fecha.iloc[:,[1,2]].head()
Out[15]:
rnd_2 | rnd_3 | |
---|---|---|
fecha | ||
2012-04-10 | 8 | 12 |
2012-04-11 | 17 | 1 |
2012-04-12 | 12 | 15 |
2012-04-13 | 1 | 16 |
2012-04-14 | 6 | 14 |
Se seleccionan las filas 1, 12, 34 y las columnas 0 y 2
In [16]:
data_fecha.iloc[[1,12,34],[0,2]]
Out[16]:
rnd_1 | rnd_3 | |
---|---|---|
fecha | ||
2012-04-11 | 1 | 1 |
2012-04-22 | 6 | 9 |
2012-05-14 | 13 | 11 |
Se usa la misma notación si se quiere seleccionar un solo valor y no un dataframe
In [17]:
data_fecha.iloc[1,0]
Out[17]:
1
Método iat¶
Funciona de la misma forma que el método iloc, siendo iat un método de acceso rápido a un dato
In [18]:
data_fecha.iat[1,0]
Out[18]:
1
In [19]:
timeit data_fecha.iat[1,0]
The slowest run took 6.74 times longer than the fastest. This could mean that an intermediate result is being cached 100000 loops, best of 3: 10.8 µs per loop
In [20]:
timeit data_fecha.iloc[1,0]
10000 loops, best of 3: 66 µs per loop
Método ix¶
Este método facilita la selección de datos, puesto que permite filtrar con valores que no se encuentran en el dataframe. Los datos de la columna fecha fueron creados desde '2012-4-10' hasta '2015-1-4' con el formato aaaa-mm-dd. Si se necesita hacer un filtro con dos fechas que tienen la hora, los métodos anteriores no son de utilidad puesto que estos valores no se encuentran en el índice.
In [21]:
fecha_1 = dt.datetime(2013, 1, 10, 8, 30)
fecha_2 = dt.datetime(2013, 1, 13, 4, 20)
# Filtro por fecha
data_fecha.ix[fecha_1: fecha_2]
Out[21]:
rnd_1 | rnd_2 | rnd_3 | |
---|---|---|---|
fecha | |||
2013-01-11 | 1 | 4 | 15 |
2013-01-12 | 10 | 19 | 5 |
2013-01-13 | 1 | 11 | 11 |
Como se ve en el dataframe resultante el dato de la fecha 2013-01-10 no se toma porque se considera previo al rango de fechas dado.