Explorar un dataFrame

Para mostrar las distintas funcionalidades que provee pandas para explorar un dataFrame, vamos a trabajar con datasets precargados y así tendremos suficientes datos sin tener que introducirlos manualmente.

Pandas no incluye datasets precargados, pero podemos usar la libreria Seaborn que sí los incluye.

Para ver los datasets que proporciona Seaborn podemos usar el siguiente código:

import seaborn as sns
print(sns.get_dataset_names())

El resultado de ejecutar el anterior código es la lista de datasets:

['anagrams', 'anscombe', 'attention', 'brain_networks', 'car_crashes', 'diamonds', 'dots', 'dowjones', 'exercise', 'flights', 'fmri', 'geyser', 'glue', 'healthexp', 'iris', 'mpg', 'penguins', 'planets', 'seaice', 'taxis', 'tips', 'titanic']

Y para cargar un dataset de ejemplo con el que trabajar, usamos la función load_dataset() que recibirá como parámetro el nombre del dataset que queramos cargar. Por ejemplo, nosotros vamos a trabajar con el dataset ‘titanic’, que aunque está muy manido, resulta muy conveniente para aprender, ya que tiene un tamaño ideal y todo tipo de datos.

import seaborn as sns
df = sns.load_dataset('titanic')

Tras ejecutar el código anterior, tenemos los datos de ‘titanic’ en el dataframe df

Información básica de los datos

Para obtener la información básica de los datos, empezaremos empleando el método info(). Este método proporciona información sobre los tipos de datos y los valores nulos para cada característica (columna). En realidad, proporciona la información de los valores no nulos, pero como tenemos también la dimensión del datasets, con una simple resta, sabemos los valores nulos para cada característica.

import seaborn as sns
df = sns.load_dataset('titanic')
df.info()

Ejecutando el código anterior, obtenemos el resultado que devuelve la función info():

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 15 columns):
 #   Column       Non-Null Count  Dtype   
---  ------       --------------  -----   
 0   survived     891 non-null    int64   
 1   pclass       891 non-null    int64   
 2   sex          891 non-null    object  
 3   age          714 non-null    float64 
 4   sibsp        891 non-null    int64   
 5   parch        891 non-null    int64   
 6   fare         891 non-null    float64 
 7   embarked     889 non-null    object  
 8   class        891 non-null    category
 9   who          891 non-null    object  
 10  adult_male   891 non-null    bool    
 11  deck         203 non-null    category
 12  embark_town  889 non-null    object  
 13  alive        891 non-null    object  
 14  alone        891 non-null    bool    
dtypes: bool(2), category(2), float64(2), int64(4), object(5)
memory usage: 80.7+ KB

En primer lugar, nos indica que estamos trabajando con un objeto DataFrame. Este objeto tiene 891 entradas, con indices del 0 al 890. Y un total de 15 columnas (características).

Luego vemos las 15 columnas, enumeradas desde el 0 al 14, con su nombre, la cuenta de los valores no nulos y el tipo de dato.

Se obtienen datos de tipo numérico: int64 y float64, datos de tipo texto: object, datos de tipo booleano: bool y datos categóricos: category, que tienen un número finito de valores únicos.

Si únicamente quisieramos ver el tipo de dato, bastaría con que emplearamos el parámetro dtypes, como en el siguiente ejemplo de código:

import seaborn as sns
titanic = sns.load_dataset('titanic')
print(titanic.dtypes)

Dimensiones del dataset

Una de las primeras cosas que querremos conocer son las dimensiones de nuestro datasets, cuantas filas y cuantas columnas de datos tenemos. Si bien es cierto que la función info() ya proporciona esta información, es común usar el parámetro shape y de esta manera poder manejar las filas y columnas en dos variables independientes. El siguiente código muestra como:

import seaborn as sns
titanic = sns.load_dataset('titanic')
print(f"dimensiones: {titanic.shape}")
print(f"filas: {titanic.shape[0]}")
print(f"columna: {titanic.shape[1]}")

El parámetro shape nos proporciona ambas dimensiones: filas y columnas, para el indice cero obtenemos las filas y para el indice 1 las columnas. El resultado de ejecutar el código anterior sería:

dimensiones: (891, 15)
filas: 891
columna: 15

Vistazo al dataset

Para hacernos una idea del aspecto de los datos, querremos echar un vistazo al dataset, es decir, ver algunos de sus registros. Lo más habitual es que dibujemos los primeros o los últimos.

Para extraer los primeros registros se emplea el método head(n), siendo n el número de los primeros registros que se quieren recuperar. De similar manera, para recuperar los n últimos registros, utilizamos el método tail(n). Por ejemplo, para recuperar los 7 primeros registros empleariamos: head(7)

n tiene un valor por defecto de 5, con lo que si no pasamos nada a head(), se presentaran los 5 primeros registros

import seaborn as sns
df = sns.load_dataset('titanic')
print(df.head(7))

El código anterior produce el siguiente resultado.

   survived  pclass     sex   age  sibsp  parch     fare embarked  class  \
