Seite 1 von 1

Excel-File mit Datum kopieren

Verfasst: Montag 13. Januar 2020, 14:11
von DMD-OS
Hallo zusammen :)

Ich habe mir eine Excel-Tapete erstellt, die ich gern mit pandas kopieren und als neue Datei (mit eigenem Namen) abspeichern möchte.
https://www.directupload.net/file/d/569 ... 3u_jpg.htm
Ich versuche es so hinzubekommen, daß ein Datum (egal in welche Zelle) automatisch erkannt wird und in der Form strftime('%d.%m.%Y') übernommen wird.
Das was ich versuche, ist, ein Dictionary zu erstellen, welches ich wieder als Excel-File abspeichern kann.
Dabei funktioniert das Datum erkennen und umwandeln schon mal.
Mein bisheriger Code:

Code: Alles auswählen

import os
import pandas as pd

input_file = "C:\\Users\\xxx\\Desktop\\DM-Dateiimport\\Testdatei.xlsx"
process_file = "C:\\Users\\xxx\\Desktop\\DM-Dateiimport\\Testdatei - Kopie.xlsx"

if os.path.isfile(process_file):
    os.remove(process_file)

def undate(x):
    if pd.isnull(x):
        return x
    try:
        return x.strftime('%d.%m.%Y')
    except AttributeError:
        return x
    except Exception:
        raise

excel_file = pd.ExcelFile(input_file)
process_dict = {}
for sheet_name in excel_file.sheet_names:
    df_frame = pd.DataFrame(pd.read_excel(input_file, sheet_name=sheet_name))
    if not df_frame.empty:
        # print(sheet_name)
        if sheet_name not in process_dict:
            process_dict[sheet_name] = {}
        for key, value in df_frame.items():
            # print(key)
            if key not in process_dict[sheet_name]:
                process_dict[sheet_name][key] = []
            process_dict[sheet_name][key].append(df_frame[key].apply(undate))
            
print(process_dict)

excel_file.close()
Ausgabe:

Code: Alles auswählen

{'Tabelle1': {'Name': [0         Ankit
1         Rahul
2       Shaurya
3    03.05.1999
4      Priyanka
Name: Name, dtype: object], 'Age': [0          18
1          19
2          20
3          18
4    7.7.1852
Name: Age, dtype: object], 'Stream': [0          Math
1       Science
2    01.02.1987
3          Math
4       Science
Name: Stream, dtype: object], 'Percentage': [0    07.06.2013
1            90
2            85
3            80
4            75
Name: Percentage, dtype: object]}, 'Tabelle2': {'Date_Names': [0        Ankit
1        Rahul
2      Shaurya
3    Aishwarya
4     Priyanka
Name: Date_Names, dtype: object], 'Dates': [0    01.02.1987
1    02.05.1999
2    02.05.1999
3    01.02.1987
4    02.05.1999
Name: Dates, dtype: object]}}

Process finished with exit code 0
Probleme tauchen jetzt schon bei der Erstellung des Dictionaries auf,
da ich diese ganzen Zusätze nicht in das Dict übernehmen will, sondern nur das was direkt in den Tabellen (im Bild) vorhanden ist.
Kennt sich da jmd mit aus?
LG Christian

Re: Excel-File mit Datum kopieren

Verfasst: Montag 13. Januar 2020, 16:04
von einfachTobi
Puh, da fällt es mir schwer den Grund dafür nachzuvollziehen.
Zunächst: Warum kann z. B. die Spalte `Name` ein Datum enthalten? Ist es nicht angebracht dafür zu sorgen, dass die Eingangsdaten konsistent sind? Was ist der Sinn hinter dem ganzen vorhaben?
Meistens gilt: Wenn man über ein DataFrame iteriert, macht man etwas falsch.
So kannst du zum Beispiel mit einer Zeile gleich beim Einlesen ein Dictionary je Blatt erzeugen und die Kalenderdaten automatisch als DateTime parsen:

Code: Alles auswählen

mein_frame = pd.read_excel(<pfad_zur_mappe>, parse_dates=True, sheet_name=['Tabelle1', 'Tabelle2'])
print(mein_frame)
Die Formatierung für die DateTimes solltest du eher bei er Ausgabe anpassen. Ansonsten schau dir die Doku von `read_excel()` an. Da steht beschreiben, wie man einen eigenen Parser verwendet.
Um aus einem DataFrame ein Dictionary zu machen sollte man ebenfalls nicht selbst mit for-Schleifen basteln, sondern to_dict() verwenden.
Du kannst aber auch gleich mit to_excel() wieder als Excelmappe abspeichern.

