datetime.timedelta.weekday() hat falsches Index: für Sontag 0; für Montag 1

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
python_versuch
User
Beiträge: 9
Registriert: Freitag 5. März 2021, 16:41

Hallo zusammen,

für jeden Wochentag versuche ich das zugehörige Datum zu ermitteln, z.B::
weekdays = {"Montag": ["2021-01-04", "2021-02-01", "2021-03-01", ...], ..., "Mittwoch": ["2021-01-06", "2021-02-03", "2021-03-03", ...]}
Allerdings beginnt der Sonntag mit 0 und Montag mit 1, was dann in der Grafik nicht so schön aussieht (weil Sontag vor dem Montag steht und nimmand es entschlüsseln kann, dass mit 0 Sonntag gemeint ist). Der Sonntag sollte mit 7 und Montag mit 1 beginnen. Ich finde den Fehler hier nicht?

Code: Alles auswählen

 
        heute = datetime.date.today()
        the_time = pd.Timestamp(heute)
        year = int(the_time.year - 1)
        # Beginne ab dem ersten Januar
        first_day = str(year) + "-01-01"
        fist_weekday_date = datetime.datetime.strptime(first_day, '%Y-%m-%d')
        last_day = str(year) + "-12-31"
        last_week_date = datetime.datetime.strptime(last_day, '%Y-%m-%d')

        next_weekday = fist_weekday_date
        weekdays = {}

        # Für den einzelnen Wochentag
        for j in range(1,8):
            dates_for_weekday = []
            # ermittelt das Datum/alle Termine für den angegebenen Wochentag
            while next_weekday < last_weekday_date:
                dates_for_weekday.append(str(next_weekday.date()))
                next_weekday = next_weekday + datetime.timedelta(weeks=1)

            next_weekday = fist_weekday_date + datetime.timedelta(days=j)
            # {Wochentag : [Datum_1, Datum_2, ... , Datum_N]}
            # weekdays = {"Montag": ["2021-01-04", "2021-02-01", "2021-03-01"], "Mittwoch": ["2021-01-06", "2021-02-03", "2021-03-03"]}
            weekdays[str(next_weekday.weekday())] = dates_for_weekday
        
        print("######################################")
        for x,y in weekdays.items():
            print(str(x) + ":" + str(y))
        print("######################################")
            
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Zuerst einmal muss man feststellen, dass es die Funktion, die du in deiner Überschrift wählst, nicht gibt. Oder wie verwendest du timedelta.weekday()?

Du verwendest date.weekday().
Und was man nebenbei immer tun sollte: In die Dokumentation schauen. Denn da steht ausdrücklich, welcher Wochentag welche Zahl liefert - und wie man dein Problem behebt.
python_versuch
User
Beiträge: 9
Registriert: Freitag 5. März 2021, 16:41

Der Montag: 0, der Sonntag:7. Das ist aber nicht der Fall bei mir und ich verstehe nicht warum. Darauf bezog sich eigentlich meine Frage
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Wie kommst du auf die Aussage, dass der Montag 0 und der Sonntag 7 ist?
Ich habe doch die Dokumentation verlinkt? Hast du dir die 2 Sekunden Zeit genommen, da mal drauf zu klicken und die 2 Sätze zu lesen, die da zur Erklärung der Funktion stehen?
monaid
User
Beiträge: 14
Registriert: Mittwoch 13. Juni 2018, 17:19

ich hab versuchst deine sorgen nachzustellen, ist mir leider nicht gelungen.
was ist pd ?

https://libraries.io/pypi/pd

hat kein Attribut Timestamp
python_versuch
User
Beiträge: 9
Registriert: Freitag 5. März 2021, 16:41

import pandas as pd
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@python_versuch: Wenn Du eh schon Pandas verwendest, dann ist das alles viel zu umständlich weil Pandas für Zeitreihen bereits eine Menge Unterstützung hat, unter anderem regelmässige Zeitstempel generieren.

Aber auch ohne Pandas würde man nicht das Jahr von Datumsobjekten in eine Zeichenkette umwandeln, da ein Tagesdatum als Zeichenkette dran basteln um das dann wieder in ein Datumsobjekt zu parsen. `date` und `datetime` haben dafür beispielsweise eine `replace()`-Methode. Oder man erstellt halt gleich Datumsobjekte mit den passenden Zahlen, ohne den Umweg über eine Zeichenkette.

`the_time` macht keinen Sinn, denn das Jahr hätte man auch einfach von `heute` genau so abfragen können. Und das Jahr ist auch bereits eine ganze Zahl, es macht keinen Sinn die in eine ganze Zahl umwandeln zu wollen.

`last_week_date` wird nirgends verwendet, dafür aber ein `last_weekday_date` das nirgends definiert ist. Falls das *eine* Variable sein sollte: ist das gewollt, dass das Datum des letzten Tages im Jahr *nicht* mit im Ergebnis landet?

Die beiden verschachtelten Schleifen kann man mit einem `defaultdict()` und *einer* Schleife, oder einer Liste mit Listen und einer Schleife einfacher ausdrücken.

Ich würde auch der Versuchung widerstehen alles sofort in Zeichenketten umzuwandeln. Zahlen und Datumsobjekte sollten in dieser Form bleiben so lange es geht, falls man doch irgend wo noch mal auf die Eigenschaften dieser Objekte zugreifen will/muss und dann dort nicht wieder parsen muss.

`x` ist ein schlechter Name für die Nummer des Wochentags und `y` ist ein schlechter Name für eine Liste mit Datumsangaben.

Das zusammenstückeln von Zeichenketten und Werten mittels ``+`` und `str()` ist eher BASIC als Python. Dafür gibt es die `format()`-Methode auf Zeichenketten und f-Zeichenkettenliterale.

Ungetestet:

Code: Alles auswählen

        last_year = datetime.date.today().year - 1
        current_day = datetime.date(last_year, 1, 1)
        last_day = datetime.date(last_year, 12, 31)

        weekday_dates = [[] for _ in range(7)]
        while current_day <= last_day:
            weekday_dates[current_day.weekday()].append(current_day)
            current_day += datetime.timedelta(days=1)

        print("#" * 38)
        for weekday_number, dates in enumerate(weekday_dates):
            print(f"{weekday_number}:{dates}")
        print("#" * 38)
Aber wie gesagt, wenn Pandas im Spiel ist, würde man das eher mit Pandas lösen was dann noch mal deutlich anders aussieht.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
python_versuch
User
Beiträge: 9
Registriert: Freitag 5. März 2021, 16:41

Danke blackjack! Sehr elegante Lösung! Wenn es nicht all zu viele Umstände macht, würde mich auch die Pandas Version interessieren, vorallem wie die Zahlen in Pandas zu den jeweiligen Bezeichnungen (z.B. 0 zu Montag) umgewandelt werden. Können dort die Wochentage auch sortiert ausgegeben werden?
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@python_versuch: Bei Pandas wäre die Frage was mit den Daten denn überhaupt passieren soll, denn es würde eher keinen Sinn machen so eine Python-Datenstruktur aus Grunddatentypen zu erstellen wenn man Pandas und `Series`- und/oder `DataFrame`-Objekte verwendet.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten