Pytanie BARDZO uzasadnione, mimo że wczesne odpowiedzi wydają się odrobinę lekceważące („tylko kwestia”, „wydaje się całkiem proste”): dwie odpowiedzi (w tym jedna ZGŁOSOWANA!) Są okropnie błędne, co oznacza, że NIE jest to takie proste lub „ tylko "...
Alex Martelli
Jestem pewien, że wróci i to naprawi
Nadia Alramli
To pytanie bardzo pomocne w 2018: D
wdfc
Jeśli obiekty datetime są przechowywane w Pandy szeregowo lub Dataframe , istnieje metoda, która zwraca odpowiedni kwartał (y): pandas.Series.dt.quarter.
Sumanth Lazarus
Odpowiedzi:
162
Biorąc pod uwagę wystąpienie xz datetime.date , (x.month-1)//3daje czwartą (0 dla pierwszego kwartału, 1 dla drugiego kwartału, etc - dodać1w jeśli trzeba liczyć od 1 zamiast ;-).
Pierwotnie dwie odpowiedzi, pomnożone za głosami, a nawet pierwotnie zaakceptowane (obie obecnie usunięte), były błędne - nie robiłem tego -1przed podziałem i dzielono przez 4 zamiast 3. Od .month1 do 12 łatwo jest sprawdzić, jaka jest formuła dobrze:
for m in range(1,13):print m//4+1,print
daje 1 1 1 2 2 2 2 3 3 3 3 4- dwa kwartały czteromiesięczne i jednomiesięczny (eep).
for m in range(1,13):print(m-1)//3+1,print
daje 1 1 1 2 2 2 3 3 3 4 4 4- czy to nie wygląda dla ciebie zdecydowanie lepiej? -)
To dowodzi, że pytanie jest, jak sądzę, uzasadnione ;-).
Nie sądzę, że moduł datetime koniecznie powinien mieć każdą możliwą użyteczną funkcję kalendarza, ale wiem, że utrzymuję (dobrze przetestowany ;-) datetoolsmoduł do wykorzystania moich (i innych) projektów w pracy, który ma wiele niewielkich funkcje do wykonywania wszystkich tych obliczeń w kalendarzu - niektóre są złożone, inne proste, ale nie ma powodu, aby wykonywać tę pracę w kółko (nawet prostą pracę) ani ryzykować błędów w takich obliczeniach ;-).
Dzięki Alex. Dlatego powinna istnieć funkcja. Zobacz, ile osób pomyliło się.
Jason Christa,
Myślę, że udowodniłeś swój punkt widzenia. Nie trzeba zanieczyszczać całej strony powtarzającymi się komentarzami.
João Silva
1
@Jason, tak, dokładnie - dlatego zagłosowałem za twoim pytaniem, gdy zobaczyłem inne błędne odpowiedzi (obecnie usunięte), chociaż wydaje się, że ktoś inny przegłosował, aby policzyć moje głosy za, hm.
Alex Martelli,
1
@JG, jakie „powtarzające się komentarze”? Ponieważ błędne odpowiedzi zostały usunięte, komentarze zniknęły wraz z nimi, więc dodałem ich treść do odpowiedzi - ważne jest, aby być świadomym, jak łatwo jest się rozproszyć lub spieszyć i uzyskać błąd, którego można uniknąć, nawet w prostym obliczeniu, i ma konsekwencje (w zakresie tworzenia i solidnego testowania funkcji wielokrotnego użytku) dla najlepszych praktyk programowania; ten przypadek jest dobrym przykładem (co moim zdaniem dowodzi, że pytanie było uzasadnione).
Alex Martelli,
7
Można również użyć: (m+2)//3zamiast(m-1)//3 + 1
Ben
49
Jeśli już używasz pandas, jest to dość proste.
import datetime as dt
import pandas as pd
quarter = pd.Timestamp(dt.date(2016,2,29)).quarter
assert quarter ==1
Jeśli masz datekolumnę w ramce danych, możesz łatwo utworzyć nową quarterkolumnę:
Jak sugeruje odpowiedź @garbanzio. Musiałem przełożyć argument miesiąca przez funkcję float, aby to zadziałałomath.ceil(float(4)/3) = 2.0 , podczas gdymath.ceil(4/3) = 1.0
Theo Kouzelis
1
Zignoruj mnie Nie zdawałem sobie sprawy, co .zrobili po 3.math.ceil(4/3.) = 2.0
Theo Kouzelis
11
Dla każdego, kto próbuje uzyskać kwartał roku podatkowego , który może różnić się od kalendarza , napisałem moduł Pythona, aby to zrobić.
Instalacja jest prosta. Po prostu biegnij:
$ pip install fiscalyear
Nie ma żadnych zależności i fiscalyear powinno działać zarówno dla Pythona 2, jak i 3.
Zasadniczo jest to otoka wokół wbudowanego modułu datetime , więc wszystkie datetimepolecenia, które już znasz, będą działać. Oto 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)
fiscalyearjest hostowany na GitHub i PyPI . Dokumentację można znaleźć pod adresem Read the Docs . Jeśli szukasz funkcji, których obecnie nie ma, daj mi znać!
Oto moje rozwiązanie, wykorzystujące doskonały moduł dateutil .
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)
Tak więc first_dayjest to pierwszy dzień kwartału i last_dayostatni dzień kwartału (obliczony poprzez znalezienie pierwszego dnia następnego kwartału minus jeden dzień).
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)
hmmm więc obliczenia mogą się nie udać, tutaj jest lepsza wersja (tylko ze względu na to)
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 w tym przypadku może mieć rację, ale czasami czytelność i bycie wyraźnym liczy się i prowadzi do mniejszej liczby błędów, zamiast
zwięzłych
1
@RussBradberry również widzisz usunięte odpowiedzi i komentarze na ten temat, widzisz proste obliczenia mogą być trudne również dla dobrych programistów i trudno jest zobaczyć poprawność poza testowaniem, w moim rozwiązaniu możesz zobaczyć i mieć pewność, że zadziała
Anurag Uniyal
1
tak jak powiedziałeś "it is difficult to see correctness except by testing it". Powinieneś pisać testy, tak jak wszyscy dobrzy programiści. Testy pomagają powstrzymać Cię od popełnienia błędów i wyłapać te, które robisz. Deweloper nigdy nie powinien poświęcać wydajności i czytelności, aby nie popełnić błędu. Ponadto jest to mniej czytelne, niż gdybyś po prostu utworzył statyczny dykt za pomocą literałów.
Russ Bradberry,
Nie zrozum mnie źle, (m-1)//3 + 1to też nie wszystko, co jest czytelne, niewiele osób wie, co to //robi. Mój pierwotny komentarz dotyczył właśnie oświadczenia"calculations can go wrong" które wydaje mi się dziwne.
Russ Bradberry,
@RussBradberry faktycznie zgadzam się z tobą, moja odpowiedź była alternatywą i czasami istnieją alternatywy. Widziałem wiele kodów, w których ludzie próbują obliczyć / wydedukować coś, co można po prostu zakodować na mapie
Anurag Uniyal
0
Oto rozwlekłe, ale także czytelne rozwiązanie, które będzie działać w przypadku wystąpienia daty i godziny
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
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))
pandas.Series.dt.quarter
.Odpowiedzi:
Biorąc pod uwagę wystąpienie
x
z datetime.date ,(x.month-1)//3
daje czwartą (0 dla pierwszego kwartału, 1 dla drugiego kwartału, etc - dodać1w jeśli trzeba liczyć od 1 zamiast ;-).Pierwotnie dwie odpowiedzi, pomnożone za głosami, a nawet pierwotnie zaakceptowane (obie obecnie usunięte), były błędne - nie robiłem tego
-1
przed podziałem i dzielono przez 4 zamiast 3. Od.month
1 do 12 łatwo jest sprawdzić, jaka jest formuła dobrze:daje
1 1 1 2 2 2 2 3 3 3 3 4
- dwa kwartały czteromiesięczne i jednomiesięczny (eep).daje
1 1 1 2 2 2 3 3 3 4 4 4
- czy to nie wygląda dla ciebie zdecydowanie lepiej? -)To dowodzi, że pytanie jest, jak sądzę, uzasadnione ;-).
Nie sądzę, że moduł datetime koniecznie powinien mieć każdą możliwą użyteczną funkcję kalendarza, ale wiem, że utrzymuję (dobrze przetestowany ;-)
datetools
moduł do wykorzystania moich (i innych) projektów w pracy, który ma wiele niewielkich funkcje do wykonywania wszystkich tych obliczeń w kalendarzu - niektóre są złożone, inne proste, ale nie ma powodu, aby wykonywać tę pracę w kółko (nawet prostą pracę) ani ryzykować błędów w takich obliczeniach ;-).źródło
(m+2)//3
zamiast(m-1)//3 + 1
Jeśli już używasz
pandas
, jest to dość proste.Jeśli masz
date
kolumnę w ramce danych, możesz łatwo utworzyć nowąquarter
kolumnę:źródło
pandas.Series.dt.quarter
jest idealnym rozwiązaniem, gdy masz wartości daty i godziny w obiekcie Dataframe lub Series .Sugerowałbym inne, prawdopodobnie czystsze rozwiązanie. Jeśli X jest
datetime.datetime.now()
instancją, to kwartał jest:ceil musi zostać zaimportowany z modułu matematycznego, ponieważ nie można uzyskać do niego bezpośredniego dostępu.
źródło
math.ceil(float(4)/3) = 2.0
, podczas gdymath.ceil(4/3) = 1.0
.
zrobili po 3.math.ceil(4/3.) = 2.0
Dla każdego, kto próbuje uzyskać kwartał roku podatkowego , który może różnić się od kalendarza , napisałem moduł Pythona, aby to zrobić.
Instalacja jest prosta. Po prostu biegnij:
Nie ma żadnych zależności i
fiscalyear
powinno działać zarówno dla Pythona 2, jak i 3.Zasadniczo jest to otoka wokół wbudowanego modułu datetime , więc wszystkie
datetime
polecenia, które już znasz, będą działać. Oto demo:fiscalyear
jest hostowany na GitHub i PyPI . Dokumentację można znaleźć pod adresem Read the Docs . Jeśli szukasz funkcji, których obecnie nie ma, daj mi znać!źródło
Oto przykład funkcji, która pobiera obiekt datetime.datetime i zwraca unikalny ciąg dla każdego kwartału:
A wynik to:
źródło
jeśli
m
to numer miesiąca ...źródło
Ta metoda działa dla dowolnego mapowania:
Właśnie wygenerowaliśmy funkcję
int->int
Ta metoda jest również niezawodna
źródło
Dla tych, którzy szukają danych za kwartał roku obrotowego, używając pand,
odniesienie: indeks okresu pand
źródło
To stare pytanie, ale nadal warte dyskusji.
Oto moje rozwiązanie, wykorzystujące doskonały moduł dateutil .
Tak więc
first_day
jest to pierwszy dzień kwartału ilast_day
ostatni dzień kwartału (obliczony poprzez znalezienie pierwszego dnia następnego kwartału minus jeden dzień).źródło
To jest bardzo proste i działa w Pythonie3:
źródło
hmmm więc obliczenia mogą się nie udać, tutaj jest lepsza wersja (tylko ze względu na to)
źródło
"it is difficult to see correctness except by testing it"
. Powinieneś pisać testy, tak jak wszyscy dobrzy programiści. Testy pomagają powstrzymać Cię od popełnienia błędów i wyłapać te, które robisz. Deweloper nigdy nie powinien poświęcać wydajności i czytelności, aby nie popełnić błędu. Ponadto jest to mniej czytelne, niż gdybyś po prostu utworzył statyczny dykt za pomocą literałów.(m-1)//3 + 1
to też nie wszystko, co jest czytelne, niewiele osób wie, co to//
robi. Mój pierwotny komentarz dotyczył właśnie oświadczenia"calculations can go wrong"
które wydaje mi się dziwne.Oto rozwlekłe, ale także czytelne rozwiązanie, które będzie działać w przypadku wystąpienia daty i godziny
źródło
używając słowników, możesz to zrobić przez
źródło