Gibt es eine Python-Funktion, um zu bestimmen, in welchem ​​Quartal des Jahres sich ein Datum befindet?


112

Natürlich könnte ich das selbst schreiben, aber bevor ich das Rad neu erfinde, gibt es eine Funktion, die dies bereits tut?


22
Frage SEHR gerechtfertigt, obwohl die frühen Antworten ein wenig abweisend erscheinen ("nur eine Frage von", "scheint ziemlich einfach"): Zwei der Antworten (einschließlich einer UPVOTED!) Sind schrecklich fehlerhaft und zeigen, dass es NICHT so einfach ist oder " nur "...
Alex Martelli

Ich bin sicher, er wird zurückkommen und das beheben
Nadia Alramli

Diese Frage sehr hilfreich im Jahr 2018: D
wdfc

Antworten:


161

Wenn Sie eine Instanz xvon datetime.date angeben , erhalten (x.month-1)//3Sie das Quartal (0 für das erste Quartal, 1 für das zweite Quartal usw. - addieren Sie 1, wenn Sie stattdessen von 1 zählen müssen ;-).


Ursprünglich waren zwei Antworten, mehrfach positiv bewertet und sogar ursprünglich akzeptiert (beide derzeit gelöscht), fehlerhaft - nicht -1vor der Teilung und durch 4 statt 3 geteilt. Da es .monthsich um 1 bis 12 handelt, ist es einfach, selbst zu überprüfen, welche Formel vorliegt richtig:

for m in range(1, 13):
  print m//4 + 1,
print

gibt 1 1 1 2 2 2 2 3 3 3 3 4- zwei viermonatige Quartale und ein einmonatiges (eep).

for m in range(1, 13):
  print (m-1)//3 + 1,
print

gibt 1 1 1 2 2 2 3 3 3 4 4 4- sieht dir das jetzt nicht vorzuziehen aus? -)

Dies beweist, dass die Frage gut begründet ist, denke ich ;-).

Ich denke nicht, dass das datetime-Modul unbedingt alle möglichen nützlichen Kalenderfunktionen haben sollte, aber ich weiß, dass ich ein (gut getestetes ;-) datetoolsModul für die Verwendung meiner (und anderer) Projekte bei der Arbeit habe, das viele wenig hat Funktionen zum Ausführen all dieser Kalenderberechnungen - einige sind komplex, andere einfach, aber es gibt keinen Grund, die Arbeit immer wieder zu erledigen (auch einfache Arbeit) oder Fehler in solchen Berechnungen zu riskieren ;-).


3
Danke Alex. Deshalb sollte es eine Funktion geben. Schauen Sie, wie viele Leute es falsch verstanden haben.
Jason Christa

Ich denke, Sie haben Ihren Standpunkt bewiesen. Es ist nicht notwendig, die gesamte Seite mit wiederholten Kommentaren zu verschmutzen.
João Silva

1
@Jason, ja, genau - deshalb habe ich Ihre Frage positiv bewertet, als ich die anderen fehlerhaften Antworten (derzeit gelöscht) gesehen habe, obwohl jemand anderes anscheinend abgelehnt hat, um meine positive Bewertung zu zählen, na ja.
Alex Martelli

1
@JG, welche "wiederholten Kommentare"? Da die fehlerhaften Antworten gelöscht wurden, gingen die Kommentare mit ihnen verloren, und ich brachte ihren Inhalt in die Antwort ein. Es ist wichtig zu wissen, wie einfach es ist, abgelenkt oder beeilt zu werden, und selbst bei einer einfachen Berechnung einen vermeidbaren Fehler zu erhalten. und es hat Konsequenzen (in Bezug auf das Erstellen und gründliche Testen wiederverwendbarer Funktionen) für die Programmierung von Best Practices; Dieser Fall ist ein gutes Beispiel (was meiner Meinung nach beweist, dass die Frage gerechtfertigt war).
Alex Martelli

7
Kann auch verwenden: (m+2)//3anstelle von(m-1)//3 + 1
Ben

48

Wenn Sie bereits verwenden pandas, ist es ganz einfach.

