Skip to content

Commit

Permalink
Merge pull request #1083 from ioam/dimension_aliases_switched
Browse files Browse the repository at this point in the history
Add Dimension.label replacing global alias state
  • Loading branch information
jlstevens authored Jan 30, 2017
2 parents 7d4f0b7 + b759400 commit bfdad59
Show file tree
Hide file tree
Showing 17 changed files with 402 additions and 139 deletions.
43 changes: 28 additions & 15 deletions holoviews/core/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ def __call__(self, new_type, kdims=None, vdims=None, groupby=None,
groupby = [groupby]

selected = self._element.reindex(groupby+kdims, vdims)
params = {'kdims': [selected.get_dimension(kd) for kd in kdims],
'vdims': [selected.get_dimension(vd) for vd in vdims],
params = {'kdims': [selected.get_dimension(kd, strict=True) for kd in kdims],
'vdims': [selected.get_dimension(vd, strict=True) for vd in vdims],
'label': selected.label}
if selected.group != selected.params()['group'].default:
params['group'] = selected.group
Expand Down Expand Up @@ -148,9 +148,16 @@ def __init__(self, data, **kwargs):
pvals = util.get_param_values(data)
kwargs.update([(l, pvals[l]) for l in ['group', 'label']
if l in pvals and l not in kwargs])
initialized = Interface.initialize(type(self), data,
kwargs.get('kdims'),
kwargs.get('vdims'),

kdims, vdims = None, None
if 'kdims' in kwargs:
kdims = [kd if isinstance(kd, Dimension) else Dimension(kd)
for kd in kwargs['kdims']]
if 'vdims' in kwargs:
vdims = [kd if isinstance(kd, Dimension) else Dimension(kd)
for kd in kwargs['vdims']]

initialized = Interface.initialize(type(self), data, kdims, vdims,
datatype=kwargs.get('datatype'))
(data, self.interface, dims, extra_kws) = initialized
super(Dataset, self).__init__(data, **dict(extra_kws, **dict(kwargs, **dims)))
Expand Down Expand Up @@ -195,6 +202,8 @@ def sort(self, by=[]):
Sorts the data by the values along the supplied dimensions.
"""
if not by: by = self.kdims
if not isinstance(by, list): by = [by]

sorted_columns = self.interface.sort(self, by)
return self.clone(sorted_columns)

Expand All @@ -206,7 +215,9 @@ def range(self, dim, data_range=True):
object.
"""
dim = self.get_dimension(dim)
if None not in dim.range:
if dim is None:
return (None, None)
elif None not in dim.range:
return dim.range
elif dim in self.dimensions() and data_range:
if len(self):
Expand Down Expand Up @@ -234,7 +245,7 @@ def add_dimension(self, dimension, dim_pos, dim_val, vdim=False, **kwargs):
dimensions and a key value scalar or sequence of the same length
as the existing keys.
"""
if isinstance(dimension, str):
if isinstance(dimension, (util.basestring, tuple)):
dimension = Dimension(dimension)

if dimension.name in self.kdims:
Expand Down Expand Up @@ -282,12 +293,12 @@ def reindex(self, kdims=None, vdims=None):
if kdims is None:
key_dims = [d for d in self.kdims if not vdims or d not in vdims]
else:
key_dims = [self.get_dimension(k) for k in kdims]
key_dims = [self.get_dimension(k, strict=True) for k in kdims]

if vdims is None:
val_dims = [d for d in self.vdims if not kdims or d not in kdims]
else:
val_dims = [self.get_dimension(v) for v in vdims]
val_dims = [self.get_dimension(v, strict=True) for v in vdims]

data = self.interface.reindex(self, key_dims, val_dims)
return self.clone(data, kdims=key_dims, vdims=val_dims)
Expand Down Expand Up @@ -369,10 +380,10 @@ def aggregate(self, dimensions=None, function=None, spreadfn=None, **kwargs):
raise ValueError("The aggregate method requires a function to be specified")
if dimensions is None: dimensions = self.kdims
elif not isinstance(dimensions, list): dimensions = [dimensions]
aggregated = self.interface.aggregate(self, dimensions, function, **kwargs)
kdims = [self.get_dimension(d, strict=True) for d in dimensions]
aggregated = self.interface.aggregate(self, kdims, function, **kwargs)
aggregated = self.interface.unpack_scalar(self, aggregated)

kdims = [self.get_dimension(d) for d in dimensions]
vdims = self.vdims
if spreadfn:
error = self.interface.aggregate(self, dimensions, spreadfn)
Expand Down Expand Up @@ -478,7 +489,7 @@ def dimension_values(self, dim, expanded=True, flat=True):
Returns the values along a particular dimension. If unique
values are requested will return only unique values.
"""
dim = self.get_dimension(dim, strict=True).name
dim = self.get_dimension(dim, strict=True)
return self.interface.values(self, dim, expanded, flat)


Expand All @@ -499,13 +510,15 @@ def dframe(self, dimensions=None):
Returns the data in the form of a DataFrame.
"""
if dimensions:
dimensions = [self.get_dimension(d).name for d in dimensions]
dimensions = [self.get_dimension(d, strict=True).name for d in dimensions]
return self.interface.dframe(self, dimensions)


def columns(self, dimensions=None):
if dimensions is None: dimensions = self.dimensions()
dimensions = [self.get_dimension(d) for d in dimensions]
if dimensions is None:
dimensions = self.dimensions()
else:
dimensions = [self.get_dimension(d, strict=True) for d in dimensions]
return {d.name: self.dimension_values(d) for d in dimensions}


Expand Down
2 changes: 1 addition & 1 deletion holoviews/core/data/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def groupby(cls, dataset, dimensions, container_type, group_type, **kwargs):
data = dataset.data

# Get dimension objects, labels, indexes and data
dimensions = [dataset.get_dimension(d) for d in dimensions]
dimensions = [dataset.get_dimension(d, strict=True) for d in dimensions]
dim_idxs = [dataset.get_dimension_index(d) for d in dimensions]
ndims = len(dimensions)
kdims = [kdim for kdim in dataset.kdims
Expand Down
21 changes: 12 additions & 9 deletions holoviews/core/data/dask.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ def sort(cls, columns, by=[]):

@classmethod
def values(cls, columns, dim, expanded=True, flat=True):
data = columns.data[dim]
dim = columns.get_dimension(dim)
data = columns.data[dim.name]
if not expanded:
data = data.unique()
return data.compute().values
Expand All @@ -88,7 +89,8 @@ def select_mask(cls, dataset, selection):
if isinstance(k, tuple):
k = slice(*k)
masks = []
series = dataset.data[dim]
alias = dataset.get_dimension(dim).name
series = dataset.data[alias]
if isinstance(k, slice):
if k.start is not None:
masks.append(k.start <= series)
Expand Down Expand Up @@ -139,15 +141,16 @@ def groupby(cls, columns, dimensions, container_type, group_type, **kwargs):
group_kwargs.update(kwargs)

data = []
groupby = columns.data.groupby(dimensions)
if len(dimensions) == 1:
column = columns.data[dimensions[0]]
group_by = [d.name for d in index_dims]
groupby = columns.data.groupby(group_by)
if len(group_by) == 1:
column = columns.data[group_by[0]]
if column.dtype.name == 'category':
indices = ((ind,) for ind in column.cat.categories)
else:
indices = ((ind,) for ind in column.unique().compute())
else:
group_tuples = columns.data[dimensions].itertuple()
group_tuples = columns.data[group_by].itertuple()
indices = util.unique_iterator(ind[1:] for ind in group_tuples)
for coord in indices:
if any(isinstance(c, float) and np.isnan(c) for c in coord):
Expand All @@ -161,12 +164,12 @@ def groupby(cls, columns, dimensions, container_type, group_type, **kwargs):
return container_type(data, kdims=index_dims)
else:
return container_type(data)

@classmethod
def aggregate(cls, columns, dimensions, function, **kwargs):
data = columns.data
cols = [d.name for d in columns.kdims if d in dimensions]
vdims = columns.dimensions('value', True)
vdims = columns.dimensions('value', label='name')
dtypes = data.dtypes
numeric = [c for c, dtype in zip(dtypes.index, dtypes.values)
if dtype.kind in 'iufc' and c in vdims]
Expand Down Expand Up @@ -203,7 +206,7 @@ def unpack_scalar(cls, columns, data):
@classmethod
def sample(cls, columns, samples=[]):
data = columns.data
dims = columns.dimensions('key', label=True)
dims = columns.dimensions('key', label='name')
mask = None
for sample in samples:
if np.isscalar(sample): sample = [sample]
Expand Down
25 changes: 15 additions & 10 deletions holoviews/core/data/dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class DictInterface(Interface):

@classmethod
def dimension_type(cls, dataset, dim):
name = dataset.get_dimension(dim).name
name = dataset.get_dimension(dim, strict=True).name
return dataset.data[name].dtype.type

@classmethod
Expand Down Expand Up @@ -81,7 +81,7 @@ def init(cls, eltype, data, kdims, vdims):

@classmethod
def validate(cls, dataset):
dimensions = dataset.dimensions(label=True)
dimensions = dataset.dimensions(label='name')
not_found = [d for d in dimensions if d not in dataset.data]
if not_found:
raise ValueError('Following dimensions not found in data: %s' % not_found)
Expand Down Expand Up @@ -113,8 +113,11 @@ def length(cls, dataset):

@classmethod
def array(cls, dataset, dimensions):
if not dimensions: dimensions = dataset.dimensions(label=True)
return np.column_stack(dataset.data[dim] for dim in dimensions)
if not dimensions:
dimensions = dataset.dimensions(label='name')
else:
dimensions = [dataset.get_dimensions(d).name for d in dimensions]
return np.column_stack(dataset.data[dim.name] for dim in dimensions)

@classmethod
def add_dimension(cls, dataset, dimension, dim_pos, values, vdim):
Expand Down Expand Up @@ -145,6 +148,7 @@ def concat(cls, dataset_objs):

@classmethod
def sort(cls, dataset, by=[]):
by = [dataset.get_dimension(d).name for d in by]
if len(by) == 1:
sorting = cls.values(dataset, by[0]).argsort()
else:
Expand All @@ -155,17 +159,18 @@ def sort(cls, dataset, by=[]):

@classmethod
def values(cls, dataset, dim, expanded=True, flat=True):
values = np.array(dataset.data.get(dataset.get_dimension(dim).name))
dim = dataset.get_dimension(dim).name
values = np.array(dataset.data.get(dim))
if not expanded:
return util.unique_array(values)
return values


@classmethod
def reindex(cls, dataset, kdims, vdims):
# DataFrame based tables don't need to be reindexed
return OrderedDict([(d.name, dataset.dimension_values(d))
for d in kdims+vdims])
dimensions = [dataset.get_dimension(d).name for d in kdims+vdims]
return OrderedDict([(d, dataset.dimension_values(d))
for d in dimensions])


@classmethod
Expand Down Expand Up @@ -230,8 +235,8 @@ def sample(cls, dataset, samples=[]):

@classmethod
def aggregate(cls, dataset, kdims, function, **kwargs):
kdims = [dataset.get_dimension(d).name for d in kdims]
vdims = dataset.dimensions('value', True)
kdims = [dataset.get_dimension(d, strict=True).name for d in kdims]
vdims = dataset.dimensions('value', label='name')
groups = cls.groupby(dataset, kdims, list, OrderedDict)
aggregated = OrderedDict([(k, []) for k in kdims+vdims])

Expand Down
23 changes: 12 additions & 11 deletions holoviews/core/data/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def coords(cls, dataset, dim, ordered=False, expanded=False):
coordinates are in ascending order and expanded creates
ND-array matching the dimensionality of the dataset.
"""
dim = dataset.get_dimension(dim)
dim = dataset.get_dimension(dim, strict=True)
if expanded:
return util.expand_grid_coords(dataset, dim)
data = dataset.data[dim.name]
Expand All @@ -129,7 +129,7 @@ def canonicalize(cls, dataset, data, coord_dims=None):
dimensions of the dataset.
"""
if coord_dims is None:
coord_dims = dataset.dimensions('key', True)[::-1]
coord_dims = dataset.dimensions('key', label='name')[::-1]

# Reorient data
invert = False
Expand Down Expand Up @@ -162,22 +162,22 @@ def canonicalize(cls, dataset, data, coord_dims=None):

@classmethod
def values(cls, dataset, dim, expanded=True, flat=True):
dim = dataset.get_dimension(dim, strict=True)
if dim in dataset.vdims:
dim = dataset.get_dimension(dim)
data = dataset.data.get(dim.name)
data = cls.canonicalize(dataset, data)
return data.T.flatten() if flat else data
elif expanded:
data = cls.coords(dataset, dim, expanded=True)
data = cls.coords(dataset, dim.name, expanded=True)
return data.flatten() if flat else data
else:
return cls.coords(dataset, dim, ordered=True)
return cls.coords(dataset, dim.name, ordered=True)


@classmethod
def groupby(cls, dataset, dim_names, container_type, group_type, **kwargs):
# Get dimensions information
dimensions = [dataset.get_dimension(d) for d in dim_names]
dimensions = [dataset.get_dimension(d, strict=True) for d in dim_names]
kdims = [kdim for kdim in dataset.kdims if kdim not in dimensions]

# Update the kwargs appropriately for Element group types
Expand Down Expand Up @@ -246,14 +246,15 @@ def key_select_mask(cls, dataset, values, ind):

@classmethod
def select(cls, dataset, selection_mask=None, **selection):
dimensions = dataset.dimensions('key', label=True)
dimensions = dataset.kdims
val_dims = [vdim for vdim in dataset.vdims if vdim in selection]
if val_dims:
raise IndexError('Cannot slice value dimensions in compressed format, '
'convert to expanded format before slicing.')

indexed = cls.indexed(dataset, selection)
selection = [(d, selection.get(d)) for d in dimensions]
selection = [(d, selection.get(d.name, selection.get(d.label)))
for d in dimensions]
data = {}
value_select = []
for dim, ind in selection:
Expand All @@ -264,7 +265,7 @@ def select(cls, dataset, selection_mask=None, **selection):
else:
values = values[mask]
value_select.append(mask)
data[dim] = values
data[dim.name] = values
int_inds = [np.argwhere(v) for v in value_select][::-1]
index = np.ix_(*[np.atleast_1d(np.squeeze(ind)) if ind.ndim > 1 else np.atleast_1d(ind)
for ind in int_inds])
Expand All @@ -283,7 +284,7 @@ def sample(cls, dataset, samples=[]):
Samples the gridded data into dataset of samples.
"""
ndims = dataset.ndims
dimensions = dataset.dimensions(label=True)
dimensions = dataset.dimensions(label='name')
arrays = [dataset.data[vdim.name] for vdim in dataset.vdims]
data = defaultdict(list)

Expand Down Expand Up @@ -320,7 +321,7 @@ def aggregate(cls, dataset, kdims, function, **kwargs):
for kdim in dataset.kdims if kdim not in kdims)
for vdim in dataset.vdims:
data[vdim.name] = np.atleast_1d(function(dataset.data[vdim.name],
axis=axes, **kwargs))
axis=axes, **kwargs))

return data

Expand Down
2 changes: 1 addition & 1 deletion holoviews/core/data/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def initialize(cls, eltype, data, kdims, vdims, datatype=None):

@classmethod
def validate(cls, dataset):
not_found = [d for d in dataset.dimensions(label=True)
not_found = [d for d in dataset.dimensions(label='name')
if d not in dataset.data]
if not_found:
raise ValueError("Supplied data does not contain specified "
Expand Down
Loading

0 comments on commit bfdad59

Please sign in to comment.