Seite 1 von 1

pandas dataframe spalte datetime in string konvertieren

Verfasst: Dienstag 28. Januar 2020, 19:25
von McGurk
Servus die MeisterInnen der Datenverarbeitung ;)

Ich als Python-Neuling arbeite an meinem ersten script, welches mir csvs aus einem Verzeichnis zusammenführen und wieder als csv ausgeben soll. Die erste spalte ist ein timestamp in Form "31.12.2020 00:00". Dieser soll in ein datetime-format konvertiert werden und am Ende wieder in einen String zur ausgabe in csv. Stundenlanges googeln fürte mich leider bisher nicht zum gewünschten Ergebnis.

Das erste Problem ist, dass beim Einlesen durch "infer_datetime_format=True" das Format nicht erkannt wird. Tag und Monat werden vertauscht und die Uhrzeit verschwindet.

Zweitens habe ich noch keine Möglichkeit gefunden die Zeitstempel-Spalte wieder in einen string umzuwandeln.

Ich würde mich sehr freuen, über ein paar Tipps

Code: Alles auswählen

import pandas as pd
import glob

NumberofPis=3

# Load all Files of directory
for i in range(1,NumberofPis+1):
    path = r'E:\Test\t%d'%i
    all_files = glob.glob(path + "/*.csv")

# Create an empty dataframe.
    li = []

# Append files in dataframe "li" as long as there are files
    for filename in all_files:
        df = pd.read_csv(filename, index_col=['date'], header=0, decimal=",", delimiter=';',parse_dates = True, infer_datetime_format=True)
        li.append(df)
        
# concatenation of li: Put single dataframes together
        frame = pd.concat(li, axis=0, sort=False)
        
# delete the headers originating in single files
        df_deduplicated = frame.drop_duplicates()

# Write into csv / just activate if you want to write new concatenated files
    df_deduplicated.to_csv(r"E:\Test\ergebnis\t%d.csv"%i, decimal=",", sep=";")
    
Im Endeffekt bräuchte ich das dataframe übrigens nach timestamp sortiert - das wäre der nächste Schritt ;)

Vielen Dank im Voraus, lg michl

Re: pandas dataframe spalte datetime in string konvertieren

Verfasst: Dienstag 28. Januar 2020, 23:02
von McGurk
oho die Formatierung des timedate habe ich hinbekommen:

Code: Alles auswählen

for filename in all_files:
        dateparse = lambda x: pd.datetime.strptime(x, '%d.%m.%Y %H:%M')
        df = pd.read_csv(filename, index_col=['date'], header=0, decimal=",", delimiter=';',parse_dates = ['date'], date_parser = dateparse)
        li.append(df)
bzgl. Konvertierung in string zur csv-ausgabe bin ich leider noch nicht weiter ^^

Re: pandas dataframe spalte datetime in string konvertieren

Verfasst: Mittwoch 29. Januar 2020, 01:35
von McGurk
Na da war einiges falsch - jetzt funktionierts - Sortierung fehlt noch:

Code: Alles auswählen

import pandas as pd
import glob


#How many Pis are installed
NumberofPis=3

# Load all Files of directory
for i in range(1,NumberofPis+1):
    path = r'E:\Test\t%d'%i
    all_files = glob.glob(path + "/*.csv")


# Create an empty dataframe.
    li = []

# Append files in dataframe "li" as long as there are files
    for filename in all_files:
        df = pd.read_csv(filename, index_col=None, header=0, decimal=",", delimiter=';')
        df['date'] = pd.to_datetime(df['date'], format='%d.%m.%Y %H:%M')
        li.append(df)
        
# concatenation of li: Put single dataframes together
        frame = pd.concat(li, axis=0, sort=False)
        
# delete the headers originating in single files
        df_deduplicated = frame.drop_duplicates()

# Write into csv / just activate if you want to write new concatenated files
    df_deduplicated.to_csv(r"E:\BOKU\BOKU Master\Master home\Daten_Python\Uebungen\Test\ergebnis\t%d.csv"%i, decimal=",", sep=";", index=False)
