Pandas: Seleccionar elementos aleatorios en DataFrames Pandas

Publicado el 08 julio 2021 por Daniel Rodríguez @analyticslane

Los objetos DataFrame de Pandas cuenta con el método sample() mediante el cual es posible seleccionar un subconjunto aleatorio de elementos. Algo que es de gran utilidad para realizar muestreo de datos. Veamos a continuación cómo se puede usar este método para seleccionar elementos aleatorios en DataFrames.

El método sample() de los DataFrames

La forma en la que se puede llamar al método sample() es:

df.sample(n=None, frac=None, replace=False, weights=None, random_state=None)

donde

  • n: es el número de elementos que se desean seleccionar del objeto.
  • frac: es la fracción de elementos que se desea obtener, no se puede emplear al mismo tiempo que n siendo únicamente posible usar uno de los dos.
  • replace: indica si el valor que se ha seleccionado se puede volver a incluir en la muestra o solamente se puede obtener una vez.
  • weights: permite asignar una probabilidad de ser seleccionado a cada uno de los registros, por defecto todos tienen la misma.

Ejemplo básico de uso del método sample()

Para evaluar el funcionamiento del método sample() es necesario crear primero disponer de un conjunto de datos. Algo que se puede hacer mediante el uso de generadores aleatorios.

import numpy as np
import pandas as pd

np.random.seed(1)

df = pd.DataFrame(np.random.randint(0, 100,
                                    size=(6, 4)),
                  columns=list('ABCD'))
    A   B   C   D
0  37  12  72   9
1  75   5  79  64
2  16   1  76  71
3   6  25  50  20
4  18  84  11  28
5  29  14  50  68

Una vez creado el conjunto de datos se puede ver qué pasa cuando se llama a este método.

df.sample()
    A   B   C   D
4  18  84  11  28

Devuelve un único registro seleccionado de forma aleatoria. Por lo que, en caso de que sea necesario extraer más de un valor, es necesario indicar estos mediante el uso de la propiedad n. Así, para obtener dos solamente se tiene que escribir.

df.sample(n = 2)
    A   B   C   D
2  16   1  76  71
0  37  12  72   9

Otra alternativa es indicar el porcentaje de registros que se desean seleccionar. Valor que se debe indicar mediante el parámetro frac, el cual no se puede llamar al mismo tiempo que n ya que provoca un error. De este modo se puede obtener el 50% de los valores mediante usando la siguiente línea de código

df.sample(frac = 0.5)
    A   B   C   D
2  16   1  76  71
4  18  84  11  28
3   6  25  50  20

Seleccionar múltiples veces un mismo valor

Por defecto el método sample() no incluirá dos veces un mismo registro, por lo que los valores de frac han de estar acotados entre 0 y 1. Aunque este comportamiento se puede modificar mediante la propiedad replace. Asignando el valor verdadero a esta propiedad después de seleccionar una regimos este puede ser seleccionado a continuación, es decir, el muestreo será con reposición. Algo que se puede comprobar en el siguiente ejemplo.

df.sample(frac = 1, replace=True)
    A   B   C   D
0  37  12  72   9
0  37  12  72   9
5  29  14  50  68
3   6  25  50  20
2  16   1  76  71
1  75   5  79  64

En donde se puede ver que la fila 0 se ha incluido dos veces.

Cambiar la probabilidad de seleccionar un valor

Otra propiedad interesante del método es weights, con la que se le puede asignar una probabilidad diferente a cada uno de los valores. Lo que se puede asignar el nombre de una columna a esta propiedad.

Por defecto la probabilidad de seleccionar cada uno de los valores es la misma para todos. Algo que se puede verificar seleccionado 1000 muestras y comprobado que todos los valores aparecen aproximadamente la cantidad de veces, para lo que nos podemos ayudar del método value_counts.

df.sample(frac = 1000, replace=True)['B'].value_counts(normalize=True)
14    0.174167
1     0.173333
25    0.167333
84    0.163500
12    0.163500
5     0.158167

Obteniendo que en todos los casos valores próximos a 1/6. Por otro lado, en caso de asignar un peso diferente a cada una de las columnas esto ya no es así.

df.sample(frac = 1000, replace=True, weights='B')['B'].value_counts(normalize=True)
84    0.599500
25    0.172167
14    0.101333
12    0.084500
5     0.035667
1     0.006833

Observando que el valor 84 aparece un 59% de las veces, lo que se corresponde con 84/141 (141 es la suma de los valores de la columna B), y 1 aparece un 0,8%, un valor muy próximo al que se esperaría 1/141.

Conclusiones

En esta ocasión se ha visto algunas de las posibilidades que ofrece el método sample() para seleccionar elementos aleatorios en DataFrames de Pandas. Un método con el que se puede automatizar los procesos de muestreo, por lo que es aconsejable tenerlo entre nuestros recursos habituales.