import datetime as dt
import pandas as pd

quarter = pd.Timestamp(dt.date(2016, 2, 29)).quarter
assert quarter == 1

Wenn Sie eine dateSpalte in einem Datenrahmen haben, können Sie einfach eine neue quarterSpalte erstellen :

df['quarter'] = df['date'].dt.quarter

Was ist, wenn mein Geschäftsquartal im September beginnt?
Arthur D. Howland

31

Ich würde eine andere wohl sauberere Lösung vorschlagen. Wenn X eine datetime.datetime.now()Instanz ist, lautet das Quartal:

import math
Q=math.ceil(X.month/3.)

Ceil muss aus dem Mathematikmodul importiert werden, da nicht direkt darauf zugegriffen werden kann.


1
Das bisher beste. Danke vielmals!
Curlyreggie

3
Wahrscheinlich sollte dies in ein int ()
Pablojim

Wie @garbanzio Antwort vorschlägt. Ich musste das math.ceil(float(4)/3) = 2.0math.ceil(4/3) = 1.0
Monatsargument

1
Ignoriere mich, ich wusste nicht, was die .nach den 3 taten. math.ceil(4/3.) = 2.0
Theo Kouzelis

11

Für alle, die versuchen, das Quartal des Geschäftsjahres zu ermitteln , das vom Kalenderjahr abweichen kann , habe ich ein Python-Modul geschrieben, um genau dies zu tun.

Die Installation ist einfach. Renn einfach:

$ pip install fiscalyear

Es gibt keine Abhängigkeiten und fiscalyearsollte sowohl für Python 2 als auch für Python 3 funktionieren.

Es handelt sich im Grunde genommen um einen Wrapper um das integrierte datetime- Modul, sodass alle datetimeBefehle, mit denen Sie bereits vertraut sind, funktionieren. Hier ist eine Demo:

>>> from fiscalyear import *
>>> a = FiscalDate.today()
>>> a
FiscalDate(2017, 5, 6)
>>> a.fiscal_year
2017
>>> a.quarter
3
>>> b = FiscalYear(2017)
>>> b.start
FiscalDateTime(2016, 10, 1, 0, 0)
>>> b.end
FiscalDateTime(2017, 9, 30, 23, 59, 59)
>>> b.q3
FiscalQuarter(2017, 3)
>>> b.q3.start
FiscalDateTime(2017, 4, 1, 0, 0)
>>> b.q3.end
FiscalDateTime(2017, 6, 30, 23, 59, 59)

fiscalyearwird auf GitHub und PyPI gehostet . Die Dokumentation finden Sie unter Lesen Sie die Dokumente . Wenn Sie nach Funktionen suchen, die derzeit nicht verfügbar sind, lassen Sie es mich wissen!


4

Hier ist ein Beispiel für eine Funktion, die ein datetime.datetime-Objekt abruft und für jedes Quartal eine eindeutige Zeichenfolge zurückgibt:

from datetime import datetime, timedelta

def get_quarter(d):
    return "Q%d_%d" % (math.ceil(d.month/3), d.year)

d = datetime.now()
print(d.strftime("%Y-%m-%d"), get_q(d))

d2 = d - timedelta(90)
print(d2.strftime("%Y-%m-%d"), get_q(d2))

d3 = d - timedelta(180 + 365)
print(d3.strftime("%Y-%m-%d"), get_q(d3))

Und die Ausgabe ist:

2019-02-14 Q1_2019
2018-11-16 Q4_2018
2017-08-18 Q3_2017


2

Diese Methode funktioniert für jede Zuordnung:

month2quarter = {
        1:1,2:1,3:1,
        4:2,5:2,6:2,
        7:3,8:3,9:3,
        10:4,11:4,12:4,
    }.get

Wir haben gerade eine Funktion generiert int->int

month2quarter(9) # returns 3

Diese Methode ist auch narrensicher

month2quarter(-1) # returns None
month2quarter('July') # returns None

2

Für diejenigen, die mit Pandas nach Geschäftsquartalsdaten suchen,

import datetime
import pandas as pd
today_date = datetime.date.today()
quarter = pd.PeriodIndex(today_date, freq='Q-MAR').strftime('Q%q')