Zut Info: Ich dacht zuerst, dass man die datetime spalte wieder in string umwandeln müsse, da im erstellten csv die Uhrzeit fehlte - dabei wurde diese aus irgendeinem Grund garnicht eingelesen. ^^

Re: pandas dataframe spalte datetime in string konvertieren

Verfasst: Mittwoch 29. Januar 2020, 08:05
von Sirius3
Das Umwandeln in datetime kann man gleich bei read_csv machen. Den passenden Parameter in der Dokumentation nachzulesen überlasse ich als Hausaufgabe.
Pfade stückelt man nicht mit + zusammen, sondern nimmt am besten pathlib.Path.
Die Einrückungen sind teilweise falsch.

Re: pandas dataframe spalte datetime in string konvertieren

Verfasst: Mittwoch 29. Januar 2020, 11:40
von __blackjack__
@McGurk: Kommentare sollten auch entsprechend eingerückt werden, weil es sonst schwieriger ist die Einrückung und damit die Codestruktur zu sehen und damit zum Beispiel die falsche Einrückung zu erkennen.

Die Pfade sollte man als Konstanten herausziehen.

Kommentare sollten dem Leser einen Mehrwert über den Code bieten und inhaltlich auf jeden Fall korrekt sein. ``# Create an empty dataframe.`` als Kommentar wenn man eine leere Liste erstellt ist falsch. Ansonsten sind die meisten Kommentare in dem Quelltext überflüssig. Faustregel: Kommentare beschreiben nicht *was* der Code tut, denn das steht da bereits als Code, sondern warum er das tut was er tut, sofern das nicht offensichtlich ist.

Der ``# Delete the headers originating in single files.`` ist ein Beispiel für einen sinnvollen Kommentar, weil man diese Information nicht aus dem Code ablesen kann. Wobei man die Kopfzeilen besser gar nicht erst einliest, statt sie hinterher auf diese Weise auszufiltern. Da müsste man nämlich noch begründen können (und vielleicht auch gleich als Kommentar dokumentieren) warum das nur Kopfzeilen betrifft und nie Daten vernichten kann.

Namen schreibt man in Python klein_mit_unterstrichen. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase). `NumberofPis` sollte also wohl `NUMBER_OF_PIS` heissen.

`all_files` enthält keine Dateien sondern Datei*namen*.

Den ``%``-Operator um Werte in Zeichenketten zu formatieren würde ich nicht mehr ohne eine gute Begründung verwenden. Die `format()`-Methode oder ab Python 3.6 f-Zeichenkettenliterale sind moderner.

Namen sollen dem Leser verraten was der Wert dahinter im Kontext des Programms bedeutet. Kryptische Abkürzungen wie `li` tun das nicht. Falls das für `list` oder `liste` stehen sollte: Grunddatentypen haben in Namen nichts zu suchen. Die ändern sich im Laufe der Programmentwicklung gerne mal und dann hat man entweder falsche, irreführende Namen im Code oder muss die überall anpassen.

Auf Modulebene gehört nur Code der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Ungetesteter Zwischenstand:

Code: Alles auswählen

#!/usr/bin/env python3
from pathlib import Path

import pandas as pd

NUMBER_OF_PIS = 3

SOURCE_PATH = Path(r"E:\Test")
TARGET_PATH = Path(
    r"E:\BOKU\BOKU Master\Master home\Daten_Python\Uebungen\Test\ergebnis"
)


