Apakah ada fungsi Python untuk menentukan kuartal tahun mana tanggal itu?

113

Tentu saya bisa menulis ini sendiri, tetapi sebelum saya menemukan kembali roda, apakah ada fungsi yang sudah melakukan ini?

Jason Christa
sumber
22
Pertanyaan SANGAT dijamin meskipun jawaban awal tampak agak meremehkan ("hanya masalah", "tampaknya cukup sederhana"): dua jawaban (termasuk yang DIPERBARUI!) Sangat bermasalah, menunjukkan bahwa TIDAK sesederhana itu atau " hanya "...
Alex Martelli
Saya yakin dia akan kembali dan memperbaiki ini
Nadia Alramli
Pertanyaan ini sangat membantu di 2018: D
wdfc
Jika objek datetime disimpan dalam Seri Panda atau Dataframe , ada metode yang mengembalikan kuartal masing-masing (s): pandas.Series.dt.quarter.
Sumanth Lazarus

Jawaban:

162

Mengingat sebuah contoh xdari datetime.date , (x.month-1)//3akan memberikan kuartal (0 untuk kuartal pertama, 1 untuk kuartal kedua, dll - tambahkan 1 jika Anda perlu untuk menghitung dari 1 bukan ;-).


Awalnya dua jawaban, kalikan upvoted dan bahkan diterima semula (keduanya saat ini dihapus), adalah buggy - tidak melakukan -1sebelum pembagian, dan membaginya dengan 4, bukan 3. Sejak .monthpergi 1 hingga 12, mudah untuk memeriksa sendiri apa rumusnya Baik:

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

memberi 1 1 1 2 2 2 2 3 3 3 3 4- dua kuartal empat bulan dan satu bulan satu (eep).

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

memberi 1 1 1 2 2 2 3 3 3 4 4 4- bukankah ini tampilan yang sangat Anda sukai? -)

Ini membuktikan bahwa pertanyaan itu dijamin dengan baik, menurut saya ;-).

Saya tidak berpikir modul datetime harus memiliki setiap kemungkinan fungsi kalender yang berguna, tapi saya tahu saya memelihara datetoolsmodul (teruji dengan baik ;-) untuk penggunaan proyek saya (dan orang lain) di tempat kerja, yang memiliki banyak berfungsi untuk melakukan semua penghitungan kalender ini - beberapa rumit, beberapa sederhana, tetapi tidak ada alasan untuk melakukan pekerjaan berulang-ulang (bahkan pekerjaan sederhana) atau mengambil risiko bug dalam penghitungan seperti itu ;-).

Alex Martelli
sumber
3
Terima kasih Alex. Inilah kenapa harus ada fungsi. Lihat berapa banyak orang yang salah.
Jason Christa
Saya pikir Anda membuktikan maksud Anda. Tidak perlu mencemari seluruh halaman dengan komentar berulang.
João Silva
1
@Jason, ya, tepatnya - itulah mengapa saya menaikkan suara pertanyaan Anda begitu saya melihat jawaban buggy lainnya (saat ini dihapus), meskipun ada orang lain yang tampaknya telah memberikan suara negatif untuk menghitung suara positif saya, ah baiklah.
Alex Martelli
1
@JG, apa "komentar berulang"? Saat jawaban buggy telah dihapus, komentar-komentar itu hilang bersama mereka, jadi saya membawa isinya ke dalam jawaban - penting untuk menyadari betapa mudahnya untuk dialihkan atau diburu-buru dan mendapatkan bug yang dapat dihindari bahkan dalam perhitungan sederhana, dan memiliki konsekuensi (dalam hal membuat dan menguji fungsi yang dapat digunakan kembali dengan kokoh) untuk praktik terbaik pemrograman; kasus ini adalah contoh yang baik (yang menurut saya membuktikan bahwa pertanyaan itu diperlukan).
Alex Martelli
7
Bisa juga menggunakan: (m+2)//3bukannya(m-1)//3 + 1
Ben
49

JIKA Anda sudah menggunakan pandas, ini cukup sederhana.

import datetime as dt
import pandas as pd

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

Jika Anda memiliki datekolom dalam dataframe, Anda dapat dengan mudah membuat quarterkolom baru :

df['quarter'] = df['date'].dt.quarter
chishaku
sumber
Bagaimana jika kuartal tahun fiskal saya dimulai pada bulan September?
Arthur D. Howland
Metode Pandas pandas.Series.dt.quarteradalah solusi ideal ketika Anda memiliki nilai datetime di objek Dataframe atau Series .
Sumanth Lazarus
31

Saya akan menyarankan solusi lain yang bisa dibilang lebih bersih. Jika X adalah sebuah datetime.datetime.now()instance, maka kuartalnya adalah:

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

ceil harus diimpor dari modul matematika karena tidak dapat diakses secara langsung.

