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.
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.