Skip to content

Commit

Permalink
Added ndloc indexing interface
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Jun 18, 2017
1 parent d2ac1d0 commit b91554c
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 1 deletion.
7 changes: 6 additions & 1 deletion holoviews/core/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import param

from ..dimension import redim
from .interface import Interface, iloc
from .interface import Interface, iloc, ndloc
from .array import ArrayInterface
from .dictionary import DictInterface
from .grid import GridInterface
Expand Down Expand Up @@ -635,6 +635,11 @@ def iloc(self):
return iloc(self)


@property
def ndloc(self):
return ndloc(self)


# Aliases for pickle backward compatibility
Columns = Dataset
ArrayColumns = ArrayInterface
Expand Down
47 changes: 47 additions & 0 deletions holoviews/core/data/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,53 @@ def canonicalize(cls, dataset, data, coord_dims=None):
return data


@classmethod
def invert_index(cls, index, length):
if np.isscalar(index):
return length - index
elif isinstance(index, slice):
start, stop = index.start, index.stop
new_start, new_stop = None, None
if start is not None:
new_stop = length - start
if stop is not None:
new_start = length - stop
return slice(new_start-1, new_stop-1)
elif isinstance(index, Iterable):
new_index = []
for ind in index:
new_index.append(length-ind)
return new_index


@classmethod
def ndloc(cls, dataset, indices):
selected = {}
adjusted_inds = []
all_scalar = True
for kd, ind in zip(dataset.kdims[::-1], indices):
coords = cls.coords(dataset, kd.name)
if np.all(coords[1:] < coords[:-1]):
ind = cls.invert_index(ind, len(coords))
if np.isscalar(ind):
ind = [ind]
else:
all_scalar = False
selected[kd.name] = coords[ind]
adjusted_inds.append(ind)
for kd in dataset.kdims:
if kd.name not in selected:
coords = cls.coords(dataset, kd.name)
selected[kd.name] = coords
all_scalar = False
for vd in dataset.vdims:
arr = dataset.dimension_values(vd, flat=False)
if all_scalar and len(dataset.vdims) == 1:
return arr[tuple(ind[0] for ind in adjusted_inds)]
selected[vd.name] = arr[tuple(adjusted_inds)]
return tuple(selected[d.name] for d in dataset.dimensions())


@classmethod
def values(cls, dataset, dim, expanded=True, flat=True):
dim = dataset.get_dimension(dim, strict=True)
Expand Down
7 changes: 7 additions & 0 deletions holoviews/core/data/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ def reindex(cls, dataset, kdims=None, vdims=None):
return data[..., inds] if len(inds) > 1 else data[..., inds[0]]
return data

@classmethod
def coords(cls, dataset, dim, ordered=False, expanded=False):
dim = dataset.get_dimension(dim, strict=True)
if expanded:
return util.expand_grid_coords(dataset, dim)
return cls.values(dataset, dim, expanded=False)

@classmethod
def range(cls, obj, dim):
dim_idx = obj.get_dimension_index(dim)
Expand Down
21 changes: 21 additions & 0 deletions holoviews/core/data/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,27 @@ def __getitem__(self, index):
datatype=datatype)


class ndloc(object):

def __init__(self, dataset):
self.dataset = dataset

def __getitem__(self, indices):
ds = self.dataset
indices = util.wrap_tuple(indices)
if not ds.interface.gridded:
raise IndexError('Cannot use ndloc on non nd-dimensional datastructure')
selected = self.dataset.interface.ndloc(ds, indices)
if np.isscalar(selected):
return selected
datatype = [dt for dt in ds.datatype if dt in Interface.interfaces and
Interface.interfaces[dt].gridded]
params = {}
if hasattr(ds, 'bounds'):
params['bounds'] = None
return self.dataset.clone(selected, datatype=[ds.interface.datatype]+datatype, **params)


class Interface(param.Parameterized):

interfaces = {}
Expand Down

0 comments on commit b91554c

Please sign in to comment.