Obtener y filtrar datos de un dataframe

mayo 03, 2015

 

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
8 rows × 3 columns

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
10 rows × 4 columns
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
7 rows × 4 columns
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.

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
3 rows × 2 columns
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
5 rows × 3 columns
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
5 rows × 3 columns
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
5 rows × 3 columns
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
5 rows × 2 columns
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
3 rows × 2 columns
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
3 rows × 3 columns
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.

You Might Also Like

7 comments

  1. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  2. Dispongo de un DataFrame en el que las etiquetas de filas son fechas con el formato '2012-01-31'. ¿Cómo podría filatralo para obtener solamente los registros del mes de fecbrero, por ejemplo "2012-2". Agradeceré su ayuda.

    ResponderEliminar
    Respuestas
    1. Hola Akitxu, podés crear una columna con solo el valor de los meses:

      data['mes'] = data['fecha'].dt.month

      y luego seleccionar solo los registros del mes que quiere:

      data[data['mes'] == 2].

      Si lo requiere con año puede hacer el mismo proceso para crear una columna con los años y luego en el filtro agregas un condicional para seleccionar año

      data[(data['mes'] == 2) & (data['año'] == 2012)]

      Este post está para una versión de python 2. Pronto publicaré las versiones de python 3 (ya puedes ver las de mejoras visuales en matplotlib actualizadas). Saludos.

      Eliminar
    2. Lo he solucionado con:
      print (msft.loc["2015-01", :])
      Muchas gracias

      Eliminar
  3. VC_CODPERIODO NB_CRED VC_CURSO VC_CODCARR
    2C 6 1 GIF
    2C 6 1 GIF
    2C 6 1 GIF
    2C 6 1 GIF
    2C 6 1 GIF
    2C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    1C 6 1 GIF
    AN 6 2 GIF

    Hola me pueden ayudar necesito filtrar de la primera columna los valores que se solo sean 1C y 2C EN PHYTON

    ResponderEliminar
    Respuestas
    1. Suponiendo que este dataframe se llama "data" basta con agregar dos condicionales en el filtro:



      data[(data['VC_CODPERIODO'] == '1C') | (data['VC_CODPERIODO'] == '2C')]

      Eliminar
  4. Tengo un dataframe pandas con columnas con datos str y otras con float, necesito encontrar los datos negativos y llenarlos con la media.

    ResponderEliminar

Apoyado por: