Skip to content

Commit 8e0f41e

Browse files
committed
Date Chunker support for DatetimeIndexes
1 parent da5c22d commit 8e0f41e

File tree

4 files changed

+28
-5
lines changed

4 files changed

+28
-5
lines changed

arctic/chunkstore/chunkstore.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def delete(self, symbol, chunk_range=None):
9494
chunk_range: range object
9595
a date range to delete
9696
"""
97-
if chunk_range:
97+
if chunk_range is not None:
9898
# read out chunks that fall within the range and filter out
9999
# data within the range
100100
df = self.read(symbol, chunk_range=chunk_range, filter_data=False)
@@ -166,7 +166,8 @@ def read(self, symbol, chunk_range=None, columns=None, filter_data=True):
166166
the symbol to retrieve
167167
chunk_range: object
168168
corresponding range object for the specified chunker (for
169-
DateChunker it is a DateRange object)
169+
DateChunker it is a DateRange object or a DatetimeIndex,
170+
as returned by pandas.date_range
170171
columns: list of str
171172
subset of columns to read back (index will always be included, if
172173
one exists)
@@ -186,7 +187,7 @@ def read(self, symbol, chunk_range=None, columns=None, filter_data=True):
186187
spec = {SYMBOL: symbol,
187188
}
188189

189-
if chunk_range:
190+
if chunk_range is not None:
190191
spec.update(self.chunker.to_mongo(chunk_range))
191192

192193
segments = []
@@ -284,7 +285,7 @@ def __update(self, symbol, item, combine_method=None, chunk_range=None):
284285
if sym[TYPE] == 'dataframe' and not isinstance(item, DataFrame):
285286
raise Exception("Cannot combine DataFrame and Series")
286287

287-
if chunk_range:
288+
if chunk_range is not None:
288289
self.delete(symbol, chunk_range)
289290
sym = self._get_symbol_info(symbol)
290291

@@ -365,7 +366,7 @@ def update(self, symbol, item, chunk_range=None):
365366
original data.
366367
"""
367368

368-
if chunk_range:
369+
if chunk_range is not None:
369370
if self.chunker.filter(item, chunk_range).empty:
370371
raise Exception('Range must be inclusive of data')
371372
self.__update(symbol, item, combine_method=self.__concat, chunk_range=chunk_range)

arctic/chunkstore/date_chunker.py

+6
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ def to_mongo(self, range_obj):
6161
-------
6262
string
6363
"""
64+
if isinstance(range_obj, pd.DatetimeIndex):
65+
range_obj = DateRange(range_obj.min(), range_obj.max())
6466
if range_obj.start and range_obj.end:
6567
return {'$and': [{START: {'$lte': range_obj.end}}, {END: {'$gte': range_obj.start}}]}
6668
elif range_obj.start:
@@ -83,6 +85,8 @@ def filter(self, data, range_obj):
8385
-------
8486
data, filtered by range_obj
8587
"""
88+
if isinstance(range_obj, pd.DatetimeIndex):
89+
range_obj = DateRange(range_obj.min(), range_obj.max())
8690
if 'date' in data.index.names:
8791
return data[range_obj.start:range_obj.end]
8892
elif 'date' in data.columns:
@@ -98,6 +102,8 @@ def exclude(self, data, range_obj):
98102
-------
99103
data, filtered by range_obj
100104
"""
105+
if isinstance(range_obj, pd.DatetimeIndex):
106+
range_obj = DateRange(range_obj.min(), range_obj.max())
101107
if 'date' in data.index.names:
102108
return data[(data.index.get_level_values('date') < range_obj.start) | (data.index.get_level_values('date') > range_obj.end)]
103109
elif 'date' in data.columns:

tests/integration/chunkstore/test_chunkstore.py

+2
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ def test_write_read_with_daterange(chunkstore_lib):
120120
read_df = chunkstore_lib.read('test_df', chunk_range=DateRange(dt(2016, 1, 1), dt(2016, 1, 2)))
121121

122122
assert_frame_equal(read_df, dg)
123+
read_with_dr = chunkstore_lib.read('test_df', chunk_range=pd.date_range(dt(2016, 1, 1), dt(2016, 1, 2)))
124+
assert_frame_equal(read_df, dg)
123125

124126

125127
def test_write_read_with_daterange_noindex(chunkstore_lib):

tests/unit/chunkstore/test_date_chunker.py

+14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from datetime import datetime as dt
44
from arctic.date import DateRange
55
from pandas.util.testing import assert_frame_equal
6+
import pandas as pd
67

78

89
def test_date_filter():
@@ -28,3 +29,16 @@ def test_date_filter():
2829
assert_frame_equal(c.filter(df, DateRange(None, dt(2020, 1, 1))), df)
2930
# CLOSED - CLOSED (after range)
3031
assert(c.filter(df, DateRange(dt(2017, 1, 1), dt(2018, 1, 1))).empty)
32+
33+
34+
def test_date_filter_with_pd_date_range():
35+
c = DateChunker()
36+
df = DataFrame(data={'data': [1, 2, 3]},
37+
index=MultiIndex.from_tuples([(dt(2016, 1, 1), 1),
38+
(dt(2016, 1, 2), 1),
39+
(dt(2016, 1, 3), 1)],
40+
names=['date', 'id'])
41+
)
42+
43+
assert(c.filter(df, pd.date_range(dt(2017, 1, 1), dt(2018, 1, 1))).empty)
44+
assert_frame_equal(c.filter(df, pd.date_range(dt(2016, 1, 1), dt(2017, 1, 1))), df)

0 commit comments

Comments
 (0)