483 Stimmen

Erstellen Sie ein Pandas DataFrame aus einem String

Um einige Funktionalitäten zu testen, möchte ich ein DataFrame aus einem String erstellen. Angenommen, meine Testdaten sehen so aus:

TESTDATA="""col1;col2;col3
1;4.4;99
2;4.5;200
3;4.7;65
4;3.2;140
"""

Was ist der einfachste Weg, diese Daten in ein Pandas DataFrame zu lesen?

816voto

Emil H Punkte 18411

Ein einfacher Weg, dies zu tun, besteht darin, StringIO.StringIO (python2) oder io.StringIO (python3) zu verwenden und dies an die Funktion pandas.read_csv zu übergeben. Z.B:

import sys
if sys.version_info[0] < 3: 
    from StringIO import StringIO
else:
    from io import StringIO

import pandas as pd

TESTDATA = StringIO("""col1;col2;col3
    1;4.4;99
    2;4.5;200
    3;4.7;65
    4;3.2;140
    """)

df = pd.read_csv(TESTDATA, sep=";")

59voto

user3810512 Punkte 321

In einer Zeile, aber zuerst importiere io

import pandas as pd
import io   

TESTDATA="""col1;col2;col3
1;4.4;99
2;4.5;200
3;4.7;65
4;3.2;140
"""

df = pd.read_csv(io.StringIO(TESTDATA), sep=";")
print(df)

58voto

Shaurya Uppal Punkte 2925

Split Methode

data = input_string
df = pd.DataFrame([x.split(';') for x in data.split('\n')])
print(df)

26voto

user2314737 Punkte 23784

Eine schnelle und einfache Lösung für interaktive Arbeit besteht darin, den Text durch Laden der Daten aus der Zwischenablage zu kopieren und einzufügen.

Wählen Sie den Inhalt des Strings mit der Maus aus:

Daten zum Einfügen in ein Pandas-Datenframe kopieren

Im Python-Shell verwenden Sie read_clipboard()

>>> pd.read_clipboard()
  col1;col2;col3
0       1;4.4;99
1      2;4.5;200
2       3;4.7;65
3      4;3.2;140

Verwenden Sie den geeigneten Trennzeichen:

>>> pd.read_clipboard(sep=';')
   col1  col2  col3
0     1   4.4    99
1     2   4.5   200
2     3   4.7    65
3     4   3.2   140

>>> df = pd.read_clipboard(sep=';') # speichern in Datenframe

9voto

Asclepius Punkte 48774

Diese Antwort gilt, wenn ein String manuell eingegeben wird, nicht wenn er von irgendwo gelesen wird.

Ein traditioneller CSV mit variabler Breite ist ungeeignet zur Speicherung von Daten als String-Variable. Insbesondere für die Verwendung innerhalb einer .py-Datei sollte stattdessen festbreitige, durch Pipe getrennte Daten in Betracht gezogen werden. Verschiedene IDEs und Editoren verfügen möglicherweise über ein Plugin, um durch Pipe getrennten Text in eine ordentliche Tabelle zu formatieren.

Verwendung von read_csv

Speichern Sie das Folgende in einem Hilfsmodul, z. B. util/pandas.py. Ein Beispiel ist in der Beschreibung der Funktion enthalten.

import io
import re

import pandas as pd

def read_psv(str_input: str, **kwargs) -> pd.DataFrame:
    """Lesen eines Pandas-Objekts aus einer durch Pipe getrennten Tabelle, die in einem String enthalten ist.

    Eingabebeispiel:
        | int_score | ext_score | eligible |
        |           | 701       | True     |
        | 221.3     | 0         | False    |
        |           | 576       | True     |
        | 300       | 600       | True     |

    Die führenden und abschließenden Pipes sind optional, aber wenn eine vorhanden ist,
    muss auch die andere vorhanden sein.

    `kwargs` werden an `read_csv` weitergeleitet. Sie dürfen nicht `sep` enthalten.

    In PyCharm hat das Plugin "Pipe Table Formatter" eine "Format"-Funktion, die
    verwendet werden kann, um eine Tabelle ordentlich zu formatieren.

    Ref: https://stackoverflow.com/a/46471952/
    """

    substitutions = [
        ('^ *', ''),  # Führende Leerzeichen entfernen
        (' *$', ''),  # Abschließende Leerzeichen entfernen
        (r' *\| *', '|'),  # Leerzeichen zwischen Spalten entfernen
    ]
    if all(line.lstrip().startswith('|') and line.rstrip().endswith('|') for line in str_input.strip().split('\n')):
        substitutions.extend([
            (r'^\|', ''),  # Überflüssiges führendes Trennzeichen entfernen
            (r'\|$', ''),  # Überflüssiges abschließendes Trennzeichen entfernen
        ])
    for pattern, replacement in substitutions:
        str_input = re.sub(pattern, replacement, str_input, flags=re.MULTILINE)
    return pd.read_csv(io.StringIO(str_input), sep='|', **kwargs)

Nicht funktionierende Alternativen

Der folgende Code funktioniert nicht richtig, weil er links und rechts jeweils eine leere Spalte hinzufügt.

df = pd.read_csv(io.StringIO(df_str), sep=r'\s*\|\s*', engine='python')

Was read_fwf betrifft, so verwendet es tatsächlich nicht so viele der optionalen kwargs, die read_csv akzeptiert und verwendet. Daher sollte es überhaupt nicht für durch Pipe getrennte Daten verwendet werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X