Есть ли функция Python для определения, в каком квартале года находится свидание?


113

Конечно, я мог бы написать это сам, но прежде чем изобретать колесо, есть ли функция, которая уже это делает?


22
Вопрос ОЧЕНЬ оправдан, даже если первые ответы кажутся немного пренебрежительными («всего-навсего», «кажется довольно простым»): два ответа (включая ПРОГЛОСОВАННЫЙ!) Ужасно ошибочны, показывая, что это НЕ все так просто или » просто "...
Алекс Мартелли

Я уверена, что он вернется и исправит это
Надя Алрамли

Этот вопрос очень полезен в 2018 году: D
wdfc

Если объекты DateTime хранятся в серии панды или Dataframe , существует метод , который возвращает соответствующий квартал (ы): pandas.Series.dt.quarter.
Сумант Лазарь,

Ответы:


162

Учитывая экземпляр xиз datetime.date , (x.month-1)//3даст вам четверть (0 за первый квартал, 1 за второй квартал и т.д. - добавить 1 , если вам нужно считать от 1 вместо ;-).


Первоначально два ответа, многократно проголосовавшие за и даже первоначально принятые (оба в настоящее время удалены), были ошибочными - не выполнялось -1до деления и делилось на 4 вместо 3. Поскольку .monthидет от 1 до 12, легко проверить для себя, что такое формула право:

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

дает 1 1 1 2 2 2 2 3 3 3 3 4- два четырехмесячных квартала и одномесячный (eep).

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

дает 1 1 1 2 2 2 3 3 3 4 4 4- разве это не выглядит для вас намного предпочтительнее? -)

Это доказывает, что вопрос, я думаю, вполне обоснован ;-).

Я не думаю, что модуль datetime обязательно должен иметь все возможные полезные календарные функции, но я знаю, что поддерживаю (хорошо протестированный ;-) datetoolsмодуль для использования моих (и других) проектов на работе, в котором много маленьких функции для выполнения всех этих календарных вычислений - некоторые из них сложные, некоторые простые, но нет причин выполнять работу снова и снова (даже простую) или рисковать ошибками в таких вычислениях ;-).


3
Спасибо, Алекс. Вот почему должна быть функция. Посмотрите, сколько людей ошиблись.
Джейсон Криста,

Я думаю, вы доказали свою точку зрения. Нет необходимости засорять всю страницу повторяющимися комментариями.
Жоао Силва,

1
@ Джейсон, да, именно поэтому я проголосовал за ваш вопрос, как только увидел другие ответы с ошибками (в настоящее время удалены), хотя кто-то, похоже, проголосовал против, чтобы подсчитать мой голос, ну что ж.
Alex Martelli

1
@JG, что за "повторяющиеся комментарии"? Когда ошибочные ответы были удалены, комментарии исчезли вместе с ними, поэтому я внес их содержание в ответ - важно знать, насколько легко отвлечься или поторопиться и получить устранимую ошибку даже в простом вычислении, и это имеет последствия (с точки зрения создания и тщательного тестирования функций многократного использования) для лучших практик программирования; этот случай - хороший пример (который, я думаю, доказывает, что вопрос был оправдан).
Alex Martelli

7
Также можно использовать: (m+2)//3вместо(m-1)//3 + 1
Ben

49

ЕСЛИ вы уже пользуетесь pandas, это довольно просто.

import datetime as dt
import pandas as pd

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

Если у вас есть dateстолбец во фрейме данных, вы можете легко создать новый quarterстолбец:

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

Что делать, если квартал моего финансового года начинается в сентябре?
Артур Д. Хауленд

Метод Pandas pandas.Series.dt.quarter- идеальное решение, когда у вас есть значения datetime в объекте Dataframe или Series .
Сумант Лазарь,

31

Я бы предложил другое, возможно, более чистое решение. Если X - datetime.datetime.now()экземпляр, то квартал равен:

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

ceil необходимо импортировать из математического модуля, так как к нему нельзя получить прямой доступ.


1
На данный момент лучший. Благодаря тонну!
curlyreggie

3
Вероятно, следует обернуть это в int ()
Паблоджим

Как и предполагает ответ @garbanzio. Мне нужно было math.ceil(float(4)/3) = 2.0math.ceil(4/3) = 1.0
передать

1
Не обращайте на меня внимания, я не понимал, что .сделали после тройки. math.ceil(4/3.) = 2.0
Тео Кузелис

11

Для тех, кто пытается получить квартал финансового года, который может отличаться от календарного года, я написал модуль Python, чтобы сделать именно это.

Установка проста. Просто беги:

$ pip install fiscalyear

Нет никаких зависимостей и fiscalyearдолжно работать как для Python 2, так и для Python 3.

По сути, это оболочка для встроенного модуля datetime , поэтому любые datetimeкоманды, с которыми вы уже знакомы, будут работать. Вот демо:

>>> 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)

fiscalyearразмещен на GitHub и PyPI . Документацию можно найти в разделе «Прочитать документацию» . Если вы ищете какие-либо функции, которых у него сейчас нет, дайте мне знать!


4

Вот пример функции, которая получает объект datetime.datetime и возвращает уникальную строку для каждого квартала:

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))

И результат:

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


2

Этот метод работает для любого отображения:

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

Мы только что сгенерировали функцию int->int

month2quarter(9) # returns 3

Этот метод также надежен

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


1

Это старый вопрос, но он все же заслуживает обсуждения.

Вот мое решение, использующее отличный модуль 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)

Таким образом, first_dayэто первый день квартала и last_dayпоследний день квартала (вычисляется путем нахождения первого дня следующего квартала минус один день).


1

Это очень просто и работает в 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

хммм, поэтому расчеты могут пойти не так, вот лучшая версия (просто ради нее)

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 в этом случае может быть вы правы, но иногда удобочитаемость и явная ясность имеют значение и приводят к меньшему количеству ошибок вместо кратких вычислений
Anurag Uniyal

1
@RussBradberry также видит удаленные ответы и комментарии по этому поводу, видите, что простой расчет может быть сложным для хороших программистов, и трудно увидеть правильность, кроме как путем его тестирования, в моем решении вы можете увидеть и быть уверенным, что оно будет работать
Anurag Uniyal

1
как ты и сказал "it is difficult to see correctness except by testing it". Вы должны писать тесты, как и все хорошие разработчики. Тесты - это то, что помогает уберечь вас от ошибок и выявить те, которые вы делаете. Разработчик никогда не должен жертвовать производительностью и удобочитаемостью, чтобы не допустить ошибки. Кроме того, это менее читабельно, чем если бы вы просто сделали статический диктант с использованием литералов.
Расс Брэдберри

не поймите меня неправильно (m-1)//3 + 1, тоже не все так читабельно, не многие люди знают, что //делает. Мой первоначальный комментарий был просто по поводу утверждения, "calculations can go wrong"которое мне кажется странным.
Расс Брэдберри

@RussBradberry на самом деле я согласен с вами, мой ответ был в качестве альтернативы, и, напомню, иногда есть альтернативы, я видел много кода, в котором люди пытаются вычислить / вывести что-то, что можно просто жестко запрограммировать на карте
Anurag Uniyal

0

Вот подробное, но также удобочитаемое решение, которое будет работать для экземпляров datetime и date.

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

используя словари, вы можете сделать это

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))
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.