biocutils 0.3.2.dev1__tar.gz → 0.3.3__tar.gz
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.
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/CHANGELOG.md +9 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/PKG-INFO +1 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/setup.py +1 -0
- biocutils-0.3.2.dev1/src/biocutils/boolean_list.py → biocutils-0.3.3/src/biocutils/BooleanList.py +24 -27
- biocutils-0.3.2.dev1/src/biocutils/factor.py → biocutils-0.3.3/src/biocutils/Factor.py +100 -83
- biocutils-0.3.2.dev1/src/biocutils/float_list.py → biocutils-0.3.3/src/biocutils/FloatList.py +13 -18
- biocutils-0.3.2.dev1/src/biocutils/integer_list.py → biocutils-0.3.3/src/biocutils/IntegerList.py +16 -20
- biocutils-0.3.2.dev1/src/biocutils/named_list.py → biocutils-0.3.3/src/biocutils/NamedList.py +142 -48
- biocutils-0.3.2.dev1/src/biocutils/names.py → biocutils-0.3.3/src/biocutils/Names.py +74 -20
- biocutils-0.3.2.dev1/src/biocutils/string_list.py → biocutils-0.3.3/src/biocutils/StringList.py +11 -17
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/__init__.py +10 -7
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/_utils_combine.py +2 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/assign.py +2 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/assign_rows.py +3 -3
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/assign_sequence.py +2 -6
- biocutils-0.3.2.dev1/src/biocutils/bioc_object.py → biocutils-0.3.3/src/biocutils/biocobject.py +6 -11
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/combine.py +5 -5
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/combine_columns.py +9 -8
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/combine_rows.py +4 -6
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/combine_sequences.py +5 -6
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/convert_to_dense.py +2 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/extract_column_names.py +4 -3
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/extract_row_names.py +2 -2
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/is_high_dimensional.py +2 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/is_list_of_type.py +7 -4
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/is_missing_scalar.py +2 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/map_to_index.py +2 -3
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/match.py +4 -3
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/normalize_subscript.py +7 -17
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/package_utils.py +2 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/print_truncated.py +6 -13
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/print_wrapped_table.py +1 -3
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/relaxed_combine_columns.py +1 -5
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/relaxed_combine_rows.py +1 -3
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/reverse_index.py +2 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/show_as_cell.py +2 -2
- biocutils-0.3.3/src/biocutils/table.py +38 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/which.py +2 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils.egg-info/PKG-INFO +1 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils.egg-info/SOURCES.txt +9 -8
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_BooleanList.py +2 -2
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_Factor.py +55 -4
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_FloatList.py +1 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_IntegerList.py +1 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_NamedList.py +75 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_Names.py +62 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_StringList.py +2 -2
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_biocobject.py +15 -15
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_combine_sequences.py +1 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_factorize.py +1 -1
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/.coveragerc +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/.github/workflows/publish-pypi.yml +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/.github/workflows/run-tests.yml +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/.gitignore +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/.pre-commit-config.yaml +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/.readthedocs.yml +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/AUTHORS.md +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/CONTRIBUTING.md +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/LICENSE.txt +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/README.md +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/docs/Makefile +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/docs/_static/.gitignore +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/docs/authors.md +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/docs/changelog.md +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/docs/conf.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/docs/contributing.md +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/docs/index.md +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/docs/license.md +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/docs/readme.md +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/docs/requirements.txt +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/pyproject.toml +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/setup.cfg +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/factorize.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/get_height.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/intersect.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/subset.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/subset_rows.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/subset_sequence.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils/union.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils.egg-info/dependency_links.txt +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils.egg-info/not-zip-safe +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils.egg-info/requires.txt +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/src/biocutils.egg-info/top_level.txt +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/conftest.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_assign.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_assign_rows.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_assign_sequence.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_combine.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_combine_columns.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_combine_rows.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_extract_column_names.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_extract_row_names.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_get_height.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_intersect.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_is_high_dimensional.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_list_type_checks.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_map_to_index.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_match.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_normalize_subscript.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_package_utils.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_print_truncated.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_print_wrapped_table.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_show_as_cell.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_subset.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_subset_rows.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_subset_sequence.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_union.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tests/test_which.py +0 -0
- {biocutils-0.3.2.dev1 → biocutils-0.3.3}/tox.ini +0 -0
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## Version 0.3.0
|
|
3
|
+
## Version 0.3.0 - 0.3.2
|
|
4
4
|
|
|
5
5
|
- Provide a base `BiocObject` class similar to the `Annotated` class in Bioconductor. The class provides `metadata` slot, accessors and validation functions.
|
|
6
|
+
- Renaming code files to follow pep guidelines
|
|
7
|
+
- Update Github actions and workflow to the new biocsetup versions
|
|
8
|
+
- Changes to improve `NamedList`, `Names` classes
|
|
9
|
+
- get name at index
|
|
10
|
+
- delete method for namedlist/names
|
|
11
|
+
- add is_unique
|
|
12
|
+
- add lint errors
|
|
13
|
+
- linting documentation, typehints etc
|
|
6
14
|
|
|
7
15
|
## Version 0.2.3
|
|
8
16
|
|
biocutils-0.3.2.dev1/src/biocutils/boolean_list.py → biocutils-0.3.3/src/biocutils/BooleanList.py
RENAMED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from typing import Any, Iterable, Optional, Sequence, Union
|
|
2
4
|
|
|
3
|
-
from .
|
|
4
|
-
from .
|
|
5
|
+
from .NamedList import NamedList
|
|
6
|
+
from .Names import Names
|
|
5
7
|
from .normalize_subscript import SubscriptTypes
|
|
6
8
|
|
|
7
9
|
|
|
@@ -16,7 +18,8 @@ class _SubscriptCoercer:
|
|
|
16
18
|
"""Initialize the coercer.
|
|
17
19
|
|
|
18
20
|
Args:
|
|
19
|
-
data:
|
|
21
|
+
data:
|
|
22
|
+
Sequence of values to coerce.
|
|
20
23
|
"""
|
|
21
24
|
self._data = data
|
|
22
25
|
|
|
@@ -24,7 +27,8 @@ class _SubscriptCoercer:
|
|
|
24
27
|
"""Get an item and coerce it to boolean.
|
|
25
28
|
|
|
26
29
|
Args:
|
|
27
|
-
index:
|
|
30
|
+
index:
|
|
31
|
+
Index of the item.
|
|
28
32
|
|
|
29
33
|
Returns:
|
|
30
34
|
Coerced boolean value.
|
|
@@ -42,7 +46,7 @@ class BooleanList(NamedList):
|
|
|
42
46
|
|
|
43
47
|
def __init__(
|
|
44
48
|
self,
|
|
45
|
-
data: Optional[
|
|
49
|
+
data: Optional[Sequence] = None,
|
|
46
50
|
names: Optional[Names] = None,
|
|
47
51
|
_validate: bool = True,
|
|
48
52
|
):
|
|
@@ -60,41 +64,34 @@ class BooleanList(NamedList):
|
|
|
60
64
|
_validate:
|
|
61
65
|
Internal use only.
|
|
62
66
|
"""
|
|
63
|
-
if
|
|
64
|
-
if data
|
|
65
|
-
|
|
67
|
+
if data is not None:
|
|
68
|
+
if isinstance(data, BooleanList):
|
|
69
|
+
data = data._data
|
|
70
|
+
else:
|
|
71
|
+
if isinstance(data, NamedList):
|
|
66
72
|
data = data._data
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
data = list(_coerce_to_bool(item) for item in original)
|
|
73
|
+
|
|
74
|
+
original = data
|
|
75
|
+
data = list(_coerce_to_bool(item) for item in original)
|
|
76
|
+
|
|
72
77
|
super().__init__(data, names, _validate=_validate)
|
|
73
78
|
|
|
74
|
-
def set_value(
|
|
75
|
-
self, index: Union[int, str], value: Any, in_place: bool = False
|
|
76
|
-
) -> "BooleanList":
|
|
79
|
+
def set_value(self, index: Union[int, str], value: Any, in_place: bool = False) -> BooleanList:
|
|
77
80
|
"""Calls :py:meth:`~biocutils.NamedList.NamedList.set_value` after coercing ``value`` to a boolean."""
|
|
78
81
|
return super().set_value(index, _coerce_to_bool(value), in_place=in_place)
|
|
79
82
|
|
|
80
|
-
def set_slice(
|
|
81
|
-
self, index: SubscriptTypes, value: Sequence, in_place: bool = False
|
|
82
|
-
) -> "BooleanList":
|
|
83
|
+
def set_slice(self, index: SubscriptTypes, value: Sequence, in_place: bool = False) -> BooleanList:
|
|
83
84
|
"""Calls :py:meth:`~biocutils.NamedList.NamedList.set_slice` after coercing ``value`` to booleans."""
|
|
84
85
|
return super().set_slice(index, _SubscriptCoercer(value), in_place=in_place)
|
|
85
86
|
|
|
86
|
-
def safe_insert(
|
|
87
|
-
self, index: Union[int, str], value: Any, in_place: bool = False
|
|
88
|
-
) -> "BooleanList":
|
|
87
|
+
def safe_insert(self, index: Union[int, str], value: Any, in_place: bool = False) -> BooleanList:
|
|
89
88
|
"""Calls :py:meth:`~biocutils.NamedList.NamedList.safe_insert` after coercing ``value`` to a boolean."""
|
|
90
89
|
return super().safe_insert(index, _coerce_to_bool(value), in_place=in_place)
|
|
91
90
|
|
|
92
|
-
def safe_append(self, value: Any, in_place: bool = False) ->
|
|
91
|
+
def safe_append(self, value: Any, in_place: bool = False) -> BooleanList:
|
|
93
92
|
"""Calls :py:meth:`~biocutils.NamedList.NamedList.safe_append` after coercing ``value`` to a boolean."""
|
|
94
93
|
return super().safe_append(_coerce_to_bool(value), in_place=in_place)
|
|
95
94
|
|
|
96
|
-
def safe_extend(self, other: Iterable, in_place: bool =
|
|
95
|
+
def safe_extend(self, other: Iterable, in_place: bool = False) -> BooleanList:
|
|
97
96
|
"""Calls :py:meth:`~biocutils.NamedList.NamedList.safe_extend` after coercing elements of ``other`` to booleans."""
|
|
98
|
-
return super().safe_extend(
|
|
99
|
-
(_coerce_to_bool(y) for y in other), in_place=in_place
|
|
100
|
-
)
|
|
97
|
+
return super().safe_extend((_coerce_to_bool(y) for y in other), in_place=in_place)
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import warnings
|
|
1
4
|
from copy import copy, deepcopy
|
|
2
5
|
from typing import Optional, Sequence, Union
|
|
3
6
|
|
|
4
7
|
import numpy
|
|
5
|
-
import warnings
|
|
6
8
|
|
|
7
9
|
from .assign_sequence import assign_sequence
|
|
8
10
|
from .combine_sequences import combine_sequences
|
|
@@ -10,22 +12,20 @@ from .factorize import factorize
|
|
|
10
12
|
from .is_list_of_type import is_list_of_type
|
|
11
13
|
from .is_missing_scalar import is_missing_scalar
|
|
12
14
|
from .match import match
|
|
13
|
-
from .
|
|
15
|
+
from .Names import Names, _combine_names, _name_to_position, _sanitize_names
|
|
14
16
|
from .normalize_subscript import (
|
|
15
17
|
NormalizedSubscript,
|
|
16
18
|
SubscriptTypes,
|
|
17
19
|
normalize_subscript,
|
|
18
20
|
)
|
|
19
21
|
from .print_truncated import print_truncated_list
|
|
20
|
-
from .
|
|
22
|
+
from .StringList import StringList
|
|
21
23
|
from .subset_sequence import subset_sequence
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
def _sanitize_codes(codes: Sequence[int], num_levels: int) -> numpy.ndarray:
|
|
25
27
|
if not isinstance(codes, numpy.ndarray):
|
|
26
|
-
replacement = numpy.ndarray(
|
|
27
|
-
len(codes), dtype=numpy.min_scalar_type(-num_levels)
|
|
28
|
-
) # get a signed type.
|
|
28
|
+
replacement = numpy.ndarray(len(codes), dtype=numpy.min_scalar_type(-num_levels)) # get a signed type.
|
|
29
29
|
for i, x in enumerate(codes):
|
|
30
30
|
if is_missing_scalar(x) or x < 0:
|
|
31
31
|
replacement[i] = -1
|
|
@@ -35,16 +35,12 @@ def _sanitize_codes(codes: Sequence[int], num_levels: int) -> numpy.ndarray:
|
|
|
35
35
|
else:
|
|
36
36
|
if len(codes.shape) != 1:
|
|
37
37
|
raise ValueError("'codes' should be a 1-dimensional array")
|
|
38
|
-
if not numpy.issubdtype(
|
|
39
|
-
codes.dtype, numpy.signedinteger
|
|
40
|
-
): # force it to be signed.
|
|
38
|
+
if not numpy.issubdtype(codes.dtype, numpy.signedinteger): # force it to be signed.
|
|
41
39
|
codes = codes.astype(numpy.min_scalar_type(-num_levels))
|
|
42
40
|
|
|
43
41
|
for x in codes:
|
|
44
42
|
if x < -1 or x >= num_levels:
|
|
45
|
-
raise ValueError(
|
|
46
|
-
"all entries of 'codes' should refer to an entry of 'levels'"
|
|
47
|
-
)
|
|
43
|
+
raise ValueError("all entries of 'codes' should refer to an entry of 'levels'")
|
|
48
44
|
|
|
49
45
|
return codes
|
|
50
46
|
|
|
@@ -67,7 +63,7 @@ def _sanitize_levels(levels: Sequence[str], check: bool = True) -> StringList:
|
|
|
67
63
|
class FactorIterator:
|
|
68
64
|
"""Iterator for a :py:class:`~Factor` object."""
|
|
69
65
|
|
|
70
|
-
def __init__(self, parent:
|
|
66
|
+
def __init__(self, parent: Factor):
|
|
71
67
|
"""
|
|
72
68
|
Args:
|
|
73
69
|
parent: The parent :py:class:`~Factor` object.
|
|
@@ -75,7 +71,7 @@ class FactorIterator:
|
|
|
75
71
|
self._parent = parent
|
|
76
72
|
self._position = 0
|
|
77
73
|
|
|
78
|
-
def __iter__(self) ->
|
|
74
|
+
def __iter__(self) -> FactorIterator:
|
|
79
75
|
"""
|
|
80
76
|
Returns:
|
|
81
77
|
The iterator.
|
|
@@ -106,10 +102,10 @@ class Factor:
|
|
|
106
102
|
|
|
107
103
|
def __init__(
|
|
108
104
|
self,
|
|
109
|
-
codes: Sequence[int],
|
|
110
|
-
levels: Sequence[str],
|
|
105
|
+
codes: Union[numpy.ndarray, Sequence[int]],
|
|
106
|
+
levels: Union[StringList, Sequence[str]],
|
|
111
107
|
ordered: bool = False,
|
|
112
|
-
names: Optional[Names] = None,
|
|
108
|
+
names: Optional[Union[Names, Sequence[str]]] = None,
|
|
113
109
|
_validate: bool = True,
|
|
114
110
|
):
|
|
115
111
|
"""Initialize a Factor object.
|
|
@@ -149,7 +145,7 @@ class Factor:
|
|
|
149
145
|
#####>>>> Simple getters <<<<#####
|
|
150
146
|
##################################
|
|
151
147
|
|
|
152
|
-
def _define_output(self, in_place: bool) ->
|
|
148
|
+
def _define_output(self, in_place: bool) -> Factor:
|
|
153
149
|
if in_place:
|
|
154
150
|
return self
|
|
155
151
|
else:
|
|
@@ -171,7 +167,7 @@ class Factor:
|
|
|
171
167
|
"""Alias for :py:meth:`~get_codes`."""
|
|
172
168
|
return self.get_codes()
|
|
173
169
|
|
|
174
|
-
def set_codes(self, codes: Sequence[int], in_place: bool = False) ->
|
|
170
|
+
def set_codes(self, codes: Sequence[int], in_place: bool = False) -> Factor:
|
|
175
171
|
"""
|
|
176
172
|
Args:
|
|
177
173
|
codes:
|
|
@@ -187,9 +183,7 @@ class Factor:
|
|
|
187
183
|
"""
|
|
188
184
|
output = self._define_output(in_place)
|
|
189
185
|
if len(codes) != len(self):
|
|
190
|
-
raise ValueError(
|
|
191
|
-
"length of 'codes' should be equal to that of the current object"
|
|
192
|
-
)
|
|
186
|
+
raise ValueError("length of 'codes' should be equal to that of the current object")
|
|
193
187
|
output._codes = _sanitize_codes(codes, len(self._levels))
|
|
194
188
|
return output
|
|
195
189
|
|
|
@@ -220,7 +214,7 @@ class Factor:
|
|
|
220
214
|
"""Alias for :py:meth:`~get_ordered`."""
|
|
221
215
|
return self.get_ordered()
|
|
222
216
|
|
|
223
|
-
def set_ordered(self, ordered: bool, in_place: bool = False) ->
|
|
217
|
+
def set_ordered(self, ordered: bool, in_place: bool = False) -> Factor:
|
|
224
218
|
"""
|
|
225
219
|
Args:
|
|
226
220
|
ordered:
|
|
@@ -293,12 +287,7 @@ class Factor:
|
|
|
293
287
|
Returns:
|
|
294
288
|
A stringified representation of this object.
|
|
295
289
|
"""
|
|
296
|
-
tmp = (
|
|
297
|
-
"Factor(codes="
|
|
298
|
-
+ print_truncated_list(self._codes)
|
|
299
|
-
+ ", levels="
|
|
300
|
-
+ print_truncated_list(self._levels)
|
|
301
|
-
)
|
|
290
|
+
tmp = "Factor(codes=" + print_truncated_list(self._codes) + ", levels=" + print_truncated_list(self._levels)
|
|
302
291
|
if self._ordered:
|
|
303
292
|
tmp += ", ordered=True"
|
|
304
293
|
if self._names:
|
|
@@ -311,42 +300,24 @@ class Factor:
|
|
|
311
300
|
Returns:
|
|
312
301
|
A pretty-printed representation of this object.
|
|
313
302
|
"""
|
|
314
|
-
message = (
|
|
315
|
-
"Factor of length "
|
|
316
|
-
+ str(len(self._codes))
|
|
317
|
-
+ " with "
|
|
318
|
-
+ str(len(self._levels))
|
|
319
|
-
+ " level"
|
|
320
|
-
)
|
|
303
|
+
message = "Factor of length " + str(len(self._codes)) + " with " + str(len(self._levels)) + " level"
|
|
321
304
|
if len(self._levels) != 0:
|
|
322
305
|
message += "s"
|
|
323
306
|
message += "\n"
|
|
324
307
|
message += (
|
|
325
308
|
"values: "
|
|
326
|
-
+ print_truncated_list(
|
|
327
|
-
self._codes, transform=lambda i: self._levels[i], include_brackets=False
|
|
328
|
-
)
|
|
309
|
+
+ print_truncated_list(self._codes, transform=lambda i: self._levels[i], include_brackets=False)
|
|
329
310
|
+ "\n"
|
|
330
311
|
)
|
|
331
312
|
if self._names is not None:
|
|
332
313
|
message += (
|
|
333
|
-
"names: "
|
|
334
|
-
+ print_truncated_list(
|
|
335
|
-
self._names, transform=lambda x: x, include_brackets=False
|
|
336
|
-
)
|
|
337
|
-
+ "\n"
|
|
338
|
-
)
|
|
339
|
-
message += (
|
|
340
|
-
"levels: "
|
|
341
|
-
+ print_truncated_list(
|
|
342
|
-
self._levels, transform=lambda x: x, include_brackets=False
|
|
314
|
+
"names: " + print_truncated_list(self._names, transform=lambda x: x, include_brackets=False) + "\n"
|
|
343
315
|
)
|
|
344
|
-
|
|
345
|
-
)
|
|
316
|
+
message += "levels: " + print_truncated_list(self._levels, transform=lambda x: x, include_brackets=False) + "\n"
|
|
346
317
|
message += "ordered: " + str(self._ordered)
|
|
347
318
|
return message
|
|
348
319
|
|
|
349
|
-
def __eq__(self, other:
|
|
320
|
+
def __eq__(self, other: Factor):
|
|
350
321
|
"""
|
|
351
322
|
Args:
|
|
352
323
|
other: Another ``Factor``.
|
|
@@ -357,7 +328,12 @@ class Factor:
|
|
|
357
328
|
"""
|
|
358
329
|
if not isinstance(other, Factor):
|
|
359
330
|
return False
|
|
360
|
-
if
|
|
331
|
+
if (
|
|
332
|
+
len(self) != len(other)
|
|
333
|
+
or self._levels != other._levels
|
|
334
|
+
or self._names != other._names
|
|
335
|
+
or self._ordered != other._ordered
|
|
336
|
+
):
|
|
361
337
|
return False
|
|
362
338
|
return (self._codes == other._codes).all()
|
|
363
339
|
|
|
@@ -384,7 +360,7 @@ class Factor:
|
|
|
384
360
|
return None
|
|
385
361
|
return self._levels[i]
|
|
386
362
|
|
|
387
|
-
def get_slice(self, index: SubscriptTypes) ->
|
|
363
|
+
def get_slice(self, index: SubscriptTypes) -> Factor:
|
|
388
364
|
"""
|
|
389
365
|
Args:
|
|
390
366
|
index:
|
|
@@ -404,7 +380,7 @@ class Factor:
|
|
|
404
380
|
output._names = subset_sequence(self._names, index)
|
|
405
381
|
return output
|
|
406
382
|
|
|
407
|
-
def __getitem__(self, index: SubscriptTypes) -> Union[str,
|
|
383
|
+
def __getitem__(self, index: SubscriptTypes) -> Union[str, Factor]:
|
|
408
384
|
"""
|
|
409
385
|
If ``index`` is a scalar, this is an alias for :py:meth:`~get_value`.
|
|
410
386
|
|
|
@@ -416,9 +392,7 @@ class Factor:
|
|
|
416
392
|
else:
|
|
417
393
|
return self.get_slice(NormalizedSubscript(index))
|
|
418
394
|
|
|
419
|
-
def set_value(
|
|
420
|
-
self, index: Union[str, int], value: Union[str, None], in_place: bool = False
|
|
421
|
-
) -> "Factor":
|
|
395
|
+
def set_value(self, index: Union[str, int], value: Union[str, None], in_place: bool = False) -> Factor:
|
|
422
396
|
"""
|
|
423
397
|
Args:
|
|
424
398
|
index:
|
|
@@ -450,14 +424,14 @@ class Factor:
|
|
|
450
424
|
output._codes[index] = -1
|
|
451
425
|
return output
|
|
452
426
|
|
|
453
|
-
for i,
|
|
454
|
-
if
|
|
427
|
+
for i, lev in enumerate(output._levels):
|
|
428
|
+
if lev == value:
|
|
455
429
|
output._codes[index] = i
|
|
456
430
|
return output
|
|
457
431
|
|
|
458
432
|
raise IndexError("failed to find level '" + str(value) + "'")
|
|
459
433
|
|
|
460
|
-
def set_slice(self, index: SubscriptTypes, value:
|
|
434
|
+
def set_slice(self, index: SubscriptTypes, value: Factor, in_place: bool = False):
|
|
461
435
|
"""
|
|
462
436
|
Replace items in the ``Factor`` list. The ``index`` elements in the
|
|
463
437
|
current object are replaced with the corresponding values in ``value``.
|
|
@@ -508,7 +482,7 @@ class Factor:
|
|
|
508
482
|
|
|
509
483
|
return output
|
|
510
484
|
|
|
511
|
-
def __setitem__(self, index: SubscriptTypes, value: Union[str,
|
|
485
|
+
def __setitem__(self, index: SubscriptTypes, value: Union[str, Factor]):
|
|
512
486
|
"""
|
|
513
487
|
If ``index`` is a scalar, this is an alias for :py:meth:`~set_value`.
|
|
514
488
|
|
|
@@ -524,7 +498,7 @@ class Factor:
|
|
|
524
498
|
#####>>>> Level setting <<<<#####
|
|
525
499
|
#################################
|
|
526
500
|
|
|
527
|
-
def drop_unused_levels(self, in_place: bool = False) ->
|
|
501
|
+
def drop_unused_levels(self, in_place: bool = False) -> Factor:
|
|
528
502
|
"""Drop unused levels.
|
|
529
503
|
|
|
530
504
|
Args:
|
|
@@ -567,7 +541,7 @@ class Factor:
|
|
|
567
541
|
self,
|
|
568
542
|
levels: Sequence[str],
|
|
569
543
|
in_place: bool = False,
|
|
570
|
-
) ->
|
|
544
|
+
) -> Factor:
|
|
571
545
|
"""Replace the existing levels with a new list. The codes of the
|
|
572
546
|
returned ``Factor`` are unchanged by this method and will index into
|
|
573
547
|
the replacement ``levels``, so each element of the ``Factor`` may refer
|
|
@@ -614,12 +588,7 @@ class Factor:
|
|
|
614
588
|
output._levels = new_levels
|
|
615
589
|
return output
|
|
616
590
|
|
|
617
|
-
def set_levels(
|
|
618
|
-
self,
|
|
619
|
-
levels: Union[str, Sequence[str]],
|
|
620
|
-
remap: bool = True,
|
|
621
|
-
in_place: bool = False
|
|
622
|
-
) -> "Factor":
|
|
591
|
+
def set_levels(self, levels: Union[str, Sequence[str]], remap: bool = True, in_place: bool = False) -> Factor:
|
|
623
592
|
"""
|
|
624
593
|
Alias for :py:meth:`~remap_levels` if ``remap = True``, otherwise an
|
|
625
594
|
alias for :py:meth:`~replace_levels`. The first alias is deprecated and
|
|
@@ -631,9 +600,7 @@ class Factor:
|
|
|
631
600
|
else:
|
|
632
601
|
return self.replace_levels(levels, in_place=in_place)
|
|
633
602
|
|
|
634
|
-
def remap_levels(
|
|
635
|
-
self, levels: Union[str, Sequence[str]], in_place: bool = False
|
|
636
|
-
) -> "Factor":
|
|
603
|
+
def remap_levels(self, levels: Union[str, Sequence[str]], in_place: bool = False) -> Factor:
|
|
637
604
|
"""Remap codes to a replacement list of levels. Each entry of the
|
|
638
605
|
remapped ``Factor`` will refer to the same string across the old and
|
|
639
606
|
new levels, provided that string is present in both sets of levels.
|
|
@@ -679,9 +646,7 @@ class Factor:
|
|
|
679
646
|
lmapping[x] = len(new_levels)
|
|
680
647
|
new_levels.append(x)
|
|
681
648
|
if levels not in lmapping:
|
|
682
|
-
raise ValueError(
|
|
683
|
-
"string 'levels' should already be present among object levels"
|
|
684
|
-
)
|
|
649
|
+
raise ValueError("string 'levels' should already be present among object levels")
|
|
685
650
|
else:
|
|
686
651
|
new_levels = levels
|
|
687
652
|
if not isinstance(new_levels, StringList):
|
|
@@ -712,7 +677,7 @@ class Factor:
|
|
|
712
677
|
#####>>>> Copying <<<<#####
|
|
713
678
|
###########################
|
|
714
679
|
|
|
715
|
-
def __copy__(self) ->
|
|
680
|
+
def __copy__(self) -> Factor:
|
|
716
681
|
"""
|
|
717
682
|
Returns:
|
|
718
683
|
A shallow copy of the ``Factor`` object.
|
|
@@ -725,7 +690,7 @@ class Factor:
|
|
|
725
690
|
_validate=False,
|
|
726
691
|
)
|
|
727
692
|
|
|
728
|
-
def __deepcopy__(self, memo) ->
|
|
693
|
+
def __deepcopy__(self, memo) -> Factor:
|
|
729
694
|
"""
|
|
730
695
|
Returns:
|
|
731
696
|
A deep copy of the ``Factor`` object.
|
|
@@ -762,8 +727,8 @@ class Factor:
|
|
|
762
727
|
sort_levels: bool = True,
|
|
763
728
|
ordered: bool = False,
|
|
764
729
|
names: Optional[Sequence[str]] = None,
|
|
765
|
-
**kwargs
|
|
766
|
-
) ->
|
|
730
|
+
**kwargs,
|
|
731
|
+
) -> Factor:
|
|
767
732
|
"""Convert a sequence of hashable values into a factor.
|
|
768
733
|
|
|
769
734
|
Args:
|
|
@@ -799,6 +764,60 @@ class Factor:
|
|
|
799
764
|
levels, indices = factorize(x, levels=levels, sort_levels=sort_levels, **kwargs)
|
|
800
765
|
return Factor(indices, levels=levels, ordered=ordered, names=names)
|
|
801
766
|
|
|
767
|
+
################################
|
|
768
|
+
#####>>>> List methods <<<<#####
|
|
769
|
+
################################
|
|
770
|
+
|
|
771
|
+
def as_list(self) -> list:
|
|
772
|
+
"""
|
|
773
|
+
Returns:
|
|
774
|
+
List of strings corresponding to the factor elements.
|
|
775
|
+
Missing values are represented as None.
|
|
776
|
+
"""
|
|
777
|
+
return [self._levels[c] if c >= 0 else None for c in self._codes]
|
|
778
|
+
|
|
779
|
+
def safe_delete(self, index: Union[int, str, slice], in_place: bool = False) -> Factor:
|
|
780
|
+
"""
|
|
781
|
+
Args:
|
|
782
|
+
index:
|
|
783
|
+
Integer index or slice containing position(s) to delete.
|
|
784
|
+
Alternatively, the name of the value to delete (the first
|
|
785
|
+
occurrence of the name is used).
|
|
786
|
+
|
|
787
|
+
in_place:
|
|
788
|
+
Whether to modify the current object in place.
|
|
789
|
+
|
|
790
|
+
Returns:
|
|
791
|
+
A ``Factor`` where the item at ``index`` is removed. This is a
|
|
792
|
+
new object if ``in_place = False``, otherwise it is a reference to
|
|
793
|
+
the current object.
|
|
794
|
+
"""
|
|
795
|
+
if in_place:
|
|
796
|
+
output = self
|
|
797
|
+
else:
|
|
798
|
+
output = copy(self)
|
|
799
|
+
output._codes = copy(self._codes)
|
|
800
|
+
if output._names is not None:
|
|
801
|
+
output._names = output._names.copy()
|
|
802
|
+
|
|
803
|
+
if isinstance(index, str):
|
|
804
|
+
index = _name_to_position(output._names, index)
|
|
805
|
+
|
|
806
|
+
output._codes = numpy.delete(output._codes, index)
|
|
807
|
+
|
|
808
|
+
if output._names is not None:
|
|
809
|
+
output._names.delete(index)
|
|
810
|
+
|
|
811
|
+
return output
|
|
812
|
+
|
|
813
|
+
def delete(self, index: Union[int, str, slice]):
|
|
814
|
+
"""Alias for :py:meth:`~safe_delete` with ``in_place = True``."""
|
|
815
|
+
self.safe_delete(index, in_place=True)
|
|
816
|
+
|
|
817
|
+
def __delitem__(self, index: Union[int, str, slice]):
|
|
818
|
+
"""Alias for :py:meth:`~delete`."""
|
|
819
|
+
self.delete(index)
|
|
820
|
+
|
|
802
821
|
|
|
803
822
|
@subset_sequence.register
|
|
804
823
|
def _subset_sequence_Factor(x: Factor, indices: Sequence[int]) -> Factor:
|
|
@@ -841,9 +860,7 @@ def _combine_factors(*x: Factor):
|
|
|
841
860
|
new_levels.append(y)
|
|
842
861
|
mapping.append(all_levels_map[y])
|
|
843
862
|
|
|
844
|
-
curout = numpy.ndarray(
|
|
845
|
-
len(f), dtype=numpy.min_scalar_type(-len(new_levels))
|
|
846
|
-
)
|
|
863
|
+
curout = numpy.ndarray(len(f), dtype=numpy.min_scalar_type(-len(new_levels)))
|
|
847
864
|
for i, j in enumerate(f._codes):
|
|
848
865
|
if j < 0:
|
|
849
866
|
curout[i] = j
|
biocutils-0.3.2.dev1/src/biocutils/float_list.py → biocutils-0.3.3/src/biocutils/FloatList.py
RENAMED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from typing import Any, Iterable, Optional, Sequence, Union
|
|
2
4
|
|
|
3
|
-
from .
|
|
4
|
-
from .
|
|
5
|
+
from .NamedList import NamedList
|
|
6
|
+
from .Names import Names
|
|
5
7
|
from .normalize_subscript import SubscriptTypes
|
|
6
8
|
|
|
7
9
|
|
|
@@ -10,7 +12,7 @@ def _coerce_to_float(x: Any):
|
|
|
10
12
|
return None
|
|
11
13
|
try:
|
|
12
14
|
return float(x)
|
|
13
|
-
except:
|
|
15
|
+
except Exception as _:
|
|
14
16
|
return None
|
|
15
17
|
|
|
16
18
|
|
|
@@ -47,7 +49,7 @@ class FloatList(NamedList):
|
|
|
47
49
|
|
|
48
50
|
def __init__(
|
|
49
51
|
self,
|
|
50
|
-
data: Optional[
|
|
52
|
+
data: Optional[Sequence] = None,
|
|
51
53
|
names: Optional[Names] = None,
|
|
52
54
|
_validate: bool = True,
|
|
53
55
|
):
|
|
@@ -74,32 +76,25 @@ class FloatList(NamedList):
|
|
|
74
76
|
data = data._data
|
|
75
77
|
original = data
|
|
76
78
|
data = list(_coerce_to_float(item) for item in original)
|
|
79
|
+
|
|
77
80
|
super().__init__(data, names, _validate=_validate)
|
|
78
81
|
|
|
79
|
-
def set_value(
|
|
80
|
-
self, index: Union[int, str], value: Any, in_place: bool = False
|
|
81
|
-
) -> "FloatList":
|
|
82
|
+
def set_value(self, index: Union[int, str], value: Any, in_place: bool = False) -> FloatList:
|
|
82
83
|
"""Calls :py:meth:`~biocutils.NamedList.NamedList.set_value` after coercing ``value`` to a float."""
|
|
83
84
|
return super().set_value(index, _coerce_to_float(value), in_place=in_place)
|
|
84
85
|
|
|
85
|
-
def set_slice(
|
|
86
|
-
self, index: SubscriptTypes, value: Sequence, in_place: bool = False
|
|
87
|
-
) -> "FloatList":
|
|
86
|
+
def set_slice(self, index: SubscriptTypes, value: Sequence, in_place: bool = False) -> FloatList:
|
|
88
87
|
"""Calls :py:meth:`~biocutils.NamedList.NamedList.set_slice` after coercing ``value`` to floats."""
|
|
89
88
|
return super().set_slice(index, _SubscriptCoercer(value), in_place=in_place)
|
|
90
89
|
|
|
91
|
-
def safe_insert(
|
|
92
|
-
self, index: Union[int, str], value: Any, in_place: bool = False
|
|
93
|
-
) -> "FloatList":
|
|
90
|
+
def safe_insert(self, index: Union[int, str], value: Any, in_place: bool = False) -> FloatList:
|
|
94
91
|
"""Calls :py:meth:`~biocutils.NamedList.NamedList.safe_insert` after coercing ``value`` to a float."""
|
|
95
92
|
return super().safe_insert(index, _coerce_to_float(value), in_place=in_place)
|
|
96
93
|
|
|
97
|
-
def safe_append(self, value: Any, in_place: bool = False) ->
|
|
94
|
+
def safe_append(self, value: Any, in_place: bool = False) -> FloatList:
|
|
98
95
|
"""Calls :py:meth:`~biocutils.NamedList.NamedList.safe_append` after coercing ``value`` to a float."""
|
|
99
96
|
return super().safe_append(_coerce_to_float(value), in_place=in_place)
|
|
100
97
|
|
|
101
|
-
def safe_extend(self, other: Iterable, in_place: bool = True) ->
|
|
98
|
+
def safe_extend(self, other: Iterable, in_place: bool = True) -> FloatList:
|
|
102
99
|
"""Calls :py:meth:`~biocutils.NamedList.NamedList.safe_extend` after coercing elements of ``other`` to floats."""
|
|
103
|
-
return super().safe_extend(
|
|
104
|
-
(_coerce_to_float(y) for y in other), in_place=in_place
|
|
105
|
-
)
|
|
100
|
+
return super().safe_extend((_coerce_to_float(y) for y in other), in_place=in_place)
|