cap-anndata 0.3.0__py3-none-any.whl → 0.4.0__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_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