Pandas Read_csv aus String

Salman Mehmood 21 Juni 2023
Pandas Read_csv aus String

Das Hauptziel dieses Artikels besteht darin, zu demonstrieren, wie CSV-Textdaten aus einer Zeichenfolge oder Paketdaten mit Pandas in Python gelesen werden.

Python-Pandas read_csv von String

das Problem

Daten können in mehreren Formen gespeichert werden; Zwei der Hauptformen werden als strukturiert und unstrukturiert definiert. Diese Hauptformulare können dann weiter in viele Formulare unterteilt werden, CSV (comma-separated values) ist eines davon.

Beim Lesen von Daten aus einer CSV-Datei, sei es für einige komplexe Abfragen oder Verarbeitungen, müssen wir je nach Situation möglicherweise Daten aus einer Zeichenfolge oder einem bestimmten Paket lesen.

Betrachten Sie den folgenden Code:

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})

Ausgang:

 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

Im folgenden Code wird eine Funktion namens get_data_file erstellt, um Daten aus dem Paket zu erhalten. Um diese Operation auszuführen, sind zwei Methoden namens pkg und path erforderlich, die den Namen des Pakets bzw. den Pfad der Datei speichern.

Der Rückgabewert von get_data_file wird dann an die read_csv-Methode zum Lesen der Daten weitergegeben, aber wie in der Ausgabe zu sehen ist, wird ein Fehler vom Typ CParserError mit der Beschreibung Passed header=0 but only 0 lines in file.

die Lösung

Die Lösung dieses Problems kann je nach Anforderung auf zwei verschiedene Arten angegangen werden.

Ansatz 1 - Für String mit io.StringIO

Betrachten Sie den folgenden Code:

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)

Ausgang:

    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

Mit dem StringIO-Modul ist es möglich, einen String an die read_csv-Methode zu übergeben, um CSV-Textdaten aus einem String zu lesen.

Das Modul StringIO hilft bei der Ausführung von Methoden, die normalerweise “dateiähnliche” Objekte erfordern; Indem es eine Zeichenkette an seinen Konstruktor übergibt, erstellt es ein “dateiähnliches” Objekt, das dann an Methoden übergeben werden kann, die ein “dateiähnliches” Objekt erfordern.

Es ist wichtig zu beachten, dass das StringIO-Modul in Python 2.7 als StringIO definiert wurde, während es in Python 3+ zu io.StringIO verschoben wurde.

Die richtige Implementierung muss implementiert werden, um die Fälle zu handhaben, in denen der Code flexibel sein soll und sowohl auf Python2 als auch auf Python3 ausgeführt werden soll.

Ansatz 2 – Für Pakete mit io.BytesIO

Betrachten Sie den folgenden Code:

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())

Ausgang:

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

Beim Lesen von CSV-Daten aus einem Paket können wir zuerst die Methode pkgutil.get_data verwenden, um die Daten abzurufen, und dann zum Lesen der CSV-Daten aus den abgerufenen Daten die Methode read_csv verwenden.

Es ist wichtig zu beachten, dass wir die Methode io.BytesIO verwenden müssen, um die von der Methode pkgutil.get_data abgerufenen Daten zu übergeben. Ganz zu schweigen von der Kodierung der Daten, in unserem Fall utf8.

Trennzeichen werden mit dem Argument sep definiert, und die Indexspalte sollte mit dem Argument index_col angegeben werden.

Insgesamt nimmt die Methode read_csv die folgenden Argumente im oben erwähnten Code entgegen.

  1. io.BytesIO(wells) entspricht den aus dem gewünschten Paket abgerufenen Daten und muss in Byteform mit der io.BytesIO-Methode übergeben werden, um sie in Bytes umzuwandeln und als “dateiähnliches” Objekt zu übergeben aufgrund der “dateiähnlichen” Objektanforderung von read_csv.
  2. encoding='utf8' bezieht sich auf die Textkodierung der Eingabe, die je nach Art der übergebenen Daten unterschiedliche Werte haben kann.
  3. sep=' ' gibt an, aus welcher Art von Trennzeichen die Daten bestehen. Es kann unterschiedlich sein, je nachdem, wie die vermeintlichen CSV-Daten überhaupt erstellt wurden.
  4. index_col="id" bezieht sich auf den Namen der Indexspalte mit Daten; Auch hier hängt es von den Daten ab und kann von Datei zu Datei variieren.
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

Verwandter Artikel - Pandas CSV