Elbette bunu kendim yazabilirim, ancak tekerleği yeniden icat etmeden önce bunu zaten yapan bir işlev var mı?
pandas.Series.dt.quarter
.
Elbette bunu kendim yazabilirim, ancak tekerleği yeniden icat etmeden önce bunu zaten yapan bir işlev var mı?
pandas.Series.dt.quarter
.
Yanıtlar:
Bir örnek göz önüne alındığında x
ait datetime.date , (x.month-1)//3
sen ;-) yerine 1'den saymak gerekirse 1 eklenir - vb ikinci çeyrek için, ilk çeyreği için size 1 çeyrek (0 verecektir.
Başlangıçta iki cevap, çarpılarak yükseltilmiş ve hatta başlangıçta kabul edilmiş (her ikisi de şu anda silinmiş) hatalıydı - -1
önceki bölümü yapmamak ve 3 yerine 4'e bölmek. .month
1'den 12'ye kadar olduğu için formülün ne olduğunu kendiniz kontrol etmek kolaydır. sağ:
for m in range(1, 13):
print m//4 + 1,
print
verir 1 1 1 2 2 2 2 3 3 3 3 4
- dört aylık iki çeyrek ve bir aylık bir (eep).
for m in range(1, 13):
print (m-1)//3 + 1,
print
verir 1 1 1 2 2 2 3 3 3 4 4 4
- şimdi bu sizin için çok tercih edilir görünmüyor mu? -)
Bu, sorunun haklı olduğunu kanıtlıyor, sanırım ;-).
Datetime modülünün her olası yararlı takvim işlevine sahip olması gerektiğini düşünmüyorum, ancak datetools
işyerinde projelerimin (ve diğerlerinin) kullanımı için bir (iyi test edilmiş ;-) modülüne sahip olduğumu biliyorum ; tüm bu takvim hesaplamalarını gerçekleştirmek için işlevler - bazıları karmaşık, bazıları basit, ancak bu tür hesaplamalarda işi tekrar tekrar yapmak (hatta basit işler bile) veya hata riski ;-).
(m+2)//3
Bunun yerine(m-1)//3 + 1
EĞER zaten kullandığınız pandas
, oldukça basit.
import datetime as dt
import pandas as pd
quarter = pd.Timestamp(dt.date(2016, 2, 29)).quarter
assert quarter == 1
Bir veri çerçevesinde bir date
sütununuz varsa, kolayca yeni bir quarter
sütun oluşturabilirsiniz :
df['quarter'] = df['date'].dt.quarter
pandas.Series.dt.quarter
, Dataframe veya Series nesnesinde datetime değerlerine sahip olduğunuzda ideal bir çözümdür .
Tartışmalı olarak daha temiz başka bir çözüm öneririm. X bir datetime.datetime.now()
örnek ise, çeyrek şu şekildedir:
import math
Q=math.ceil(X.month/3.)
ceil doğrudan erişilemediği için matematik modülünden içe aktarılmalıdır.
math.ceil(float(4)/3) = 2.0
süremath.ceil(4/3) = 1.0
.
3'ün ne yaptığını anlamadım. math.ceil(4/3.) = 2.0
Takvim yılından farklı olabilecek mali yılın çeyreğini almaya çalışan herkes için , bunu yapmak için bir Python modülü yazdım.
Kurulum basittir. Sadece koş:
$ pip install fiscalyear
Bağımlılık yoktur ve fiscalyear
hem Python 2 hem de 3 için çalışmalıdır.
Temelde yerleşik datetime modülü etrafında bir sarmalayıcıdır , bu nedenle datetime
zaten aşina olduğunuz tüm komutlar çalışacaktır. İşte bir demo:
>>> 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 ve PyPI'de barındırılmaktadır . Belgeler, Belgeleri Okuyun adresinde bulunabilir . Şu anda sahip olmayan herhangi bir özelliği arıyorsanız, bize bildirin!
Bir datetime.datetime nesnesi alan ve her çeyrek için benzersiz bir dize döndüren bir işlev örneği aşağıda verilmiştir:
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))
Ve çıktı:
2019-02-14 Q1_2019
2018-11-16 Q4_2018
2017-08-18 Q3_2017
Bu yöntem herhangi bir eşleme için işe yarar:
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
Az önce bir fonksiyon oluşturduk int->int
month2quarter(9) # returns 3
Bu yöntem aynı zamanda kusursuzdur
month2quarter(-1) # returns None
month2quarter('July') # returns None
Pandalar kullanarak mali yıl çeyrek verilerini arayanlar için,
import datetime
import pandas as pd
today_date = datetime.date.today()
quarter = pd.PeriodIndex(today_date, freq='Q-MAR').strftime('Q%q')
başvuru: pandalar dönem dizini
Bu eski bir sorudur ama yine de tartışmaya değer.
İşte benim çözümüm, mükemmel dateutil modülünü kullanarak .
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)
Bu first_day
, çeyreğin ilk günüdür ve çeyreğin last_day
son günüdür (sonraki çeyreğin ilk günü eksi bir gün bulunarak hesaplanır).
hmmm hesaplamalar yanlış gidebilir, işte daha iyi bir versiyon (sadece uğruna)
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"
. Tüm iyi geliştiricilerin yapması gerektiği gibi testler yazmalısınız. Testler, sizi hata yapmaktan alıkoymaya ve yaptığınız hataları yakalamanıza yardımcı olan şeydir. Bir geliştirici, hata yapmasını engellemek için performans ve okunabilirlikten asla ödün vermemelidir. Ayrıca, bu, değişmez değerleri kullanarak statik bir diktede bulunmanızdan daha az okunabilir.
(m-1)//3 + 1
o kadar da okunabilir değil, çoğu insan ne yaptığını bilmiyor //
. Orijinal yorumum sadece "calculations can go wrong"
bana garip gelen ifadesi üzerineydi.
İşte datetime ve tarih örnekleri için çalışacak ayrıntılı, ancak okunabilir bir çözüm
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
sözlükleri kullanarak, bunu şu şekilde yapabilirsiniz:
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))