Skip to content

Commit 8e0fcc2

Browse files
authored
Fix slicing when subset args are numpy vectors (#55)
1 parent ef95a64 commit 8e0fcc2

File tree

4 files changed

+38
-12
lines changed

4 files changed

+38
-12
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# Changelog
22

3-
## Version 0.5.1 - 0.5.2
3+
## Version 0.5.1 - 0.5.3
44

55
- Add wrapper class methods to combine experiments by rows or columns.
66
- Expand function names for readability, still backwards compatible with the older function and method names.
77
- Add getters and setters to replace a specific alternative experiment or reduced dimension.
8+
- Fixed an issue with numpy arrays as slice arguments. Code now uses Biocutils's subset functions to perform these operations.
9+
810

911
## Version 0.5.0
1012

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ python_requires = >=3.9
4949
# For more information, check out https://semver.org/.
5050
install_requires =
5151
importlib-metadata; python_version<"3.8"
52-
summarizedexperiment>=0.5.1
52+
summarizedexperiment>=0.5.3
5353

5454
[options.packages.find]
5555
where = src

src/singlecellexperiment/SingleCellExperiment.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -980,41 +980,40 @@ def get_slice(
980980
rows: Optional[Union[str, int, bool, Sequence]],
981981
columns: Optional[Union[str, int, bool, Sequence]],
982982
) -> "SingleCellExperiment":
983-
"""Alias for :py:attr:`~__getitem__`, for back-compatibility."""
983+
"""Alias for :py:attr:`~__getitem__`."""
984984

985985
slicer = self._generic_slice(rows=rows, columns=columns)
986+
do_slice_rows = not (isinstance(slicer.row_indices, slice) and slicer.row_indices == slice(None))
987+
do_slice_cols = not (isinstance(slicer.col_indices, slice) and slicer.col_indices == slice(None))
986988

987989
new_row_ranges = None
988-
if slicer.row_indices != slice(None):
990+
if do_slice_rows:
989991
new_row_ranges = self._row_ranges[slicer.row_indices]
990992

991993
new_reduced_dims = {}
992994
for rdim, rmat in self._reduced_dims.items():
993-
if slicer.col_indices != slice(None):
995+
if do_slice_cols:
994996
rmat = rmat[slicer.col_indices, :]
995997

996998
new_reduced_dims[rdim] = rmat
997999

9981000
new_alt_expts = {}
9991001
for altname, altexpt in self._alternative_experiments.items():
1000-
if slicer.row_indices != slice(None):
1001-
altexpt = altexpt[slicer.row_indices, :]
1002-
1003-
if slicer.col_indices != slice(None):
1002+
if do_slice_cols:
10041003
altexpt = altexpt[:, slicer.col_indices]
10051004

10061005
new_alt_expts[altname] = altexpt
10071006

10081007
new_row_pairs = {}
10091008
for rname, rpair in self._row_pairs.items():
1010-
if slicer.row_indices != slice(None):
1009+
if do_slice_rows:
10111010
rpair = rpair[slicer.row_indices, :]
10121011

10131012
new_row_pairs[rname] = rpair
10141013

10151014
new_col_pairs = {}
10161015
for cname, cpair in self._column_pairs.items():
1017-
if slicer.col_indices != slice(None):
1016+
if do_slice_cols:
10181017
cpair = cpair[:, slicer.col_indices]
10191018

10201019
new_col_pairs[cname] = cpair

tests/test_sce_slice.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,31 @@ def test_SCE_slice():
6666

6767
assert tse_slice.assay("counts").shape == (10, 3)
6868

69+
def test_SCE_slice_with_numpy():
70+
tse = SingleCellExperiment(
71+
assays={"counts": counts},
72+
row_data=row_data,
73+
column_data=col_data,
74+
reduced_dims={"random_embeds": np.random.rand(ncols, 5)},
75+
)
76+
77+
tse_slice = tse[np.arange(10), 0:3]
78+
assert tse_slice is not None
79+
assert isinstance(tse_slice, sce)
80+
81+
assert len(tse_slice.row_data) == 10
82+
assert len(tse_slice.col_data) == 3
83+
84+
assert tse_slice.assay("counts").shape == (10, 3)
85+
86+
tse_slice = tse[np.arange(10), np.arange(3)]
87+
assert tse_slice is not None
88+
assert isinstance(tse_slice, sce)
89+
90+
assert len(tse_slice.row_data) == 10
91+
assert len(tse_slice.col_data) == 3
92+
93+
assert tse_slice.assay("counts").shape == (10, 3)
6994

7095
def test_SCE_creation_with_alts_slice():
7196
trse = SummarizedExperiment(
@@ -91,4 +116,4 @@ def test_SCE_creation_with_alts_slice():
91116

92117
assert tsce_slice.assay("counts").shape == (10, 3)
93118
alt_exp = tsce_slice.alternative_experiments["alt"]
94-
assert alt_exp.shape == (10, 3)
119+
assert alt_exp.shape == (200, 3)

0 commit comments

Comments
 (0)