0         0       3    male  22.0      1      0   7.2500        S  Third   
1         1       1  female  38.0      1      0  71.2833        C  First   
2         1       3  female  26.0      0      0   7.9250        S  Third   
3         1       1  female  35.0      1      0  53.1000        S  First   
4         0       3    male  35.0      0      0   8.0500        S  Third   
5         0       3    male   NaN      0      0   8.4583        Q  Third   
6         0       1    male  54.0      0      0  51.8625        S  First   

     who  adult_male deck  embark_town alive  alone  
0    man        True  NaN  Southampton    no  False  
1  woman       False    C    Cherbourg   yes  False  
2  woman       False  NaN  Southampton   yes   True  
3  woman       False    C  Southampton   yes  False  
4    man        True  NaN  Southampton    no   True  
5    man        True  NaN   Queenstown    no   True  
6    man        True    E  Southampton    no   True  

Aquí podemos hacernos una mejor idea de los datos que tenemos en cada columna. En general, para los datos numéricos querremos conocer los principales estadísticos, mientras que para los datos de texto o categoricos, querremos conocer la frecuencia de las distintas categorías.

Obtención de estadísticos

Disponemos de varios métodos para la obtención de estadísticos de un dataFrame. Lo más habitual es que empleemos el método describe() que proporciona un resumen de los datos estadísticos básicos. Logicamente, este método, sólo actua sobre los datos numéricos.

import seaborn as sns
df = sns.load_dataset('titanic')
print(df.describe())

El resultado de ejecutar el anterior código es:

         survived      pclass         age       sibsp       parch        fare
count  891.000000  891.000000  714.000000  891.000000  891.000000  891.000000
mean     0.383838    2.308642   29.699118    0.523008    0.381594   32.204208
std      0.486592    0.836071   14.526497    1.102743    0.806057   49.693429
min      0.000000    1.000000    0.420000    0.000000    0.000000    0.000000
25%      0.000000    2.000000   20.125000    0.000000    0.000000    7.910400
50%      0.000000    3.000000   28.000000    0.000000    0.000000   14.454200
75%      1.000000    3.000000   38.000000    1.000000    0.000000   31.000000
max      1.000000    3.000000   80.000000    8.000000    6.000000  512.329200

Disponemos además de los siguientes métodos estadísticos que podemos aplicar a las distintas características:

  • count(): Conteo de valores nulos
  • min(), max(): Valor mínimo y máximo
  • sum(): Sumatorio
  • mean(): Valor medio
  • median(): Mediana
  • var(): Varianza
  • std(): Desviación estándar
  • cumsum(): Suma acumulada
  • hist(): Histograma

Por ejemplo, si quisieramos ver el histograma de la edad, podríamos emplear el siguiente código:

import seaborn as sns
df = sns.load_dataset('titanic')
print(df.hist('age'))

Y obtendríamos:

Histograma de la característica age
Histograma de la característica age

Frecuencias de datos categóricos

Para los datos no numéricos, la información que nos va a interesar será la frecuencia de las distintas categorías de cada característica. Si la característica en cuestión tiene muchas categorías, esta información tampoco va a aportar mucho. Sin embargo, cuando tengamos pocas categorías, esta información nos ayudará a entender la distribución de dichas categorías en nuestros datos, y saber por ejemplo si nuestro dataset está o no equilibrado con respecto a ese dato.

Spoiler: Cuando trabajemos con clasificadores en machine learning, tendremos que ver la distribución (frecuencia) de las categorías de la etiqueta(el valor que queramos predecir). Si nuestro dataset está desbalanceado, tendremos que hacer una división estratificada de nuestros datos, para asegurarnos que se mantienen las proporciones de las categorías en los dataset de entrenamiento y test.

Para conocer la frecuencia de cada una de las características podemos emplear el método value_counts(). Este método lo podemos aplicar tando a los campos numéricos como a los no numéricos, pero tendrá sentido cuando tengamos un conjunto de valores reducidos, de otra manera veremos muchas valores con frecuencias bajas, lo cual no aportará información.

Por ejemplo, si lo aplicamos a la característica ‘age’:

import seaborn as sns
df = sns.load_dataset('titanic')
print(df['age'].value_counts())

Obtenemos muchos valores con frecuencias bajas:

age
24.00    30
22.00    27
18.00    26
19.00    25
28.00    25
         ..
36.50     1
55.50     1
0.92      1
23.50     1
74.00     1
Name: count, Length: 88, dtype: int64

Proporciona cierta información, aunque no muy valiosa. Probablemente, nos ayude más ver los datos en un histograma.

Sin embargo, si lo aplicamos a la característica ‘sex’:

import seaborn as sns
df = sns.load_dataset('titanic')
print(df['sex'].value_counts())

Que nos da el siguiente resultado:

sex
male      577
female    314
Name: count, dtype: int64

El cual, al tener sólo dos categorías, nos permite hacernos una idea clara de su distribución: ¿cual es mayoritaria y en que proporción?,

NOTA:

Este post es parte de la colección “Python”. Puedes ver el índice de esta colección aquí.