Bereinigung von Daten in Pandas aus CSV-File

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Danny_Deluxe
User
Beiträge: 10
Registriert: Dienstag 27. Juli 2021, 08:49

Hallo zusammen

Bei der Verarbeitung von Daten aus einem CSV-File stosse ich als Programmieranfänger an meine Grenzen und mein Internet-Recherchen waren leider erfolglos.

Die Datenqualität bzw. Formatierung innerhalb des CSV-Files ist leider sehr schlecht und ich kann dies nicht beeinflussen. Zahlen werden z.B. in dem Format 20'000.00 geliefert und ich versuche das Sonderzeichen < ' > zu löschen, was leider nicht funktioniert.

Hier mein Code (viele andere Bereinigungen funktionieren und habe sie rausgelöscht, um es kurz und knackig zu halten):

import os
import numpy as np
import pandas as pd
import sqlite3

df_STP = pd.read_csv("Beispiel.csv", sep=";")

df_STP_final = df_STP.replace(r"\'","")

Ich fürchte, in <df_STP.replace(r"\'","")> ist etwas falsch oder muss ich mit einer For-Schleife arbeiten?

Ich freue mich auf Euer Feedback und bin Euch sehr dankbar.

Danny
einfachTobi
User
Beiträge: 491
Registriert: Mittwoch 13. November 2019, 08:38

Was bedeutet "was leider nicht funktioniert"? Fehlermeldung? Falsches Ergebnis?
Ohne zu wissen, wie genau dein Input aussieht und wie deine Erwartungen an den Output sind, ist es unmöglich hier irgendwas zu sagen.

PS: Code gehört in Code-Tags, damit die Einrückungen erhalten bleiben ([ code ] [/ code ] ohne Leerzeichen).
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Danny_Deluxe: Beim einlesen kann man auch den Tausendertrenner angeben. Den muss man nicht nach dem einlesen entfernen und danach erst alles in Zahlen umwandeln.

Wobei ich die Verwendung eines Tausendertrenners in den Daten weder als niedrige Qualität noch generell als Formtierungs*problem* bezeichnen würde. Klar ist es ohne praktischer, aber es ist auch nicht sooo ungewöhnlich so etwas in den Daten zu haben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Danny_Deluxe
User
Beiträge: 10
Registriert: Dienstag 27. Juli 2021, 08:49

Hallo Tobias

Vielen Dank für Deine Nachricht. Hast natürlich recht, dass hier noch Informationen fehlen. Sorry

Es bringt keine Fehlermeldung, aber der Datentyp ist Object und ich versuche dies auf Datentypen für SQLite zu ändern. Dazu bräuchte ich aber Float, und das funktioniert nicht, da ich < ' > in den Zahlen habe:

Code: Alles auswählen

Import os
import numpy as np
import pandas as pd
import sqlite3

df_STP = pd.read_csv("Beispiel.csv", sep=";")

df_STP.columns = [x.replace(" ", "").replace("?", "").replace("-", "_") \
                       .replace(r"/", "_").replace("\\", "_").replace("%", "").replace("$", " ") \
                       .replace("�", "ae") for x in df.columns]

df_STP_final = df_STP.drop(['Valoren_Nummer', 'LandEmittent', 'LandAsset', 'Industriesektor', 'Rating', 'RMoodys', 'RS&P',
                     'Marchzins', 'Kursdatum', 'DatumderletztenZinszahlung', 'SplitAsset', 'Allokation', 'MacaulayDauer',
                     'Mod.Duration', 'Konvexitaet', 'Waehrungsregion', 'Telekurs_Branchencode(Emittent)', 'Laufzeit', 
                     'EmpfehlungComfort'], axis=1) # "axis=1" löscht Spalten

df_STP_final_neu = df_STP_final.replace(r"\'","")

df_STP_final_neu.head()

replacements = {
    "object": "varchar",
    "float64": "float",
    "int64": "int",
    "datetime64": "timestamp",
    "timedelta64[ns]": "varchar"  
}
column_str = ", ".join("{} {}".format(n, d) for (n, d) in zip(df_STP_final_neu.columns, df_STP_final_neu.dtypes.replace(replacements)))
column_str

