From 142e6d02deeb14e5c71a7ae7d7dcced8cf73da97 Mon Sep 17 00:00:00 2001 From: Philipp A Date: Mon, 23 Dec 2019 17:20:02 +0100 Subject: [PATCH] Deprecate square matrix slicing in .uns --- anndata/_core/anndata.py | 15 +++++++++++++-- anndata/tests/test_base.py | 5 ++++- docs/release_notes.rst | 1 + 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/anndata/_core/anndata.py b/anndata/_core/anndata.py index 44bd077ba..ee3f6b166 100644 --- a/anndata/_core/anndata.py +++ b/anndata/_core/anndata.py @@ -1097,7 +1097,10 @@ def strings_to_categoricals(self, df: Optional[pd.DataFrame] = None): _sanitize = strings_to_categoricals # backwards compat - def _slice_uns_sparse_matrices_inplace(self, uns: MutableMapping, oidx: Index1D): + def _slice_uns_sparse_matrices_inplace( + self, uns: MutableMapping, oidx: Index1D, keys: Tuple[str, ...] = () + ): + # TODO: remove # slice sparse spatrices of n_obs × n_obs in self.uns if not ( isinstance(oidx, slice) @@ -1108,11 +1111,19 @@ def _slice_uns_sparse_matrices_inplace(self, uns: MutableMapping, oidx: Index1D) for k, v in uns.items(): # treat nested dicts if isinstance(v, Mapping): - self._slice_uns_sparse_matrices_inplace(v, oidx) + self._slice_uns_sparse_matrices_inplace(v, oidx, (*keys, k)) if isinstance(v, sparse.spmatrix) and v.shape == ( self.n_obs, self.n_obs, ): + path = "".join(f"['{key}']" for key in (*keys, k)) + warnings.warn( + f"During AnnData slicing, found matrix at .obs{path} " + "that happens to be dimensioned at n_obs×n_obs " + f"({self.n_obs}×{self.n_obs}). " + "This slicing behavior will soon go away.", + DeprecationWarning, + ) uns[k] = v.tocsc()[:, oidx].tocsr()[oidx, :] def _inplace_subset_var(self, index: Index1D): diff --git a/anndata/tests/test_base.py b/anndata/tests/test_base.py index b01d74907..fcdd8396f 100644 --- a/anndata/tests/test_base.py +++ b/anndata/tests/test_base.py @@ -235,7 +235,10 @@ def test_slicing_graphs(): np.array([[1, 2], [3, 4], [5, 6]]), uns=dict(neighbors=dict(connectivities=sp.csr_matrix(np.ones((3, 3))))), ) - adata_sub = adata[[0, 1], :] + with pytest.warns( + DeprecationWarning, match=r".obs\['neighbors'\]\['connectivities'\] .*(3×3)" + ): + adata_sub = adata[[0, 1], :] assert adata_sub.uns["neighbors"]["connectivities"].shape[0] == 2 assert adata.uns["neighbors"]["connectivities"].shape[0] == 3 assert adata_sub.copy().uns["neighbors"]["connectivities"].shape[0] == 2 diff --git a/docs/release_notes.rst b/docs/release_notes.rst index 4e64c6d81..91dd9aaa1 100644 --- a/docs/release_notes.rst +++ b/docs/release_notes.rst @@ -10,6 +10,7 @@ - :attr:`~anndata.AnnData.filename` and :attr:`~anndata.AnnData.isbacked` will be unified under a new name. - The types of :attr:`~anndata.AnnData.raw`, :attr:`~anndata.AnnData.layers`, :attr:`~anndata.AnnData.obsm`, :attr:`~anndata.AnnData.varm`, :attr:`~anndata.AnnData.obsp` and :attr:`~anndata.AnnData.varp` will be exported. + - Square matrices in :attr:`~anndata.AnnData.uns` will no longer be sliced (use `.{obs,var}p` instead). 0.7rc1 :small:`December 23, 2019`