2011-06-23 20 views
7

Datetime nesnelerini ondalık yıla dönüştürmenin bir yolunu arıyorum. Aşağıdapython datetime tarihlerini onluk aya dönüştürebilir

>>> obj = SomeObjet() 
>>> obj.DATE_OBS 
datetime.datetime(2007, 4, 14, 11, 42, 50) 

Nasıl datetime.datetime dönüştürebilirim bir örnek (2007, 4, 14, 11, 42, 50) ondalık yıllara mı? Bu biçimden gg/aa/yyyy biçiminde bu tür bir yyyy.yyyy

+0

Bir örnek verebilir misiniz? "Ondalık yıl" ile ne demek istiyorsun? –

+0

Bu biçimden gg/aa/yyyy biçiminde yyyy.yyyy – user739807

+0

Yani, kayan nokta sayılarına dönüştürmek mi demek istiyorsunuz? Gibi - gün/ay/saat/etc bir sayıya dönüştürmek? Eğer öyleyse, o zaman bunu kendiniz hesaplamanız gerekir. –

cevap

18
from datetime import datetime as dt 
import time 

def toYearFraction(date): 
    def sinceEpoch(date): # returns seconds since epoch 
     return time.mktime(date.timetuple()) 
    s = sinceEpoch 

    year = date.year 
    startOfThisYear = dt(year=year, month=1, day=1) 
    startOfNextYear = dt(year=year+1, month=1, day=1) 

    yearElapsed = s(date) - s(startOfThisYear) 
    yearDuration = s(startOfNextYear) - s(startOfThisYear) 
    fraction = yearElapsed/yearDuration 

    return date.year + fraction 

Demo: (Gün ışığından veya diğer garip bölgesel şeyler yürürlükte ise veya saate)

>>> toYearFraction(dt.today()) 
2011.47447514 

Bu yöntem, muhtemelen ikinci dahilinde doğrudur. Ayrıca, oraklar sırasında doğru şekilde çalışır. Eğer zorlu bir çözünürlüğe ihtiyacınız varsa (örneğin Dünya'nın rotasyonundaki değişiklikler nedeniyle) bir net servisi sorgulamaktan daha iyi olursunuz.

+0

Cevabım çok daha basit ve eşdeğer bir yüzdürme sağlıyor. Çözümlerimizden hiçbiri kesindir, ancak belli bir anın belirli bir anı bir yılın ondalık bir temsiline dönüştürmek için genel olarak kabul edilebilir bir standart yoktur, değil mi? – Kimvais

+0

@Kimvais evet, var; iyi tanımlanmış bir miktardır. Bu bir saat içinde doğru, kütüphaneler gün ışığından yararlanırsa daha fazla şey yaparlarsa (ki bunu yaptıklarını sanmıyorum). – ninjagecko

+0

Üzgünüm, 'genel olarak kabul edilen standart' değil 'genel olarak kabul edilebilir ...' – Kimvais

2

Bu süreyi, datetime değerlerini karşılaştırmak için kullandığınızı kabul ediyorum. Bunu yapmak için, tekerleği yeniden tanımlamak yerine lütfen timedelta nesnelerini kullanın.

Örnek:

>>> from datetime import timedelta 
>>> from datetime import datetime as dt 
>>> d = dt.now() 
>>> year = timedelta(days=365) 
>>> tomorrow = d + timedelta(days=1) 
>>> tomorrow + year > d + year 
True 

ise nedense gerçekten ihtiyaç ondalık yıl için %j istedi eğer yöntem strftime() size yılı ait günün bir tamsayı gösterimi verebilir datetime nesneler - bu ise Ne arıyorsanız, basit bir örnek için aşağıya bakın (yalnızca 1 günlük çözünürlükte):

>>> from datetime import datetime 
>>> d = datetime(2007, 4, 14, 11, 42, 50) 
>>> (float(d.strftime("%j"))-1)/366 + float(d.strftime("%Y")) 
2007.2814207650274 
+0

Bu yöntem, yıla bağlı olarak yaklaşık 1-2 gün boyunca yanlıştır ve kaç yıl. Yılda 367 gün neden varsaydığınızı da karıştırıyorum. – ninjagecko

+0

367, böylece artık yılın son günü, tam olarak bir sonraki yıl olmayacak. – Kimvais

+1

bu doğru bir şey değil. Ayrıca başka bir hata var: her zaman 2010.0' ve 2011.0'ları ve diğer tüm sayıları atlayabilirsiniz, çünkü datetime (yıl = 2011, month = 1, day = 1) .strftime ("% j") 1 değil 0'dır. Düzeltme, 1'i çıkarmaktır, ancak bu, bir gün boyunca hala, oraklar sırasında yanlıştır. – ninjagecko

0

Bu, diğer çözümlere göre biraz daha basit yoludur: Bu 0.997 değil 1,0 olacak 31 Aralık böylece günün başlangıcında dayalı fraksiyonu, hesaplar

import datetime 
def year_fraction(date): 
    start = datetime.date(date.year, 1, 1).toordinal() 
    year_length = datetime.date(date.year+1, 1, 1).toordinal() - start 
    return date.year + float(date.toordinal() - start)/year_length 

>>> print year_fraction(datetime.datetime.today()) 
2016.32513661 

Not.

0

Şaşırmış hiç kimse bundan bahsetmedi ... datetime.datetime nesnelerinin çıkarılmasından kaynaklanan datetime.timedelta nesnelerinin bir bölümleme yöntemi vardır. Yani, bölünme datetime.timedelta nesneler arasında basit işlevi

from datetime import datetime 
def datetime2year(dt): 
    year_part = dt - datetime(year=dt.year, month=1, day=1) 
    year_length = datetime(year=dt.year+1, month=1, day=1) - datetime(year=dt.year, month=1, day=1) 
    return dt.year + year_part/year_length 

kullanabilirsiniz.

0

Pandaların julian tarihini ve aşağıdaki formülleri kullanarak ondalık tarihi hesaplamak mümkündür.

JD=dat.index.to_julian_date() #create julian date 
L= JD+68569 
N= 4*L/146097 
L= L-(146097*N+3)/4 
I= 4000*(L+1)/1461001 
L= L-1461*I/4+31 
J= 80*L/2447 
K= L-2447*J/80 
L= J/11 
J= J+2-12*L 
decimal_date= 100*(N-49)+I+L 

decimal_date (dataframe endeksi aynı TZ içinde) tarih dizisidir 2007.123452 gibi bir şey şeklinde: En pandalar dataframe tarih-saat olan bir dizini durumda

.

dat['decimal_date']=dat.index.year+ (dat.index.dayofyear -1)/365 

bir tarih-saat endeksi Pandalar dataframe kullanılabilir olmalı:

Adapted from this post.

0

kabul çözümünü uygulamadan sonra, bu modern panda sürümü özdeş ve daha basit olduğu vahiy vardı.Bu sorunun yayınlanması için google aramada en üstte bu çözüm yazısı ekleniyor.

İlgili konular