Um einige Funktionen zu testen, möchte ich aus einer Zeichenfolge ein DataFrame
erstellen. Nehmen wir an, 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, um diese Daten in ein Pandas DataFrame
zu lesen?
Ein einfacher Weg, dies zu tun, ist die Verwendung von StringIO
und die Übergabe an die Funktion pandas.read_csv
. 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=";")
Eine herkömmliche CSV mit variabler Breite ist zum Speichern von Daten als String-Variable nicht lesbar. Berücksichtigen Sie vor allem für die Verwendung in einer .py
-Datei stattdessen die durch Rohrleitung getrennten Daten mit fester Breite. Verschiedene IDEs und Editoren verfügen möglicherweise über ein Plugin, um durch Pipe getrennten Text in einer übersichtlichen Tabelle zu formatieren.
Folgendes funktioniert für mich. Um es zu verwenden, speichern Sie es in einer Datei, z. pandas_util.py
. Ein Beispiel ist in der Dokumentzeichenfolge der Funktion enthalten. Wenn Sie eine ältere Python-Version als 3.6 verwenden, löschen Sie die Typanmerkungen aus der Funktionsdefinitionszeile.
import re
import pandas as pd
def read_pipe_separated_str(str_input: str, **kwargs) -> pd.DataFrame:
"""Read a Pandas object from a pipe-separated table contained within a string.
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(pd.compat.StringIO(str_input), sep='|', **kwargs)
Der folgende Code funktioniert nicht ordnungsgemäß, da auf der linken und rechten Seite eine leere Spalte hinzugefügt wird.
df = pd.read_csv(pd.compat.StringIO(df_str), sep=r'\s*\|\s*', engine='python')
Eine schnelle und einfache Lösung für interaktives Arbeiten ist das Kopieren und Einfügen des Textes durch Laden der Daten aus der Zwischenablage.
Wählen Sie den Inhalt der Zeichenfolge mit der Maus aus:
Verwenden Sie in der Python-Shell 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
Split-Methode
x = input_string
df = pd.DataFrame([x.split(';') for x in data.split('\n')])
print(df)