Pergunta MUITO justificada, embora as primeiras respostas pareçam um pouco desdenhosas ("apenas uma questão de", "parece muito simples"): duas das respostas (incluindo uma REALIZADA!) São terrivelmente bugadas, mostrando que NÃO é tão simples ou " apenas "...
Alex Martelli
Tenho certeza que ele vai voltar e consertar isso
Nadia Alramli
Esta pergunta é muito útil em 2018: D
wdfc
Se os objetos de data e hora são armazenados em uma série Pandas ou trama de dados , há um método que retorna o respectivo trimestre (s): pandas.Series.dt.quarter.
Sumanth Lazarus
Respostas:
162
Dada uma instância xde datetime.date , (x.month-1)//3fornecerá o trimestre (0 para o primeiro trimestre, 1 para o segundo trimestre, etc. - adicione 1 se precisar contar a partir de 1 ;-).
Originalmente, duas respostas, com votos positivos multiplicados e até mesmo aceitas originalmente (ambas atualmente excluídas), apresentavam erros - não fazendo o -1antes da divisão e dividindo por 4 em vez de 3. Como .monthvai de 1 a 12, é fácil verificar por si mesmo qual é a fórmula certo:
for m in range(1,13):print m//4+1,print
dá 1 1 1 2 2 2 2 3 3 3 3 4- dois trimestres de quatro meses e um de um mês (eep).
for m in range(1,13):print(m-1)//3+1,print
dá 1 1 1 2 2 2 3 3 3 4 4 4- agora isso não parece muito preferível para você? -)
Isso prova que a questão é bem justificada, eu acho ;-).
Não acho que o módulo datetime deva necessariamente ter todas as funções de calendário úteis possíveis, mas sei que mantenho um datetoolsmódulo (bem testado ;-) para o uso de meus (e de outros) projetos no trabalho, que tem muitos poucos funções para realizar todos esses cálculos do calendário - alguns são complexos, outros simples, mas não há razão para fazer o trabalho repetidamente (mesmo o trabalho simples) ou arriscar bugs em tais cálculos ;-).
Obrigado Alex. É por isso que deve haver uma função. Veja quantas pessoas erraram.
Jason Christa
Eu acho que você provou seu ponto. Não é necessário poluir a página inteira com comentários repetidos.
João Silva
1
@Jason, sim, exatamente - é por isso que votei positivamente em sua pergunta quando vi as outras respostas problemáticas (atualmente excluídas), embora outra pessoa pareça ter votado negativamente para contar meu voto positivo, ah, bem.
Alex Martelli
1
@JG, quais são os "comentários repetidos"? Como as respostas com erros foram excluídas, os comentários foram embora com eles, então eu trouxe seu conteúdo para a resposta - é importante estar ciente de como é fácil se distrair ou se apressar e obter um bug evitável, mesmo em um cálculo simples, e tem consequências (em termos de fazer e testar solidamente funções reutilizáveis) para as melhores práticas de programação; este caso é um bom exemplo (o que eu acho que prova que a questão era justificada).
Alex Martelli
7
Também pode usar: em (m+2)//3vez de(m-1)//3 + 1
Ben
49
SE você já está usando pandas, é bem simples.
import datetime as dt
import pandas as pd
quarter = pd.Timestamp(dt.date(2016,2,29)).quarter
assert quarter ==1
Se você tem uma datecoluna em um dataframe, pode facilmente criar uma nova quartercoluna:
Como a resposta de @garbanzio sugere. Eu precisava colocar o argumento do mês por meio da função float para fazer isso funcionar math.ceil(float(4)/3) = 2.0enquantomath.ceil(4/3) = 1.0
Theo Kouzelis
1
Ignore-me, não percebi o que o .depois do 3 fez. math.ceil(4/3.) = 2.0
Theo Kouzelis
11
Para quem está tentando obter o trimestre do ano fiscal , que pode ser diferente do ano civil , escrevi um módulo Python para fazer exatamente isso.
A instalação é simples. Apenas corra:
$ pip install fiscalyear
Não há dependências e fiscalyeardeve funcionar tanto no Python 2 quanto no 3.
É basicamente um invólucro em torno do módulo datetime integrado , portanto, todos os datetimecomandos com os quais você já está familiarizado funcionarão. Aqui está uma demonstração:
>>>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)
fiscalyearestá hospedado no GitHub e PyPI . A documentação pode ser encontrada em Read the Docs . Se você estiver procurando por algum recurso que ele não tenha atualmente, me avise!
Esta é uma questão antiga, mas ainda digna de discussão.
Aqui está minha solução, usando o excelente módulo 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)
Assim first_dayé o primeiro dia do trimestre e last_dayé o último dia do trimestre (calculado encontrando o primeiro dia do próximo trimestre, menos um dia).
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 então os cálculos podem dar errado, aqui está uma versão melhor (apenas por causa dela)
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 neste caso pode estar certo, mas às vezes a legibilidade e o fato de ser explícito contam e levam a menos erros, em vez de um cálculo conciso
Anurag Uniyal
1
@RussBradberry também veja respostas deletadas e comentários sobre isso, veja um cálculo simples pode ser complicado para bons programadores também e é difícil ver a correção exceto testando-o, na minha solução você pode ver e ter certeza de que funcionará
Anurag Uniyal
1
exatamente como você disse "it is difficult to see correctness except by testing it". Você deve escrever testes, como todos os bons desenvolvedores deveriam. Os testes ajudam a evitar que você cometa erros e a detectar os erros cometidos. Um desenvolvedor nunca deve sacrificar o desempenho e a legibilidade para evitar cometer erros. Além disso, isso é menos legível do que se você simplesmente fizesse um dicionário estático usando literais.
Russ Bradberry
Não me interpretem mal (m-1)//3 + 1também não é tão legível, muitas pessoas não sabem o que //significa. Meu comentário original foi apenas sobre a afirmação "calculations can go wrong"que soa estranho para mim.
Russ Bradberry
@RussBradberry na verdade, eu concordo com você, minha resposta foi como uma alternativa e às vezes há alternativas. Eu vi muito código onde as pessoas estão tentando calcular / deduzir algo que pode ser codificado em um mapa
Anurag Uniyal
0
Aqui está uma solução detalhada, mas também legível, que funcionará para instâncias de data e hora
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
.Respostas:
Dada uma instância
x
de datetime.date ,(x.month-1)//3
fornecerá o trimestre (0 para o primeiro trimestre, 1 para o segundo trimestre, etc. - adicione 1 se precisar contar a partir de 1 ;-).Originalmente, duas respostas, com votos positivos multiplicados e até mesmo aceitas originalmente (ambas atualmente excluídas), apresentavam erros - não fazendo o
-1
antes da divisão e dividindo por 4 em vez de 3. Como.month
vai de 1 a 12, é fácil verificar por si mesmo qual é a fórmula certo:dá
1 1 1 2 2 2 2 3 3 3 3 4
- dois trimestres de quatro meses e um de um mês (eep).dá
1 1 1 2 2 2 3 3 3 4 4 4
- agora isso não parece muito preferível para você? -)Isso prova que a questão é bem justificada, eu acho ;-).
Não acho que o módulo datetime deva necessariamente ter todas as funções de calendário úteis possíveis, mas sei que mantenho um
datetools
módulo (bem testado ;-) para o uso de meus (e de outros) projetos no trabalho, que tem muitos poucos funções para realizar todos esses cálculos do calendário - alguns são complexos, outros simples, mas não há razão para fazer o trabalho repetidamente (mesmo o trabalho simples) ou arriscar bugs em tais cálculos ;-).fonte
(m+2)//3
vez de(m-1)//3 + 1
SE você já está usando
pandas
, é bem simples.Se você tem uma
date
coluna em um dataframe, pode facilmente criar uma novaquarter
coluna:fonte
pandas.Series.dt.quarter
é uma solução ideal quando você tem valores de data e hora em um objeto Dataframe ou Series .Eu sugeriria outra solução indiscutivelmente mais limpa. Se X for uma
datetime.datetime.now()
instância, o quarto será:ceil deve ser importado do módulo matemático, pois não pode ser acessado diretamente.
fonte
math.ceil(float(4)/3) = 2.0
enquantomath.ceil(4/3) = 1.0
.
depois do 3 fez.math.ceil(4/3.) = 2.0
Para quem está tentando obter o trimestre do ano fiscal , que pode ser diferente do ano civil , escrevi um módulo Python para fazer exatamente isso.
A instalação é simples. Apenas corra:
Não há dependências e
fiscalyear
deve funcionar tanto no Python 2 quanto no 3.É basicamente um invólucro em torno do módulo datetime integrado , portanto, todos os
datetime
comandos com os quais você já está familiarizado funcionarão. Aqui está uma demonstração:fiscalyear
está hospedado no GitHub e PyPI . A documentação pode ser encontrada em Read the Docs . Se você estiver procurando por algum recurso que ele não tenha atualmente, me avise!fonte
Aqui está um exemplo de uma função que obtém um objeto datetime.datetime e retorna uma string exclusiva para cada trimestre:
E o resultado é:
fonte
se
m
é o número do mês ...fonte
Este método funciona para qualquer mapeamento:
Acabamos de gerar uma função
int->int
Este método também é infalível
fonte
Para aqueles que procuram dados trimestrais do ano financeiro, usando o pandas,
referência: índice do período dos pandas
fonte
Esta é uma questão antiga, mas ainda digna de discussão.
Aqui está minha solução, usando o excelente módulo dateutil .
Assim
first_day
é o primeiro dia do trimestre elast_day
é o último dia do trimestre (calculado encontrando o primeiro dia do próximo trimestre, menos um dia).fonte
Isso é muito simples e funciona em python3:
fonte
hmmm então os cálculos podem dar errado, aqui está uma versão melhor (apenas por causa dela)
fonte
"it is difficult to see correctness except by testing it"
. Você deve escrever testes, como todos os bons desenvolvedores deveriam. Os testes ajudam a evitar que você cometa erros e a detectar os erros cometidos. Um desenvolvedor nunca deve sacrificar o desempenho e a legibilidade para evitar cometer erros. Além disso, isso é menos legível do que se você simplesmente fizesse um dicionário estático usando literais.(m-1)//3 + 1
também não é tão legível, muitas pessoas não sabem o que//
significa. Meu comentário original foi apenas sobre a afirmação"calculations can go wrong"
que soa estranho para mim.Aqui está uma solução detalhada, mas também legível, que funcionará para instâncias de data e hora
fonte
usando dicionários, você pode fazer isso
fonte