2016-02-16 15 views
6

Próbuję wygenerować zakres dat półrocznych za pomocą języka Python. Pandas zapewnia funkcję pd.date_range, aby pomóc w tym, jednak chciałbym, aby mój zakres dat zaczynał się od daty końcowej i wykonywał iterację wstecz.Pandy data_range od daty zakończenia do daty początkowej

Na przykład ze względu na wejście:

start = datetime.datetime(2016 ,2, 8) 
end = datetime.datetime(2018 , 6, 1) 
pd.date_range(start, end, freq='6m') 

wynik jest:

DatetimeIndex(['2016-02-29', '2016-08-31', '2017-02-28', '2017-08-31', 
       '2018-02-28']) 

Jak mogę generować następujące:

DatetimeIndex(['2016-02-08', '2016-06-01', '2016-12-01', '2017-06-01', 
       '2017-12-01', '2018-06-01']) 
+1

Usunięto moją początkową odpowiedź. Myślę, że najważniejsze jest przesunięcie, czy to prawda? – Maximilian

+0

@Maximilian yeah to inny sposób na umieszczenie go. – pyCthon

Odpowiedz

4

Z zaktualizowanego wyjścia (z edycji utworzonego) można zrobić coś jak poniżej:

from pandas.tseries.offsets import DateOffset 

end = datetime.datetime(2018 , 6, 1) 
start = datetime.datetime(2016 ,2, 8) 
#Get the range of months to cover 
months = (end.year - start.year)*12 + end.month - start.month 
#The frequency of periods 
period = 6 # in months 

pd.DatetimeIndex([end - DateOffset(months=e) for e in range(0, months, period)][::-1]).insert(0, start) 

Jest to dość zwięzły rozwiązanie, chociaż nie porównałem środowisk wykonawczych, więc nie jestem pewien, jak szybko to działa.

Zasadniczo jest to po prostu tworzenie dat, których potrzebujesz jako listy, a następnie przekształcenie ich w indeks datetime.

2

Można to zrobić bez: pandy i zamiast tego należy użyć datutil. Jednak jest to bardziej złożone niż to może powinien:

from datetime import date 
import math 
from dateutil.relativedelta import relativedelta 

#set up key dates 
start = date(2016 ,2, 8) 
end = date(2018 , 6, 1) 

#calculate date range and number of 6 month periods 
daterange = end-start 
periods = daterange.days *2//365 

#calculate next date in sequence and check for year roll-over 
next_date = date(start.year,math.ceil(start.month/6)*6,1) 
if next_date < start: next_date = date(next_date.year+1,next_date.month,1) 

#add the first two values to a list 
arr = [start.isoformat(),next_date.isoformat()] 

#calculate all subsequent dates using 'relativedelta' 
for i in range(periods): 
    next_date = next_date+ relativedelta(months=+6) 
    arr.append(next_date.isoformat()) 


#display results 
print(arr) 
+0

Występuje błąd 'TypeError: oczekiwany argument liczby całkowitej, został zmieniony na' next_date = '. – pyCthon

+0

@pyCthon co to jest linia next_date? Pierwszy lub jeden w pętli for? Jeśli później, może to oznaczać, że nie masz zainstalowanego dateutil, o czym powinienem wspomnieć. –

+0

Pierwsza, datautil jest zainstalowana, mam ''2.4.2''' – pyCthon