Конечно, я мог бы написать это сам, но прежде чем изобретать колесо, есть ли функция, которая уже это делает?
pandas.Series.dt.quarter.
Конечно, я мог бы написать это сам, но прежде чем изобретать колесо, есть ли функция, которая уже это делает?
pandas.Series.dt.quarter.
Ответы:
Учитывая экземпляр 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модуль для использования моих (и других) проектов на работе, в котором много маленьких функции для выполнения всех этих календарных вычислений - некоторые из них сложные, некоторые простые, но нет причин выполнять работу снова и снова (даже простую) или рисковать ошибками в таких вычислениях ;-).
(m+2)//3вместо(m-1)//3 + 1
ЕСЛИ вы уже пользуетесь 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.Series.dt.quarter- идеальное решение, когда у вас есть значения datetime в объекте Dataframe или Series .
Я бы предложил другое, возможно, более чистое решение. Если X - datetime.datetime.now()экземпляр, то квартал равен:
import math
Q=math.ceil(X.month/3.)
ceil необходимо импортировать из математического модуля, так как к нему нельзя получить прямой доступ.
math.ceil(float(4)/3) = 2.0math.ceil(4/3) = 1.0
.сделали после тройки. math.ceil(4/3.) = 2.0
Для тех, кто пытается получить квартал финансового года, который может отличаться от календарного года, я написал модуль 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 . Документацию можно найти в разделе «Прочитать документацию» . Если вы ищете какие-либо функции, которых у него сейчас нет, дайте мне знать!
Вот пример функции, которая получает объект 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
Этот метод работает для любого отображения:
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
Для тех, кто ищет данные за квартал финансового года, используя pandas,
import datetime
import pandas as pd
today_date = datetime.date.today()
quarter = pd.PeriodIndex(today_date, freq='Q-MAR').strftime('Q%q')
ссылка: индекс периода панд
Это старый вопрос, но он все же заслуживает обсуждения.
Вот мое решение, использующее отличный модуль 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последний день квартала (вычисляется путем нахождения первого дня следующего квартала минус один день).
хммм, поэтому расчеты могут пойти не так, вот лучшая версия (просто ради нее)
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]
"it is difficult to see correctness except by testing it". Вы должны писать тесты, как и все хорошие разработчики. Тесты - это то, что помогает уберечь вас от ошибок и выявить те, которые вы делаете. Разработчик никогда не должен жертвовать производительностью и удобочитаемостью, чтобы не допустить ошибки. Кроме того, это менее читабельно, чем если бы вы просто сделали статический диктант с использованием литералов.
(m-1)//3 + 1, тоже не все так читабельно, не многие люди знают, что //делает. Мой первоначальный комментарий был просто по поводу утверждения, "calculations can go wrong"которое мне кажется странным.
Вот подробное, но также удобочитаемое решение, которое будет работать для экземпляров 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