Capítulo 2 - Explicación
Previamente… Módulo 3 - Capítulo 2
Explorando los datos
Una vez los archivos de datos se ha subido, es necesario analizar su contenido para identificar y corregir problemas y errores contenidos.
Visualización de los tipos de datos de las columnas
Es importante mirar a los tipos de datos para identificar si son consistentes con los datos que leemos.
En este caso se ve que los datos son numéricos pero el tipo de dato no identifica los identifica correctamente. Esto implica que valores no numéricos en esta columna tendrán que ser eliminados pues es una columna de datos numéricos.
Input [10]:
data.info()
Output [10]:
<class 'pandas.core.frame.DataFrame'>
Index:
537 entries, European Union (EU6-1958, EU9-1973, EU10-1981, EU12-1986,
EU15-1995, EU25-2004, EU27-2007, EU28-2013) to Bosnia and Herzegovina
Data columns (total 58 columns):
1991 537 non-null object
Flags and footnotes 0 non-null float64
1992 537 non-null object
Flags and footnotes.1 0 non-null float64
1993 537 non-null object
Flags and footnotes.2 0 non-null float64
1994 537 non-null object
Flags and footnotes.3 0 non-null float64
1995 537 non-null object
Flags and footnotes.4 0 non-null float64
1996 537 non-null object
Flags and footnotes.5 0 non-null float64
1997 537 non-null object
Flags and footnotes.6 0 non-null float64
1998 537 non-null object
Flags and footnotes.7 0 non-null float64
1999 537 non-null object
Flags and footnotes.8 0 non-null float64
2000 537 non-null object
Flags and footnotes.9 0 non-null float64
2001 537 non-null object
Flags and footnotes.10 0 non-null float64
2002 537 non-null object
Flags and footnotes.11 0 non-null float64
2003 537 non-null object
Flags and footnotes.12 0 non-null float64
2004 537 non-null object
Flags and footnotes.13 0 non-null float64
2005 537 non-null object
Flags and footnotes.14 0 non-null float64
2006 537 non-null object
Flags and footnotes.15 0 non-null float64
2007 537 non-null object
Flags and footnotes.16 0 non-null float64
2008 537 non-null object
Flags and footnotes.17 1 non-null object
2009 537 non-null object
Flags and footnotes.18 26 non-null object
2010 537 non-null object
Flags and footnotes.19 6 non-null object
2011 537 non-null object
Flags and footnotes.20 6 non-null object
2012 537 non-null object
Flags and footnotes.21 14 non-null object
2013 537 non-null object
Flags and footnotes.22 33 non-null object
2014 537 non-null object
Flags and footnotes.23 44 non-null object
2015 537 non-null object
Flags and footnotes.24 12 non-null object
2016 537 non-null object
Flags and footnotes.25 16 non-null object
2017 537 non-null object
Flags and footnotes.26 16 non-null object
2018 537 non-null object
Flags and footnotes.27 41 non-null object
2019 537 non-null object
Flags and footnotes.28 0 non-null float64
dtypes: float64(18), object(40)
memory usage: 247.5+ KB
Estadísticas de las columnas
Otra manera básica de revisar los datos para identificar problemas es a través de un sumario estadístico que nos de una idea de lo que la tabla contiene.
Si el parámetro “include” es “all”, nos muestra todas las columnas.
Algunos valores serán “NaN” porque no tienen sentido para el tipo de dato de la columna.
Para datos numéricos include el número de elementos (count), la media (mean), la desviación estándar (str), el mínimo y máximo (min, max) y los percentiles 25, 50 y 75.
Para el resto de datos (texto y fechas), además del número de elementos (count), nos muestra el valor más común (top) y su frecuencia (freq).
Input [11]:
data.describe(include = "all")
Output [11]:
Las dos operaciones previas muestran una primera serie de problemas.
Por una parte, el tipo de datos de las columnas no es numérico. Esto implica que hay valores inválidos, tal y como se ve con la operación “describe”.
Además, hay una serie de “Flags” (banderas) que no contienen ninguna información. Estas son columnas descriptivas que pueden ser eliminadas.
Eliminar columnas innecesarias
Para eliminar columnas innecesarias se necesita saber sus nombres (o índices).
Input [12]:
print(data.columns)
Output [12]:
Index(['1991', 'Flags and footnotes', '1992', 'Flags and footnotes.1', '1993',
'Flags and footnotes.2', '1994', 'Flags and footnotes.3', '1995',
'Flags and footnotes.4', '1996', 'Flags and footnotes.5', '1997',
'Flags and footnotes.6', '1998', 'Flags and footnotes.7', '1999',
'Flags and footnotes.8', '2000', 'Flags and footnotes.9', '2001',
'Flags and footnotes.10', '2002', 'Flags and footnotes.11', '2003',
'Flags and footnotes.12', '2004', 'Flags and footnotes.13', '2005',
'Flags and footnotes.14', '2006', 'Flags and footnotes.15', '2007',
'Flags and footnotes.16', '2008', 'Flags and footnotes.17', '2009',
'Flags and footnotes.18', '2010', 'Flags and footnotes.19', '2011',
'Flags and footnotes.20', '2012', 'Flags and footnotes.21', '2013',
'Flags and footnotes.22', '2014', 'Flags and footnotes.23', '2015',
'Flags and footnotes.24', '2016', 'Flags and footnotes.25', '2017',
'Flags and footnotes.26', '2018', 'Flags and footnotes.27', '2019',
'Flags and footnotes.28'],
dtype='object')
Tienes que eliminar todas las columnas que empiezan con “Flags”.
Una primera manera de eliminarlas es una a una indicando su nombre.
Input [13]:
data = data.drop(columns=['Flags and footnotes'])
data.head(1)
Output [13]:
Pero también se pueden eliminar todas de golpe creando un vector con los nombres de las columnas que se van a borrar.
Esto se hace creando un vector con los nombres de las columnas que contienen “Flags” y después borrando todas las columnas de ese vector.
Input [14]:
indices = [i for i, s in enumerate(data.columns) if 'Flags' in s]
colToDelete=data.columns[np.array(indices)]
print(colToDelete)
Output [14]:
Index(['Flags and footnotes.1', 'Flags and footnotes.2',
'Flags and footnotes.3', 'Flags and footnotes.4',
'Flags and footnotes.5', 'Flags and footnotes.6',
'Flags and footnotes.7', 'Flags and footnotes.8',
'Flags and footnotes.9', 'Flags and footnotes.10',
'Flags and footnotes.11', 'Flags and footnotes.12',
'Flags and footnotes.13', 'Flags and footnotes.14',
'Flags and footnotes.15', 'Flags and footnotes.16',
'Flags and footnotes.17', 'Flags and footnotes.18',
'Flags and footnotes.19', 'Flags and footnotes.20',
'Flags and footnotes.21', 'Flags and footnotes.22',
'Flags and footnotes.23', 'Flags and footnotes.24',
'Flags and footnotes.25', 'Flags and footnotes.26',
'Flags and footnotes.27', 'Flags and footnotes.28'],
dtype='object')
Input [15]:
data = data.drop(columns=colToDelete)
data.head(1)
Output [15]:
Ajustar el nombre de las columnas o filas en la tabla
Podría ser necesario cambiar los nombres de los encabezados para hacerlos más relevantes.
Por ejemplo, puedes renombrar la primera columna, ya que contiene los nombres de las divisiones NUTS.
Input [17]:
data.index.names = ['NUTS']
También podemos ajustar los nombres de las filas si consideramos que pueden simplificar la lectura de la tabla.
Por ejemplo, podemos cambiar el nombre de la primera fila a “European Union”.
Input [18]:
data = data.rename(index={data.index.ravel()[0]: 'European Union'})
data.head()
Output [18]:
Limpieza de datos.
El análisis general podria darte una idea de que algo está mal, pero un análisis mas detallado de las columnas es necesario para identificar problemas en los valores.
Una buena estrategia de análisis es visualizar y/o contar el número de valores diferentes, ver el número de valores no numéricos o incluso ver si hay filas o columnas repetidas.
Contar valores diferentes en las columnas podría mostrar un problema en los datos.
· dataframe[column].count() muestra el número de valores en la columna.
· dataframe[column].unique() muestral el número de valores diferentes en la columna
· dataframe[column].value_counts() muestra el número de ocurrencia de cada valor
Podemos analizar la columna de 2019 mirando su contenido.
Input [19]:
print("Number of values", data['2019'].count())
print("Unique values", data['2019'].unique())
Output [19]:
Number of values 537
Unique values [':' 2373.1 0.72 1275.98 345.21 129.6 311.89 96.07 393.21 1096.4 45.33
279.47 241.17 311.55 218.87 1500 28 72 594 453 354]
Input [20]:
serie = data['2019'].value_counts()
serie
Output [20]:
: 517
28 1
279.47 1
129.6 1
2373.1 1
1096.4 1
393.21 1
72 1
594 1
311.55 1
345.21 1
1275.98 1
218.87 1
1500 1
96.07 1
354 1
453 1
45.33 1
241.17 1
311.89 1
0.72 1
Name: 2019, dtype: int64
Hay 537 valores en 2019 pero la mayoría de ellos son no-numéricos. Hay que cambiarlos a valores nulos.
Reemplazo de valores no numéricos.
Cambiabos todos los valores no numéricos a NaN (not a number) excepto la primera columna.
Se define una función para identificar si un valor es “float”.
Selecciona las columnas a filtrar y entonces añade la columna con los nombres.
Input [21]:
def isfloat(value):
try:
float(value)
return True
except ValueError:
return False
data= data.where(data.applymap(lambda x: isfloat(x)))
data.head(5)
Output [21]:
Continua… Módulo 3 – Capítulo 3