cap-anndata 0.3.0__py3-none-any.whl → 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cap_anndata/__init__.py CHANGED
@@ -1,10 +1,10 @@
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"]
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,81 @@
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
+
5
+ from pandas._typing import Self
6
+ from pandas.core.generic import bool_t
7
+
8
+
9
+ class CapAnnDataDF(pd.DataFrame):
10
+ """
11
+ The class to expand the pandas DataFrame behaviour to support partial
12
+ reading and writing of AnnData obs and var (raw.var) fields.
13
+ The main feature of the class is handling <column-order> attribute
14
+ which must be a copy of h5py.Group attribute
15
+ """
16
+
17
+ _metadata = ["column_order"]
18
+
19
+ def column_order_array(self) -> np.array:
20
+ order = self.column_order
21
+ if order is not None and isinstance(order, List):
22
+ # Convert it to numpy array of str elements
23
+ return np.array(order, dtype=object)
24
+ else:
25
+ return order
26
+
27
+ def rename_column(self, old_name: str, new_name: str) -> None:
28
+ i = np.where(self.column_order_array() == old_name)[0]
29
+ tmp_array = self.column_order_array().copy()
30
+ tmp_array[i] = new_name
31
+ self.column_order = tmp_array.copy()
32
+ self.rename(columns={old_name: new_name}, inplace=True)
33
+
34
+ def remove_column(self, col_name: str) -> None:
35
+ i = np.where(self.column_order_array() == col_name)[0]
36
+ self.column_order = np.delete(self.column_order_array(), i)
37
+ self.drop(columns=[col_name], inplace=True)
38
+
39
+ def __setitem__(self, key, value) -> None:
40
+ if key not in self.column_order_array():
41
+ self.column_order = np.append(self.column_order_array(), key)
42
+ return super().__setitem__(key, value)
43
+
44
+ @classmethod
45
+ def from_df(cls, df: pd.DataFrame, column_order: Union[np.array, List[str], None] = None) -> Self:
46
+ if column_order is None:
47
+ column_order = df.columns.to_numpy()
48
+ elif isinstance(column_order, List):
49
+ column_order = np.array(column_order)
50
+ new_inst = cls(df)
51
+ new_inst.column_order = column_order
52
+ return new_inst
53
+
54
+ def join(self, other: Any, **kwargs) -> Self:
55
+ result = super().join(other=other, **kwargs)
56
+ if isinstance(other, CapAnnDataDF):
57
+ new_columns = [
58
+ col for col in other.column_order_array() if col not in self.column_order_array()
59
+ ]
60
+ else:
61
+ new_columns = [col for col in other.columns if col not in self.column_order_array()]
62
+ column_order = np.append(self.column_order_array(), new_columns)
63
+ df = self.from_df(result, column_order=column_order)
64
+ return df
65
+
66
+ def merge(self, right, **kwargs) -> Self:
67
+ result = super().merge(right=right, **kwargs)
68
+ if isinstance(right, CapAnnDataDF):
69
+ new_columns = [
70
+ col for col in right.column_order_array() if col not in self.column_order_array()
71
+ ]
72
+ else:
73
+ new_columns = [col for col in right.columns if col not in self.column_order_array()]
74
+ column_order = np.append(self.column_order_array(), new_columns)
75
+ df = self.from_df(result, column_order=column_order)
76
+ return df
77
+
78
+ def copy(self, deep: Union[bool_t, None] = True) -> Self:
79
+ column_order = self.column_order_array()
80
+ df = self.from_df(super().copy(deep=deep), column_order=column_order)
81
+ return df
@@ -1,34 +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
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