Jonathan Rocher
sumber
1
Yang terbaik sejauh ini. Terima kasih banyak!
curlyreggie
3
Mungkin harus membungkus ini dalam sebuah int ()
Pablojim
Seperti saran jawaban @garbanzio. Saya perlu memasukkan argumen bulan melalui fungsi float agar ini berfungsi math.ceil(float(4)/3) = 2.0sementaramath.ceil(4/3) = 1.0
Theo Kouzelis
1
Abaikan saya, saya tidak menyadari apa yang dilakukan .setelah 3. math.ceil(4/3.) = 2.0
Theo Kouzelis
11

Bagi siapa pun yang mencoba mendapatkan kuartal tahun fiskal , yang mungkin berbeda dari tahun kalender , saya menulis modul Python untuk melakukan hal ini.

Pemasangannya sederhana. Lari saja:

$ pip install fiscalyear

Tidak ada dependensi, dan fiscalyearharus berfungsi untuk Python 2 dan 3.

Ini pada dasarnya adalah pembungkus di sekitar modul datetime bawaan , jadi datetimeperintah apa pun yang sudah Anda kenal akan berfungsi. Berikut demo nya:

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

fiscalyeardihosting di GitHub dan PyPI . Dokumentasi dapat ditemukan di Read the Docs . Jika Anda mencari fitur apa pun yang saat ini tidak dimiliki, beri tahu saya!

Adam Stewart
sumber
4

Berikut adalah contoh fungsi yang mendapatkan objek datetime.datetime dan mengembalikan string unik untuk setiap kuartal:

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

Dan hasilnya adalah:

2019-02-14 Q1_2019
2018-11-16 Q4_2018
2017-08-18 Q3_2017
Roei Bahumi
sumber
2

jika mnomor bulan ...

import math
math.ceil(float(m) / 3)
garbanzio
sumber
2

Metode ini berfungsi untuk pemetaan apa pun:

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

Kami baru saja membuat fungsi int->int

month2quarter(9) # returns 3

Metode ini juga sangat mudah

month2quarter(-1) # returns None
month2quarter('July') # returns None
Uri Goren
sumber
2

Bagi mereka, yang mencari data kuartal tahun keuangan, menggunakan panda,

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

referensi: indeks periode panda

Siddaram H.
sumber
1

Ini adalah pertanyaan lama tetapi masih layak untuk didiskusikan.

Inilah solusi saya, menggunakan modul dateutil yang sangat baik .

  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)

Begitu first_dayjuga dengan hari pertama kuartal, dan last_daymerupakan hari terakhir kuartal (dihitung dengan mencari hari pertama kuartal berikutnya, dikurangi satu hari).

MikeHoss
sumber
1

Ini sangat sederhana dan berfungsi di 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
sumber
0

hmmm jadi perhitungannya bisa salah, ini versi yang lebih baik (hanya demi itu)

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]
Anurag Uniyal
sumber
@RussBradberry dalam hal ini mungkin Anda benar, tetapi terkadang keterbacaan dan penghitungan eksplisit dan menyebabkan lebih sedikit kesalahan, alih-alih penghitungan singkat
Anurag Uniyal
1
@RussBradberry juga melihat jawaban dan komentar yang dihapus tentang itu, lihat perhitungan sederhana bisa jadi rumit untuk programmer yang baik juga dan sulit untuk melihat kebenaran kecuali dengan mengujinya, dalam solusi saya Anda dapat melihat dan yakin itu akan berhasil
Anurag Uniyal
1
seperti yang kamu katakan "it is difficult to see correctness except by testing it". Anda harus menulis tes, seperti semua pengembang yang baik. Tes adalah apa yang membantu untuk mencegah Anda membuat kesalahan, dan menangkap kesalahan yang Anda lakukan. Seorang pengembang tidak boleh mengorbankan kinerja dan keterbacaan, untuk mencegah diri mereka membuat kesalahan. Juga, ini kurang terbaca dibandingkan jika Anda hanya membuat dikt statis menggunakan literal.
Russ Bradberry
jangan salah (m-1)//3 + 1paham juga tidak semuanya bisa dibaca, tidak banyak orang yang tahu apa //. Komentar asli saya hanyalah pernyataan "calculations can go wrong"yang terdengar aneh bagi saya.
Russ Bradberry
@RussBradberry sebenarnya saya setuju dengan Anda jawaban saya adalah sebagai alternatif dan untuk memperbaikinya kadang-kadang ada alternatif Saya telah melihat banyak kode di mana orang mencoba menghitung / menyimpulkan sesuatu yang hanya dapat di-hardcode di peta
Anurag Uniyal
0

Berikut ini adalah solusi bertele-tele, tetapi juga dapat dibaca yang akan berfungsi untuk contoh tanggal dan waktu

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
aliran api
sumber
0

menggunakan kamus, Anda dapat melakukannya

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