def main():
    decimal = ","
    separator = ";"
    for i in range(1, NUMBER_OF_PIS + 1):
        dataframes = []
        for file_path in (SOURCE_PATH / f"t{i}").glob("*.csv"):
            data = pd.read_csv(
                file_path, header=0, decimal=decimal, sep=separator
            )
            #
            # TODO Do conversion in the `read_csv()` call.
            #
            data["date"] = pd.to_datetime(
                data["date"], format="%d.%m.%Y %H:%M"
            )
            dataframes.append(data)

        data = pd.concat(dataframes, axis=0, sort=False)
        #
        # TODO If this really is just to filter out the same headers then just
        # don't read them in the first place instead of filtering them out after
        # reading and concatenating.
        #
        # Delete the headers originating in single files.
        #
        data = data.drop_duplicates()

        data.to_csv(
            TARGET_PATH / f"t{i}.csv",
            decimal=decimal,
            sep=separator,
            index=False,
        )


if __name__ == "__main__":
    main()

Re: pandas dataframe spalte datetime in string konvertieren

Verfasst: Donnerstag 30. Januar 2020, 16:10
von McGurk
@blackjack, vielen Dank für die ausführliche Antwort und die Tipps! Ich bin natürlich auch dabei die Grundlagen zu lernen, allerdings brauche ich für meine Arbeit demnächst ein paar Skripte - darum hin und wieder die Ausflüge Querfeldein, wie in diesem Fall ^^

Das Skript läuft bei mir leider nicht und ich hab noch nicht herausfinden können woran das liegt. Pathlib habe ich installiert (Anaconda). Ausgabe ist nur:
runfile('E:/BOKU/BOKU Master/Master home/Daten_Python/Uebungen/Test/test_forum.py', wdir='E:/BOKU/BOKU Master/Master home/Daten_Python/Uebungen/Test')
-source path hat sich übrigens geändert.

Per Test mit dem Spyder debugger wird nicht einmal die Konstante NUMBER_OF_PIS = 3 kreiert (Variablenmanager bleibt leer). Sehr eigenartig

Code: Alles auswählen

from pathlib import Path

import pandas as pd

NUMBER_OF_PIS = 3

SOURCE_PATH = Path(r"E:\BOKU\BOKU Master\Master home\Daten_Python\Uebungen\Test")
TARGET_PATH = Path(r"E:\BOKU\BOKU Master\Master home\Daten_Python\Uebungen\Test\ergebnis")


def main():
    decimal = ","
    separator = ";"
    for i in range(1, NUMBER_OF_PIS + 1):
        dataframes = []
        for file_path in (SOURCE_PATH / f"t{i}").glob("*.csv"):
            data = pd.read_csv(file_path, header=0, decimal=decimal, sep=separator)
	    #
            # TODO Do conversion in the `read_csv()` call.
            #
            data["date"] = pd.to_datetime(data["date"], format="%d.%m.%Y %H:%M")
            dataframes.append(data)

        data = pd.concat(dataframes, axis=0, sort=False)
        #
        # TODO If this really is just to filter out the same headers then just
        # don't read them in the first place instead of filtering them out after
        # reading and concatenating.
        #
        # Delete the headers originating in single files.
        #
        data = data.drop_duplicates()

        data.to_csv(TARGET_PATH / f"t{i}.csv", decimal=decimal, sep=separator, index=False)


if __name__ == "__main__":
    main()

Re: pandas dataframe spalte datetime in string konvertieren

Verfasst: Donnerstag 30. Januar 2020, 16:15
von McGurk
Sirius3 hat geschrieben: Mittwoch 29. Januar 2020, 08:05 Das Umwandeln in datetime kann man gleich bei read_csv machen. Den passenden Parameter in der Dokumentation nachzulesen überlasse ich als Hausaufgabe.
Pfade stückelt man nicht mit + zusammen, sondern nimmt am besten pathlib.Path.
Die Einrückungen sind teilweise falsch.
Sirius3 danke für den Hinweis, damit hatte ichs auch anfangs probiert - leider versagt ^^

Re: pandas dataframe spalte datetime in string konvertieren

Verfasst: Donnerstag 30. Januar 2020, 16:49
von __blackjack__
@McGurk: `pathlib` ist Bestandteil der Standardbibliothek, ausser man verwendet eine Python-Version die man nicht mehr verwenden sollte.

Ausgabe sollte es keine geben, denn es wird ja nirgends etwas ausgegeben.