cap-anndata 0.2.2__py3-none-any.whl → 0.3.1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
cap_anndata/__init__.py CHANGED
@@ -1,10 +1,10 @@
1
- from .backed_df import CapAnnDataDF
2
- from .backed_uns import CapAnnDataUns
3
- from .cap_anndata import CapAnnData
4
- from .reader import (
5
- read_directly,
6
- read_h5ad,
7
- )
8
-
9
-
10
- __all__ = ["CapAnnData"]
1
+ from .backed_df import CapAnnDataDF
2
+ from .backed_dict import CapAnnDataDict
3
+ from .cap_anndata import CapAnnData
4
+ from .reader import (
5
+ read_directly,
6
+ read_h5ad,
7
+ )
8
+
9
+
10
+ __all__ = ["CapAnnData"]
cap_anndata/backed_df.py CHANGED
@@ -1,69 +1,69 @@
1
- import pandas as pd
2
- import numpy as np
3
- from typing import List, Any, Union
4
- import logging
5
-
6
- from pandas._typing import Self
7
- from pandas.core.generic import bool_t
8
-
9
- logger = logging.getLogger(__name__)
10
-
11
-
12
- class CapAnnDataDF(pd.DataFrame):
13
- """
14
- The class to expand the pandas DataFrame behaviour to support partial
15
- reading and writing of AnnData obs and var (raw.var) fields.
16
- The main feature of the class is handling <column-order> attribute
17
- which must be a copy of h5py.Group attribute
18
- """
19
-
20
- _metadata = ["column_order"]
21
-
22
- def rename_column(self, old_name: str, new_name: str) -> None:
23
- i = np.where(self.column_order == old_name)[0]
24
- self.column_order[i] = new_name
25
- self.rename(columns={old_name: new_name}, inplace=True)
26
-
27
- def remove_column(self, col_name: str) -> None:
28
- i = np.where(self.column_order == col_name)[0]
29
- self.column_order = np.delete(self.column_order, i)
30
- self.drop(columns=[col_name], inplace=True)
31
-
32
- def __setitem__(self, key, value) -> None:
33
- if key not in self.column_order:
34
- self.column_order = np.append(self.column_order, key)
35
- return super().__setitem__(key, value)
36
-
37
- @classmethod
38
- def from_df(cls, df: pd.DataFrame, column_order: List[str] = None) -> Self:
39
- if column_order is None:
40
- column_order = df.columns.to_numpy()
41
-
42
- new_inst = cls(df)
43
- new_inst.column_order = column_order
44
- return new_inst
45
-
46
- def join(self, other: Any, **kwargs) -> Self:
47
- result = super().join(other=other, **kwargs)
48
- if isinstance(other, CapAnnDataDF):
49
- new_columns = [
50
- col for col in other.column_order if col not in self.column_order
51
- ]
52
- else:
53
- new_columns = [col for col in other.columns if col not in self.column_order]
54
- column_order = np.append(self.column_order, new_columns)
55
- return self.from_df(result, column_order=column_order)
56
-
57
- def merge(self, right, **kwargs) -> Self:
58
- result = super().merge(right=right, **kwargs)
59
- if isinstance(right, CapAnnDataDF):
60
- new_columns = [
61
- col for col in right.column_order if col not in self.column_order
62
- ]
63
- else:
64
- new_columns = [col for col in right.columns if col not in self.column_order]
65
- column_order = np.append(self.column_order, new_columns)
66
- return self.from_df(result, column_order=column_order)
67
-
68
- def copy(self, deep: Union[bool_t, None] = True) -> Self:
69
- return self.from_df(super().copy(deep=deep), column_order=self.column_order)
1
+ import pandas as pd
2
+ import numpy as np
3
+ from typing import List, Any, Union
4
+ import logging
5
+
6
+ from pandas._typing import Self
7
+ from pandas.core.generic import bool_t
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ class CapAnnDataDF(pd.DataFrame):
13
+ """
14
+ The class to expand the pandas DataFrame behaviour to support partial
15
+ reading and writing of AnnData obs and var (raw.var) fields.
16
+ The main feature of the class is handling <column-order> attribute
17
+ which must be a copy of h5py.Group attribute
18
+ """
19
+
20
+ _metadata = ["column_order"]
21
+
22
+ def rename_column(self, old_name: str, new_name: str) -> None:
23
+ i = np.where(self.column_order == old_name)[0]
24
+ self.column_order[i] = new_name
25
+ self.rename(columns={old_name: new_name}, inplace=True)
26
+
27
+ def remove_column(self, col_name: str) -> None:
28
+ i = np.where(self.column_order == col_name)[0]
29
+ self.column_order = np.delete(self.column_order, i)
30
+ self.drop(columns=[col_name], inplace=True)
31
+
32
+ def __setitem__(self, key, value) -> None:
33
+ if key not in self.column_order:
34
+ self.column_order = np.append(self.column_order, key)
35
+ return super().__setitem__(key, value)
36
+
37
+ @classmethod
38
+ def from_df(cls, df: pd.DataFrame, column_order: List[str] = None) -> Self:
39
+ if column_order is None:
40
+ column_order = df.columns.to_numpy()
41
+
42
+ new_inst = cls(df)
43
+ new_inst.column_order = column_order
44
+ return new_inst
45
+
46
+ def join(self, other: Any, **kwargs) -> Self:
47
+ result = super().join(other=other, **kwargs)
48
+ if isinstance(other, CapAnnDataDF):
49
+ new_columns = [
50
+ col for col in other.column_order if col not in self.column_order
51
+ ]
52
+ else:
53
+ new_columns = [col for col in other.columns if col not in self.column_order]
54
+ column_order = np.append(self.column_order, new_columns)
55
+ return self.from_df(result, column_order=column_order)
56
+
57
+ def merge(self, right, **kwargs) -> Self:
58
+ result = super().merge(right=right, **kwargs)
59
+ if isinstance(right, CapAnnDataDF):
60
+ new_columns = [
61
+ col for col in right.column_order if col not in self.column_order
62
+ ]
63
+ else:
64
+ new_columns = [col for col in right.columns if col not in self.column_order]
65
+ column_order = np.append(self.column_order, new_columns)
66
+ return self.from_df(result, column_order=column_order)
67
+
68
+ def copy(self, deep: Union[bool_t, None] = True) -> Self:
69
+ return self.from_df(super().copy(deep=deep), column_order=self.column_order)
@@ -0,0 +1,34 @@
1
+ from typing import Set, Any
2
+
3
+
4
+ class CapAnnDataDict(dict):
5
+ __keys_to_remove: Set[str] = None
6
+
7
+ def __delitem__(self, __key: Any) -> None:
8
+ self.keys_to_remove.add(__key)
9
+ return super().__delitem__(__key)
10
+
11
+ def __setitem__(self, __key: Any, __value: Any) -> None:
12
+ if __value is not None:
13
+ if __key in self.keys_to_remove:
14
+ self.keys_to_remove.remove(__key)
15
+ else:
16
+ self.keys_to_remove.add(__key)
17
+ return super().__setitem__(__key, __value)
18
+
19
+ @property
20
+ def keys_to_remove(self) -> Set[str]:
21
+ if self.__keys_to_remove is None:
22
+ self.__keys_to_remove = set()
23
+ return self.__keys_to_remove
24
+
25
+ def pop(self, __key: Any, __default: Any = None) -> Any:
26
+ if __key in self:
27
+ self.keys_to_remove.add(__key)
28
+ return super().pop(__key, __default)
29
+
30
+ def popitem(self) -> Any:
31
+ item = super().popitem()
32
+ key = item[0]
33
+ self.keys_to_remove.add(key)
34
+ return item