Es bringt keine Fehlermeldung, ändert es aber nicht ab:

'Depot_Nummer varchar, ISIN varchar, Name varchar, Waehrung varchar, Klasse varchar, Menge varchar, Kurs varchar, Wechselkurs float, Marktwert varchar, Einstandskurs varchar, Einstandswechselkurs float, Risikowaehrung varchar, Faelligkeit float, LLBNachhaltigkeit varchar, BewertungMultifaktor float

Hilft Dir dies weiter?
einfachTobi
User
Beiträge: 491
Registriert: Mittwoch 13. November 2019, 08:38

Schomal vorab: Wenn man bestimmte Spalten nicht haben will, dann liest man sie einfach nicht ein, statt sie direkt danach wegzuschmeißen. Die Namenswahl ist schlecht: Dein df_STP_final ist gar nicht final, sondern wird dann als df_STP_final_neu noch mal geändert. Der Versuch die Formate für SQLite aufzuarbeiten über das Replacement ist vermutlich mindestens unnötig, wenn nicht sogar falsch. Aber das kann man alles angehen, wenn die Daten erstmal richtig vorliegen. Wenn wir jetzt also noch Beispieldaten bekämen, die das Problem verdeutlichen, dann kanns richtig los gehen. Es reichen meist ein paar der Zeilen, die Probleme machen. Gemeint ist ein Auszug aus deinem echten Datensatz. Nicht etwas, was so ähnlich aussieht.
Danny_Deluxe
User
Beiträge: 10
Registriert: Dienstag 27. Juli 2021, 08:49

Ja, hast recht. Das "Final" muss ich noch ändern. Hatte gehofft, dass ich schon durch bin und ich nicht noch weiteres machen muss.

Mit den Daten ist problematisch, da ich aus der Firma nicht drauf komme. Sind zwar keine Kunden- oder Firmendaten, funktioniert aber nicht. Und wenn ich es hier einfüge, gibt es nur einen "Datensalat". Helfen wenige Spalten da weiter?
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wo kommt denn `df` her und das "�" in den Ersetzungen? So etwas sollte man *vorher* und *ordentlich* lösen. Das einfach durch "ae" zu ersetzen funktioniert ja nur solange nicht noch irgend ein anderes Zeichen nicht richtig dekodiert wurde.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
einfachTobi
User
Beiträge: 491
Registriert: Mittwoch 13. November 2019, 08:38

Wenn du die Daten hier ebenfalls in Code-Tags postest, müsste kein Datensalat entstehen, auch wenns im Editor so aussieht. Wenn die Spalten das Problem aufzeigen, dann helfen auch wenige Spalte. Geht ja nur um Beispiele.
Danny_Deluxe
User
Beiträge: 10
Registriert: Dienstag 27. Juli 2021, 08:49

Code: Alles auswählen

