[英]Creating a list using a date as index
我創建了一個使用日期列表作為索引的列表,如下所示:
>>> import datedlist
>>> import datetime
>>> dates = [datetime.date(2012,1,x) for x in range(2,6)]
>>> values = range(4,8)
>>> dates
[datetime.date(2012, 1, 2), datetime.date(2012, 1, 3), datetime.date(2012, 1, 4), datetime.date(2012, 1, 5)]
>>> dl = datedlist.DatedList(values, dates)
>>> dl
[4, 5, 6, 7]
>>> dl[datetime.date(2012,1,3)]
5
到目前為止,一切都很好,但我也希望能夠用切片(不延長切片),像這樣(以下不能正常工作-這是我想要的結果):
>>> datedlist[datetime.date(2012,1,3):datetime.date(2012,1,4)]
[5, 6]
這是我對此的嘗試(顯然不起作用):
class DatedList(list):
def __init__(self, values, dates):
self.dates = dates
list.__init__(self, values)
def __getitem__(self, date):
if isinstance(date, slice):
start = self.dates.index(slice[0])
end = self.dates.index(slice[1])
return [list.__getitem__(self, index) for index in range(start, end)]
elif isinstance( date, datetime.date ) :
index = self.dates.index(date)
return list.__getitem__(self, index)
elif isinstance(date, int):
if date < 0:
date += len(self)
if date >= len(self):
raise IndexError, "index out of range {}".format(date)
return list.__getitem__(self, date)
else:
raise TypeError, "Invalid argument type."
切片[0]和切片[1]僅用於解釋我的意圖。 isinstance(date,int)僅用於調試 - 將刪除生產代碼。
這是一個問題 :如何實現使用datetime.date對象作為索引的切片?
編輯(在gnibblers第2條評論之后):我也嘗試過getslice(即使文檔說getslice已經過時)。 然后該類看起來像這樣(由於語法,isinstance-slice位被注釋掉):
class DatedList(list):
def __init__(self, values, dates):
self.dates = dates
list.__init__(self, values)
def __contains__(self, date):
return date in self.dates
def __getslice__(self, fromdate, todate):
i_from = self.get_index(fromdate)
i_to = self.get_index(todate)
print i_from, i_to
return [list.__getitem__(self, i) for i in range(i_from, i_to)]
def __getitem__(self, date):
if isinstance(date, slice):
pass
# start = self.dates.index(slice[0])
# end = self.dates.index(slice[1])
# return [list.__getitem__(self, i) for i in range(start, end)]
elif isinstance(date, datetime.date):
index = self.get_index(date)
return list.__getitem__(self, index)
elif isinstance(date, int):
if date < 0:
date += len(self)
if date >= len(self):
raise IndexError, "index out of range {}".format(date)
return list.__getitem__(self, date)
else:
raise TypeError, "Invalid argument type."
def get_index(self, date):
if date in self.dates:
index = self.dates.index(date)
elif date < self.dates[0]:
index = 0
elif date > self.dates[-1]:
index = len(self.dates) - 1
return index
結果是:
>>> print dl[datetime.date(2012,1,3):datetime.date(2012,1,5)]
>>> None
顯然,完全沒有使用過,因為打印沒有被執行。 看來getitem在請求切片時執行,但我似乎無法在切片中使用datetime.date。 /編輯
注意:顯然,將子類列入子列並不是一個好主意,但到目前為止,我嘗試過的替代方案似乎都沒有更好(或根本沒有):
從頭開始構建一個類:我無法使[]表示法工作:
dl = DatedList(values, dates) value = dl[some_date] # I want this to work value = dl.value(same_date) # I don't want this
我考慮使用dict,但我的列表需要訂購,我也需要使用切片。
我也嘗試將collections.Sequence子類化,但結果是:
TypeError:描述符' init '需要'list'對象但收到'DatedList'
您可能希望查看一些現有的時間序列實現,而不是重新實現它。 熊貓和scikits.timeseries一樣非常好。
作為一個例子,與熊貓:
In [1]: from pandas import Series, DateRange
In [2]: import datetime
In [3]: ts = Series(range(12), index=DateRange('1/1/2000', periods=12, freq='T'))
In [4]: ts
Out[4]:
2000-01-03 0
2000-01-04 1
2000-01-05 2
2000-01-06 3
2000-01-07 4
2000-01-10 5
2000-01-11 6
2000-01-12 7
2000-01-13 8
2000-01-14 9
2000-01-17 10
2000-01-18 11
In [5]: ts[datetime.datetime(2000,1,10):]
Out[5]:
2000-01-10 5
2000-01-11 6
2000-01-12 7
2000-01-13 8
2000-01-14 9
2000-01-17 10
2000-01-18 11
或者,您可以調查那里的源代碼並重新實現您的具體情況。
這是一個非常簡單的示例,基本上您將參數傳遞給__getitem__
並將它們傳遞給映射,以便您可以利用構建列表行為。
至於你提到的__getslice__
是過時的, __getitem__
只需要注意到它已經通過了slice
,並用它妥善處理。
import datetime
class DatedList(list):
def __init__(self, values, dates):
list.__init__(self, values)
self.dates = dates
self._dt_to_idx = {k:v for v,k in enumerate(dates)}
def __getitem__(self, arg):
if isinstance(arg, slice):
start = self._dt_to_idx[arg.start]
stop = self._dt_to_idx[arg.stop]
return list.__getitem__(self, slice(start, stop, arg.step))
else:
return list.__getitem__(self, self._dt_to_idx[arg])
dates = [datetime.date(2012,1,x) for x in range(2,6)]
dl = DatedList([1,2,3,4], dates)
print dl[dates[2]]
print dl[dates[1]:dates[3]]
如果你需要一個更復雜的映射 - 處理跳過的日期等,只需定義一個方法來進行映射並調用你使用self._dt_to_idx[...]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.