Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ref paths #342

Closed
wants to merge 17 commits into from
8 changes: 8 additions & 0 deletions anndata/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from ._core.anndata import AnnData, ImplicitModificationWarning
from ._core.raw import Raw
from ._core.ref_path import RefPath
from ._io import (
read_h5ad,
read_loom,
Expand Down Expand Up @@ -71,6 +72,13 @@
AnnData.write_loom
AnnData.write_zarr

Helper classes
--------------

.. autosummary::
:toctree: .

RefPath

Errors and warnings
-------------------
Expand Down
5 changes: 5 additions & 0 deletions anndata/_core/aligned_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,11 @@ def __init__(
if vals is not None:
self.update(vals)

def __setitem__(self, key: str, value: V):
if hasattr(value, "index") and isinstance(value.index, pd.RangeIndex):
value.index = self.dim_names
super().__setitem__(key, value)


class AxisArraysView(AlignedViewMixin, AxisArraysBase):
def __init__(
Expand Down
27 changes: 23 additions & 4 deletions anndata/_core/anndata.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
_resolve_idxs,
)
from .sparse_dataset import SparseDataset
from . import ref_path
from .. import utils
from ..utils import convert_to_dict, ensure_df_homogeneous
from ..logging import anndata_logger as logger
Expand Down Expand Up @@ -275,8 +276,18 @@ def __init__(
obs: Optional[Union[pd.DataFrame, Mapping[str, Iterable[Any]]]] = None,
var: Optional[Union[pd.DataFrame, Mapping[str, Iterable[Any]]]] = None,
uns: Optional[Mapping[str, Any]] = None,
obsm: Optional[Union[np.ndarray, Mapping[str, Sequence[Any]]]] = None,
varm: Optional[Union[np.ndarray, Mapping[str, Sequence[Any]]]] = None,
obsm: Optional[
Union[
np.ndarray,
Mapping[str, Union[np.ndarray, sparse.spmatrix, pd.DataFrame]],
]
] = None,
varm: Optional[
Union[
np.ndarray,
Mapping[str, Union[np.ndarray, sparse.spmatrix, pd.DataFrame]],
]
] = None,
layers: Optional[Mapping[str, Union[np.ndarray, sparse.spmatrix]]] = None,
raw: Optional[Mapping[str, Any]] = None,
dtype: Union[np.dtype, str] = "float32",
Expand All @@ -285,8 +296,12 @@ def __init__(
filemode: Optional[Literal["r", "r+"]] = None,
asview: bool = False,
*,
obsp: Optional[Union[np.ndarray, Mapping[str, Sequence[Any]]]] = None,
varp: Optional[Union[np.ndarray, Mapping[str, Sequence[Any]]]] = None,
obsp: Optional[
Union[np.ndarray, Mapping[str, Union[np.ndarray, sparse.spmatrix]]]
] = None,
varp: Optional[
Union[np.ndarray, Mapping[str, Union[np.ndarray, sparse.spmatrix]]]
] = None,
oidx: Index1D = None,
vidx: Index1D = None,
):
Expand Down Expand Up @@ -1334,6 +1349,10 @@ def _get_X(self, use_raw=False, layer=None):
else:
return self.X

resolve_path = ref_path.resolve_path
get_df = ref_path.get_df
get_vector = ref_path.get_vector

def obs_vector(self, k: str, *, layer: Optional[str] = None) -> np.ndarray:
"""\
Convenience function for returning a 1 dimensional ndarray of values
Expand Down
26 changes: 18 additions & 8 deletions anndata/_core/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import pandas as pd
from scipy.sparse import spmatrix, issparse

from ..compat import Literal
from . import anndata


Index1D = Union[slice, int, str, np.int64, np.ndarray]
Index = Union[Index1D, Tuple[Index1D, Index1D], spmatrix]
Expand Down Expand Up @@ -138,9 +141,14 @@ def make_slice(idx, dimidx, n=2):
return tuple(mut)


def get_vector(adata, k, coldim, idxdim, layer=None):
def get_vector(
adata: "anndata.AnnData",
k: str,
coldim: Literal["obs", "var"],
idxdim: Literal["obs", "var"],
layer: Optional[str] = None,
Copy link
Member

@falexwolf falexwolf Mar 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about adding an axis=None param that defaults to 0 for obsp and to ? for obsm?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To resolve the ambiguity of indexing into obsp (defaulting to rows), and potentially allows indexing into rows of obsm (where it defaults to columns).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To what for obsm?

):
# adata could be self if Raw and AnnData shared a parent
dims = ("obs", "var")
col = getattr(adata, coldim).columns
idx = getattr(adata, f"{idxdim}_names")

Expand All @@ -158,9 +166,11 @@ def get_vector(adata, k, coldim, idxdim, layer=None):
elif in_col:
return getattr(adata, coldim)[k].values
elif in_idx:
selected_dim = dims.index(idxdim)
idx = adata._normalize_indices(make_slice(k, selected_dim))
a = adata._get_X(layer=layer)[idx]
if issparse(a):
a = a.toarray()
return np.ravel(a)
return get_x_vector(adata, idxdim, k, layer)


def get_x_vector(adata, idxdim: Literal["obs", "var"], k: str, layer: str = None):
selected_dim = ("obs", "var").index(idxdim)
idx = adata._normalize_indices(make_slice(k, selected_dim))
a = adata._get_X(layer=layer)[idx]
return np.ravel(a.toarray() if issparse(a) else a)
4 changes: 4 additions & 0 deletions anndata/_core/raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ def var_names(self):
def obs_names(self):
return self._adata.obs_names

@property
def layers(self):
return {None: self.X}

def __getitem__(self, index):
oidx, vidx = self._normalize_indices(index)

Expand Down
Loading