Erstellen Sie einen Pandas DataFrame aus einer Zeichenfolge

275

Um einige Funktionen zu testen, möchte ich eine DataFrameaus einer Zeichenfolge erstellen . Angenommen, meine Testdaten sehen folgendermaßen 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 einen Pandas einzulesen DataFrame?

Emil H.
quelle

Antworten:

493

Eine einfache Möglichkeit, dies zu tun, besteht darin, StringIO.StringIO(python2) oder io.StringIO(python3) zu verwenden und diese an die pandas.read_csvFunktion 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=";")
Emil H.
quelle
7
Wenn Sie Code benötigen, der sowohl mit Python 2 als auch mit Python 3 kompatibel ist, können Sie diesen optional auch verwenden from pandas.compat import StringIO. Beachten Sie dabei, dass es sich um dieselbe Klasse handelt wie die, die mit Python geliefert wird.
Acumenus
3
FYI - pd.read_table()ist eine äquivalente Funktion, nur etwas bessere Nomenklatur : df = pd.read_table(TESTDATA, sep=";").
wkzhu
5
@AntonvBR Bemerkte, dass man verwenden könnte pandas.compat.StringIO. Auf diese Weise müssen wir nicht StringIOseparat importieren . Das pandas.compatPaket wird jedoch gemäß pandas.pydata.org/pandas-docs/stable/api.html?highlight=compat als privat betrachtet , sodass die Antwort unverändert bleibt.
Emil H
Wenn Sie TESTDATA mit erstellen df.to_csv(TESTDATA), verwenden SieTESTDATA.seek(0)
user3226167
18

Split-Methode

data = input_string
df = pd.DataFrame([x.split(';') for x in data.split('\n')])
print(df)
Shaurya Uppal
quelle
2
Wenn Sie möchten, dass die erste Zeile für Spaltennamen verwendet wird, ändern Sie die zweite Zeile in folgende:df = pd.DataFrame([x.split(';') for x in data.split('\n')[1:]], columns=[x for x in data.split('\n')[0].split(';')])
Mabyn
1
Dies ist falsch, da in CSV-Dateien das Zeilenumbruchzeichen (\ n) Teil eines Feldes sein kann.
Antonio Ercole De Luca
Dies ist nicht sehr robust, und die meisten Menschen wären mit der akzeptierten Antwort besser dran. Unter thomasburette.com/blog/2014/05/25/…
DanB
10

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

Wählen Sie den Inhalt der Zeichenfolge mit der Maus aus:

Kopieren Sie Daten zum Einfügen in einen Pandas-Datenrahmen

In der Python-Shell verwenden 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 das entsprechende 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=';') # save to dataframe
user2314737
quelle
2
Nicht gut für die Reproduzierbarkeit, aber ansonsten eine ziemlich ordentliche Lösung!
Mabyn
5

Eine herkömmliche CSV mit variabler Breite ist zum Speichern von Daten als Zeichenfolgenvariable nicht lesbar. .pyBerücksichtigen Sie stattdessen speziell für die Verwendung in einer Datei Rohrleitungsdaten mit fester Breite. Verschiedene IDEs und Editoren verfügen möglicherweise über ein Plugin zum Formatieren von durch Pipes getrenntem Text in eine übersichtliche Tabelle.

Verwenden von read_csv

Speichern Sie Folgendes in einem Dienstprogrammmodul, z util/pandas.py. Ein Beispiel ist in der Dokumentzeichenfolge der Funktion enthalten.

import io
import re

import pandas as pd


def read_psv(str_input: str, **kwargs) -> pd.DataFrame:
    """Read a Pandas object from a pipe-separated table contained within a string.

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

    The leading and trailing pipes are optional, but if one is present,
    so must be the other.

    `kwargs` are passed to `read_csv`. They must not include `sep`.

    In PyCharm, the "Pipe Table Formatter" plugin has a "Format" feature that can 
    be used to neatly format a table.

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

    substitutions = [
        ('^ *', ''),  # Remove leading spaces
        (' *$', ''),  # Remove trailing spaces
        (r' *\| *', '|'),  # Remove spaces between columns
    ]
    if all(line.lstrip().startswith('|') and line.rstrip().endswith('|') for line in str_input.strip().split('\n')):
        substitutions.extend([
            (r'^\|', ''),  # Remove redundant leading delimiter
            (r'\|$', ''),  # Remove redundant trailing delimiter
        ])
    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, da links und rechts eine leere Spalte hinzugefügt wird.

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

Was read_fwfes eigentlich nicht verwenden so viele der optionalen kwargs die read_csvund Anwendungen akzeptiert. Daher sollte es überhaupt nicht für Daten verwendet werden, die durch Rohrleitungen getrennt sind.

Scharfsinn
quelle
1
Ich fand (durch Versuch und Irrtum), dass read_fwfmehr von read_csvs Argumenten als dokumentiert sind, aber es ist wahr, dass einige keine Wirkung haben .
Gerrit
-4

Am einfachsten ist es, es in einer temporären Datei zu speichern und dann zu lesen:

import pandas as pd

CSV_FILE_NAME = 'temp_file.csv'  # Consider creating temp file, look URL below
with open(CSV_FILE_NAME, 'w') as outfile:
    outfile.write(TESTDATA)
df = pd.read_csv(CSV_FILE_NAME, sep=';')

Richtige Methode zum Erstellen einer temporären Datei: Wie kann ich eine tmp-Datei in Python erstellen?

QtRoS
quelle
Was ist, wenn keine Berechtigung zum Erstellen einer Datei vorhanden ist?
BingLi224
Meiner Meinung nach ist es nicht mehr der einfachste Fall. Beachten Sie, dass "am einfachsten" in der Frage explizit angegeben wird.
QtRoS