Есть ли функция 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
Chishaku
источник
Что делать, если квартал моего финансового года начинается в сентябре?
Артур Д. Хауленд
Метод 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

если mэто номер месяца ...

import math
math.ceil(float(m) / 3)
Гарбанцио
источник
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
Ури Горен
источник
2

Для тех, кто ищет данные за квартал финансового года, используя pandas,

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

ссылка: индекс периода панд

Сиддарам Х
источник
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последний день квартала (вычисляется путем нахождения первого дня следующего квартала минус один день).

MikeHoss
источник
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)
JavDomGom
источник
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))
Светодиод
источник