Re: Excel-File mit Datum kopieren

Verfasst: Dienstag 14. Januar 2020, 08:51
von DMD-OS
Ich möchte es gern so haben, daß man überall auch ein Datum einfügen kann.
In meinem neuen Code passt das auch alles.
Es fehlt nur noch, daß die einzelnen df_frame's nicht immer nur in der ersten Spalte eingesetzt (d.h. dauernd überschrieben) werden.
Es taucht in der Excel-Datei immer nur die letzte Spalte auf, alle anderen werden anscheinend immer überschrieben :)

Code: Alles auswählen

import os
import pandas as pd

input_file = "C:\\Users\\xxx\\Desktop\\DM-Dateiimport\\Testdatei.xlsx"
process_file = "C:\\Users\\xxx\\Desktop\\DM-Dateiimport\\Testdatei - Kopie.xlsx"
if os.path.isfile(process_file):
    os.remove(process_file)


def undate(x):
    if pd.isnull(x):
        return x
    try:
        return x.strftime('%d.%m.%Y')
    except AttributeError:
        return x
    except Exception:
        raise


xlsx = pd.ExcelFile(input_file)
writer = pd.ExcelWriter(process_file, engine='xlsxwriter')

for sheet_name in xlsx.sheet_names:
    if not xlsx.parse(sheet_name).empty:
        for key, value in xlsx.parse(sheet_name).items():
            df_frame = pd.DataFrame(value.apply(undate)).to_excel(writer, sheet_name=sheet_name, index=False)
            worksheet = writer.sheets[sheet_name]
            # pd.concat(df_frame, axis=0, ignore_index=True).to_excel(writer, sheet_name=sheet_name, index=False)


writer.save()
writer.close()
xlsx.close()
Kann man einzelne Spalte auch nebeneinander setzen und dann an den writer geben?
(pd.concat setzt die spalten glaub ich untereinander?)

Re: Excel-File mit Datum kopieren

Verfasst: Dienstag 14. Januar 2020, 09:19
von Sirius3
`apply` ist die falsche Funktion, ebenso die for-Schleife. Nimm `applymap`. Den Rückgabewert von to_excel and df_frame zu binden ist quatsch.
Mehrmals `parse` aufzurufen ist falsch. Exceptions sollten wirklich Ausnahmen sein.

Code: Alles auswählen

import pandas as pd

INPUT_FILENAME = "C:\\Users\\xxx\\Desktop\\DM-Dateiimport\\Testdatei.xlsx"
OUTPUT_FILENAME = "C:\\Users\\xxx\\Desktop\\DM-Dateiimport\\Testdatei - Kopie.xlsx"

def undate(x):
    return x.strftime('%d.%m.%Y') if hasattr(x, 'strftime') else x

def main():
    xlsx = pd.ExcelFile(INPUT_FILENAME)
    writer = pd.ExcelWriter(OUTPUT_FILENAME, engine='xlsxwriter')
    for sheet_name in xlsx.sheet_names:
        sheet = xlsx.parse(sheet_name)
        if not sheet.empty:
            sheet.applymap(undate).to_excel(writer, sheet_name=sheet_name, index=False)
    writer.save()
    writer.close()
    xlsx.close()

if __name__ == '__main__':
    main()

Re: Excel-File mit Datum kopieren

Verfasst: Dienstag 14. Januar 2020, 10:47
von DMD-OS
vielen dank für deine hilfe.
aber ich hab da noch eine frage zu der zeile:
return x.strftime('%d.%m.%Y') if hasattr(x, 'strftime') else x
kannst du mir erklären was if hasattr(x, 'strftime') bewirkt?
soweit ich das verstehe, bedeutet es:
gib das datum in form '%d.%m.%Y' zurück, wenn (es möglich ist, äh !?if hasattr(x, 'strftime')?!), ansonsten den wert der angegeben ist.
ich versteh das hasattr nicht.

Re: Excel-File mit Datum kopieren

Verfasst: Dienstag 14. Januar 2020, 11:03
von Sirius3
hasattr fragt ab, ob es die Methode (eigentlich das Attribut) strftime gibt.

Re: Excel-File mit Datum kopieren

Verfasst: Dienstag 14. Januar 2020, 11:09
von DMD-OS
also
sheet.applymap(undate)
und
hasattr(x, 'strftime')
haben mir gefehlt.
vielen dank nochmal :D