Depot-Nummer	Valoren-Nummer	ISIN	Name	Währung	Land Emittent	Land Asset	Industriesektor	Rating	RMoodys	R S&P	Klasse	Menge	Kurs	Wechselkurs	Marktwert	Marchzins	Kursdatum	Einstandskurs	Einstandswechselkurs	Datum der letzten Zinszahlung	Risikowährung	Split Asset	Allokation	Macaulay Dauer	Mod. Duration	Konvexität	Fälligkeit	Währungsregion	Telekurs-Branchencode (Emittent)	Laufzeit	Nachhaltigkeit	Bewertung Multifaktor	Empfehlung Comfort
123.456.789	117329063	XS2425848053	Cert WISDOMTREE MULT Struc Instr.2022-30.11.62 on	USD	IE	IE					Strukturierte Produkte	3'800	18.12	1.206589	57'058.78	0	26.07.2022	22.49	1.246994		USD		100				2062	Nordamerika	Finanz-, Beteiligungs- & andere diversif				
123.456.780	47358238	CH0473582382	Zert UBS AG Underlying Tracker 2019-13.07.26 (Exp.06.07.26)	EUR	CH	CH	Finanzwesen	AA-			Strukturierte Produkte	330	104.41	0.9768	33'655.94	0	26.07.2022	100	1.113357		EUR		100				2026	Euroländer	Banken & andere Kreditinstitute				
123.456.781	3624607	DE000A0S9GB0	Ant Deutsche Boerse Commodities o.f.Verfall auf Xetra Gold (3624607)	EUR	DE	DE					Rohstoffe / Metalle 	67	54.54		3'654.18	0	26.07.2022	52.44			EUR		100					Euroländer	Finanz-, Beteiligungs- & andere diversif		Nein		
123.456.782	3624607	DE000A0S9GB0	Ant Deutsche Boerse Commodities o.f.Verfall auf Xetra Gold (3624607)	EUR	DE	DE					Rohstoffe / Metalle 	120	54.54	0.9768	6'392.96	0	26.07.2022	55.26	1.045701		EUR		100					Euroländer	Finanz-, Beteiligungs- & andere diversif		Nein		
Das CSV wird mir täglich mit "ä" usw. geliefert und das kann ich nicht beeinflussen. Das bringt immer Fehler. Voll nervig.

Ganz herzlichen Dank für Deine Unterstützung!
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Ist dann nicht eher voll nervig, dass du die Datei nicht mit der richtigen Kodierung einliest?
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Daten lassen sich ohne Probleme mit dem richtigen Encoding und thousands="'" einlesen.
Die Tabellendefinition solltest Du selbst schreiben, anstatt da irgendwas automatisch zusammenbauen zu lassen.
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei man das Tabellenschema auch Pandas überlassen kann:

Code: Alles auswählen

#!/usr/bin/env python3
from contextlib import closing
from sqlite3 import connect

import pandas as pd


def main():
    data = pd.read_csv(
        "test.csv",
        delimiter="\t",
        usecols=[
            "Depot-Nummer",
            "ISIN",
            "Name",
            "Währung",
            "Klasse",
            "Menge",
            "Kurs",
            "Wechselkurs",
            "Marktwert",
            "Einstandskurs",
            "Einstandswechselkurs",
            "Risikowährung",
            "Fälligkeit",
            "Nachhaltigkeit",
            "Bewertung Multifaktor",
        ],
        thousands="'",
        encoding="utf-8",
    )
    with closing(connect("test.db")) as connection:
        data.to_sql("table_name", connection)
        connection.commit()


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Danny_Deluxe
User
Beiträge: 10
Registriert: Dienstag 27. Juli 2021, 08:49

@all: Vielen Dank für die Anmerkungen!

@__blackjack__: Danke für den Code. Mit Encoding 'utf-8' hat es mir eine Fehlermeldung gebracht und ich habe es auf 'ISO-8858-1' abgeändert. Jetzt kommt diese Fehlermeldung:

ValueError: Usecols do not match columns, columns expected but not found: ['Risikowährung', 'Depot-Nummer', 'Bewertung Multifaktor', 'Wechselkurs', 'Währung', 'Fälligkeit', 'Einstandskurs', 'Klasse', 'Kurs', 'Marktwert', 'Menge', 'Einstandswechselkurs', 'ISIN', 'Name']

Woran könnte das liegen?
Danny_Deluxe
User
Beiträge: 10
Registriert: Dienstag 27. Juli 2021, 08:49

Habe es gefunden: delimiter=";" und es läuft....
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Danny_Deluxe: Die gezeigten Beispieldaten hatten halt Tabulatorzeichen als Trenner, darum habe ich das auch im Code gewählt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Danny_Deluxe
User
Beiträge: 10
Registriert: Dienstag 27. Juli 2021, 08:49

@__blackjack__: Alles gut, es ist gelöst. Und ich hab wieder eine Liste mit Lernthemen wie Encoding etc. :lol:
Ganz herzlichen Dank für Deine / Eure Hilfe und ganz besonders für Eure Geduld!
Antworten