Skip to content

Commit c53320f

Browse files
committed
Always use index selection if available
1 parent 7b83b10 commit c53320f

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

holoviews/core/data/pandas.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -351,22 +351,32 @@ def sort(cls, dataset, by=None, reverse=False):
351351
return dataset.data.sort(columns=cols, ascending=not reverse)
352352
return dataset.data.sort_values(by=cols, ascending=not reverse)
353353

354+
@classmethod
355+
def index_selection(cls, df, selection):
356+
index_sel = {}
357+
skip_index = True
358+
for idx in cls.indexes(df):
359+
if idx not in selection:
360+
index_sel[idx] = slice(None, None)
361+
continue
362+
skip_index = False
363+
sel = selection[idx]
364+
if isinstance(sel, tuple) and len(sel) < 4:
365+
sel = slice(*sel)
366+
elif not isinstance(sel, (list, slice)):
367+
sel = [sel]
368+
index_sel[idx] = sel
369+
return {} if skip_index else index_sel
354370

355371
@classmethod
356372
def select(cls, dataset, selection_mask=None, **selection):
357373
df = dataset.data
358374
if selection_mask is None:
359-
indexes = {
360-
idx: v
361-
for idx in cls.indexes(df)
362-
if isinstance((v := selection.get(idx)), slice) or
363-
isinstance(v, tuple) and len(v) < 4 and (v := slice(*v))
364-
} if not isinstance(df.index, pd.MultiIndex) else {}
365-
if selection.keys() - indexes.keys():
366-
selection_mask = cls.select_mask(dataset, selection)
367-
else:
368-
for v in indexes.values():
369-
df = df[v]
375+
if index_sel:= cls.index_selection(df, selection):
376+
df = df.loc[tuple(index_sel.values()), :]
377+
column_sel = {k: v for k, v in selection.items() if k not in index_sel}
378+
if column_sel:
379+
selection_mask = cls.select_mask(dataset, column_sel)
370380

371381
indexed = cls.indexed(dataset, selection)
372382
if isinstance(selection_mask, pd.Series):

holoviews/tests/core/data/test_pandasinterface.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,25 @@ def test_index_select(self):
229229
assert isinstance(selected.data.index, pd.MultiIndex)
230230
pd.testing.assert_frame_equal(selected.data, expected)
231231

232+
def test_index_select_all_indexes(self):
233+
ds = Dataset(self.df, kdims=["number", "color"])
234+
selected = ds.select(number=1, color='red')
235+
assert selected == 0
236+
237+
def test_index_select_all_indexes_lists(self):
238+
ds = Dataset(self.df, kdims=["number", "color"])
239+
selected = ds.select(number=[1], color=['red'])
240+
expected = pd.DataFrame({'color': ['red'], 'values': [0], 'number': [1]}).set_index(['number', 'color'])
241+
assert isinstance(selected.data.index, pd.MultiIndex)
242+
pd.testing.assert_frame_equal(selected.data, expected)
243+
244+
def test_index_select_all_indexes_slice_and_scalar(self):
245+
ds = Dataset(self.df, kdims=["number", "color"])
246+
selected = ds.select(number=(0, 1), color='red')
247+
expected = pd.DataFrame({'color': ['red'], 'values': [0], 'number': [1]}).set_index(['number', 'color'])
248+
assert isinstance(selected.data.index, pd.MultiIndex)
249+
pd.testing.assert_frame_equal(selected.data, expected)
250+
232251
def test_iloc_scalar_scalar_only_index(self):
233252
ds = Dataset(self.df, kdims=["number", "color"])
234253
selected = ds.iloc[0, 0]

0 commit comments

Comments
 (0)