Pandas Read_csv de cadena

Salman Mehmood 21 junio 2023
Pandas Read_csv de cadena

El objetivo principal de este artículo es demostrar cómo leer datos de texto CSV de una cadena o paquete de datos usando Pandas en Python.

Python Pandas read_csv de la cadena

el problema

Los datos se pueden almacenar en múltiples formas; dos de las formas principales se definen como estructuradas y no estructuradas. Estos formularios principales se pueden dividir en muchos formularios, CSV (valores separados por comas) es uno de ellos.

Mientras leemos datos de un archivo CSV, ya sea para algunas consultas o procesamientos complejos, según la situación, es posible que necesitemos leer datos de una cadena o un paquete determinado.

Considere el siguiente código:

import pandas as pd

import pkgutil
from io import StringIO


def get_data_file(pkg, path):
    f = StringIO()
    contents = unicode(pkgutil.get_data("pymc.examples", "data/wells.dat"))
    f.write(contents)
    return f


wells = get_data_file("pymc.examples", "data/wells.dat")

data = pd.read_csv(wells, delimiter=" ", index_col="id", dtype={"switch": np.int8})

Producción :

 File "/usr/local/lib/python2.7/dist-packages/pandas/io/parsers.py", line 401, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "/usr/local/lib/python2.7/dist-packages/pandas/io/parsers.py", line 209, in _read
    parser = TextFileReader(filepath_or_buffer, **kwds)
  File "/usr/local/lib/python2.7/dist-packages/pandas/io/parsers.py", line 509, in __init__
    self._make_engine(self.engine)
  File "/usr/local/lib/python2.7/dist-packages/pandas/io/parsers.py", line 611, in _make_engine
    self._engine = CParserWrapper(self.f, **self.options)
  File "/usr/local/lib/python2.7/dist-packages/pandas/io/parsers.py", line 893, in __init__
    self._reader = _parser.TextReader(src, **kwds)
  File "parser.pyx", line 441, in pandas._parser.TextReader.__cinit__ (pandas/src/parser.c:3940)
  File "parser.pyx", line 551, in pandas._parser.TextReader._get_header (pandas/src/parser.c:5096)
pandas._parser.CParserError: Passed header=0 but only 0 lines in file

En el siguiente código, se crea una función llamada get_data_file para obtener datos del paquete. Para realizar esta operación, se necesitan dos métodos denominados paquete y ruta, que almacenan el nombre del paquete y la ruta del archivo, respectivamente.

El valor devuelto de get_data_file luego se pasa al método read_csv para leer los datos, pero como se ve en la salida, se devuelve un error de tipo CParserError con la descripción Passed header=0 but only 0 lines in file.

la solución

La solución a este problema se puede abordar de dos maneras diferentes según el requisito.

Enfoque 1 - Para cadena con io.StringIO

Considere el siguiente código:

import pandas as pd

from io import StringIO

df = pd.read_csv(
    StringIO(
        "id,switch, arsenic, dist, assoc, educ\n"
        "1, 2.36, 16.826000, 0, 0, 0\n"
        "2, 1, 0.71, 47.321999, 0, 0\n"
        "3, 0, 2.07, 20.966999, 0, 10\n"
        "4, 1, 1.15, 21.486000, 0, 12\n"
        "5, 1, 1.10, 40.874001, 1, 14\n"
        "6, 2, 1.22, 23.123131, 1, 23\n"
        "7, 5, 5.33, 29.232322, 0, 38\n"
        "8, 1, 2.38, 90.222221, 1, 10\n"
        "9, 9, 2.01, 10.222334, 0, 0\n"
        "10, 0, 9.12, 20.324252, 0, 10\n"
    ),
    index_col=0,
)

print(df)

Producción :

    switch   arsenic       dist   assoc   educ
id
1     2.36    16.826   0.000000       0      0
2     1.00     0.710  47.321999       0      0
3     0.00     2.070  20.966999       0     10
4     1.00     1.150  21.486000       0     12
5     1.00     1.100  40.874001       1     14
6     2.00     1.220  23.123131       1     23
7     5.00     5.330  29.232322       0     38
8     1.00     2.380  90.222221       1     10
9     9.00     2.010  10.222334       0      0
10    0.00     9.120  20.324252       0     10

Usando el módulo StringIO, es posible pasar una cadena al método read_csv para leer datos de texto CSV de una cadena.

El módulo StringIO ayuda a ejecutar métodos que normalmente requieren objetos “similares a archivos”; al pasar una cadena a su constructor, crea un objeto “similar a un archivo” que luego se puede pasar a métodos que requieren un objeto “similar a un archivo”.

Es importante tener en cuenta que en Python 2.7, el módulo StringIO se definió como StringIO, mientras que en Python 3+ se cambió a io.StringIO.

Se debe implementar una implementación adecuada para manejar los casos en los que se supone que el código es flexible y está destinado a ejecutarse tanto en Python2 como en Python3.

Enfoque 2: para paquetes con io.BytesIO

Considere el siguiente código:

import numpy as np
import pandas as pd
import io
import pkgutil

wells = pkgutil.get_data("pymc.examples", "data/wells.dat")
print("Data Type: ", str(type(wells)))

df = pd.read_csv(
    io.BytesIO(wells),
    encoding="utf8",
    sep=" ",
    index_col="id",
    dtype={"switch": np.int8},
)
print(df.head())

Producción :

Data Type: <class 'bytes'>
    switch  arsenic       dist  assoc  educ
id
1        1     2.36  16.826000      0     0
2        1     0.71  47.321999      0     0
3        0     2.07  20.966999      0    10
4        1     1.15  21.486000      0    12
5        1     1.10  40.874001      1    14

En el caso de leer datos CSV de un paquete, primero podemos usar el método pkgutil.get_data para obtener los datos, luego, para leer los datos CSV de los datos obtenidos, podemos usar el método read_csv.

Es importante tener en cuenta que debemos usar el método io.BytesIO para pasar los datos obtenidos del método pkgutil.get_data. Y por mencionar la codificación de los datos, que en nuestro caso es utf8.

Los separadores se definen usando el argumento sep, y la columna de índice debe indicarse usando el argumento index_col.

Con todo, el método read_csv toma los siguientes argumentos en el código mencionado anteriormente.

  1. io.BytesIO(wells) corresponde a los datos extraídos del paquete deseado y debe pasarse en forma de bytes utilizando el método io.BytesIO para convertirlo en bytes y pasarlo como un objeto “similar a un archivo”. debido al requisito de objeto “similar a un archivo” de read_csv.
  2. encoding='utf8' se refiere a la codificación de texto de la entrada, que puede tener diferentes valores según el tipo de datos pasados.
  3. sep=' ' indica en qué tipo de separadores consisten los datos. Puede ser diferente en función de cómo se crearon los supuestos datos CSV en primer lugar.
  4. index_col="id" se refiere al nombre de la columna de índice de datos; de nuevo, depende de los datos y puede variar de un archivo a otro.
Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

Artículo relacionado - Pandas CSV