Pandas y la importación de archivos de manera segura
Muchos cuando lean este título podrían inferir en que esto trata sobre las validaciones necesarias para la importación de un dataframe, este no será el caso, es más bien la forma de importar un dataframe así reducir de manera considerable un dataframe insostenible y tener que iterar sobre este.
Para este post consideraremos 2 links adicionales
Para tener un descubrimiento del dataframe más a fondo pueden visitar el link de kaggle aquí
Para la exploración del notebook pueden siempre visitar github.
Manos a la obra
Al iniciar en el mundo de la data surge una inminente necesidad de importar dataframes muchas veces sin considerar el origen de los datos ni su Data Profile simplemente nos vamos de cabeza a importar y ver qué ocurre.
Debido a ese problema voy a presentar algunos tips para la importación segura.
df = pd.read_csv('SRAG_01-06.csv') --------------------------------------------------------------------------- ParserError Traceback (most recent call last) <ipython-input-11-87d6281cea41> in <module> ----> 1 df = pd.read_csv('SRAG_01-06.csv') ~/Desktop/DataEngineer/etl/env/lib/python3.8/site-packages/pandas/io/parsers.py in parser_f(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, dialect, error_bad_lines, warn_bad_lines, delim_whitespace, low_memory, memory_map, float_precision) 674 ) 675 --> 676 return _read(filepath_or_buffer, kwds) 677 678 parser_f.__name__ = name ~/Desktop/DataEngineer/etl/env/lib/python3.8/site-packages/pandas/io/parsers.py in _read(filepath_or_buffer, kwds) 452 453 try: --> 454 data = parser.read(nrows) 455 finally: 456 parser.close() ~/Desktop/DataEngineer/etl/env/lib/python3.8/site-packages/pandas/io/parsers.py in read(self, nrows) 1131 def read(self, nrows=None): 1132 nrows = _validate_integer("nrows", nrows) -> 1133 ret = self._engine.read(nrows) 1134 1135 # May alter columns / col_dict ~/Desktop/DataEngineer/etl/env/lib/python3.8/site-packages/pandas/io/parsers.py in read(self, nrows) 2035 def read(self, nrows=None): 2036 try: -> 2037 data = self._reader.read(nrows) 2038 except StopIteration: 2039 if self._first_chunk: pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader.read() pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._read_low_memory() pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._read_rows() pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._tokenize_rows() pandas/_libs/parsers.pyx in pandas._libs.parsers.raise_parser_error() ParserError: Error tokenizing data. C error: Expected 1 fields in line 8, saw 5
Uno de los errores más comunes al importar csv para un posterior estudio es no conocer ( o pandas no puede inferir ) el tipo de separación, otro de los errores más importantes son los de mala importación por data corrupta o líneas puntualmente mal tipeadas, errores con los cuales un archivo podría no ser cargado o peor aún, arruinar la memoria donde se corra la data.
df = pd.read_csv('SRAG_01-06.csv', error_bad_lines=False, warn_bad_lines=True) b'Skipping line 8: expected 1 fields, saw 5\nSkipping line 11: expected 1 fields, saw 3\nSkipping line 16: expected 1 fields, saw 2\nSkipping line 18: expected 1 fields, saw 3\nSkipping line 20: expected 1 fields, saw 7\nSkipping line 29: expected 1 fields, saw 5\nSkipping line 39: expected 1 fields, saw 6\nSkipping line 52: expected 1 fields, saw 2\nSkipping line 60: expected 1 fields, saw 8\nSkipping line 63: expected 1 fields, saw 3\nSkipping line 80: expected 1 fields, saw 2\nSkipping line 81: expected 1 fields, saw 4\nSkipping line 82: expected 1 fields, saw 3\nSkipping line 84: expected 1 fields, saw 4\nSkipping line 87: expected 1 fields, saw 3\nSkipping line 102: expected 1 fields, saw 3\nSkipping line 106: expected 1 fields, saw 2\nSkipping line 109: expected 1 fields, saw 2\nSkipping line 122: expec
Al importar y pedir un detalle podemos confirmar que mucha data no viene en los formatos que soporte pandas ( al menos no sin antes hacer un poco de cleaning )
Para finalizar con algunos ejemplos también quiero presentarles formas de establecer tipos de datos y manejo de datos NaN desde la importación.
null_values = {'PAIS_VGM': 'BR', 'CO_REGIONA': 0} data_types = {'CS_SEXO':'category', 'CO_PS_VGM': str} df = pd.read_csv('SRAG_01-06.csv', error_bad_lines=False, warn_bad_lines=True, sep=';', na_values=null_values, dtype=data_types) 0 1331.0 1 1331.0 2 1331.0 3 1331.0 4 1938.0 5 1331.0 6 1363.0 7 1380.0 8 1605.0 9 1364.0 10 1331.0 11 1342.0 12 1497.0 13 1497.0 14 1497.0 15 1338.0 16 1331.0 17 1476.0 18 1331.0 19 NaN Name: CO_REGIONA, dtype: float64
Les recuerdo que en el repositorio de github podrán ver en accion todas estas particularidades, es una buena práctica poder interiorizarse al momento de trabajar en tu data.