Referenz: Pandas Period Index


1

Dies ist eine alte Frage, die aber noch diskutiert werden sollte.

Hier ist meine Lösung mit dem hervorragenden Dateutil- Modul.

  from dateutil import rrule,relativedelta

   year = this_date.year
   quarters = rrule.rrule(rrule.MONTHLY,
                      bymonth=(1,4,7,10),
                      bysetpos=-1,
                      dtstart=datetime.datetime(year,1,1),
                      count=8)

   first_day = quarters.before(this_date)
   last_day =  (quarters.after(this_date)
                -relativedelta.relativedelta(days=1)

Dies first_daygilt auch für den ersten Tag des Quartals und last_dayden letzten Tag des Quartals (berechnet anhand des ersten Tages des nächsten Quartals abzüglich eines Tages).


1

Dies ist sehr einfach und funktioniert in Python3:

from datetime import datetime

# Get current date-time.
now = datetime.now()

# Determine which quarter of the year is now. Returns q1, q2, q3 or q4.
quarter_of_the_year = 'q'+str((now.month-1)//3+1)

0

hmmm damit Berechnungen schief gehen können, hier ist eine bessere Version (nur deswegen)

first, second, third, fourth=1,2,3,4# you can make strings if you wish :)

quarterMap = {}
quarterMap.update(dict(zip((1,2,3),(first,)*3)))
quarterMap.update(dict(zip((4,5,6),(second,)*3)))
quarterMap.update(dict(zip((7,8,9),(third,)*3)))
quarterMap.update(dict(zip((10,11,12),(fourth,)*3)))

print quarterMap[6]

@RussBradberry in diesem Fall mögen Sie Recht haben, aber manchmal zählt Lesbarkeit und explizite Aussage und führt zu weniger Fehlern anstelle einer knappen Berechnung
Anurag Uniyal

1
@RussBradberry sieht auch gelöschte Antworten und Kommentare dazu. Eine einfache Berechnung kann auch für gute Programmierer schwierig sein und es ist schwierig, die Richtigkeit zu erkennen, außer durch Testen. In meiner Lösung können Sie sehen und sicher sein, dass es funktioniert
Anurag Uniyal

1
so wie du gesagt hast "it is difficult to see correctness except by testing it". Sie sollten Tests schreiben, wie es alle guten Entwickler tun sollten. Tests helfen Ihnen, Fehler zu vermeiden und diejenigen zu erfassen, die Sie tun. Ein Entwickler sollte niemals auf Leistung und Lesbarkeit verzichten, um Fehler zu vermeiden. Dies ist auch weniger lesbar, als wenn Sie nur ein statisches Diktat mit Literalen erstellen würden.
Russ Bradberry

Versteh mich nicht falsch (m-1)//3 + 1ist auch nicht so lesbar, nicht viele Leute wissen, was //tut. Mein ursprünglicher Kommentar war nur auf die Aussage, "calculations can go wrong"die für mich nur seltsam klingt.
Russ Bradberry

@RussBradberry Eigentlich stimme ich Ihnen zu, meine Antwort war als Alternative und manchmal gibt es Alternativen. Ich habe viel Code gesehen, in dem Leute versuchen, etwas zu berechnen / abzuleiten, das nur in einer Karte fest
codiert werden

0

Hier ist eine ausführliche, aber auch lesbare Lösung, die für Datums- und Datumsinstanzen funktioniert

def get_quarter(date):
    for months, quarter in [
        ([1, 2, 3], 1),
        ([4, 5, 6], 2),
        ([7, 8, 9], 3),
        ([10, 11, 12], 4)
    ]:
        if date.month in months:
            return quarter

0

Mit Wörterbüchern können Sie dies durchziehen

def get_quarter(month):
    quarter_dictionary = {
        "Q1" : [1,2,3],
        "Q2" : [4,5,6],
        "Q3" : [7,8,9],
        "Q4" : [10,11,12]
    }

    for key,values in quarter_dictionary.items():
        for value in values:
            if value == month:
                return key

print(get_quarter(3))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.