Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/pandas/core/internals/base.py: 45%
86 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1"""
2Base class for the internal managers. Both BlockManager and ArrayManager
3inherit from this class.
4"""
5from __future__ import annotations
7from typing import (
8 Literal,
9 TypeVar,
10 final,
11)
13import numpy as np
15from pandas._typing import (
16 ArrayLike,
17 DtypeObj,
18 Shape,
19)
20from pandas.errors import AbstractMethodError
22from pandas.core.dtypes.cast import (
23 find_common_type,
24 np_can_hold_element,
25)
27from pandas.core.base import PandasObject
28from pandas.core.indexes.api import (
29 Index,
30 default_index,
31)
33T = TypeVar("T", bound="DataManager")
36class DataManager(PandasObject):
38 # TODO share more methods/attributes
40 axes: list[Index]
42 @property
43 def items(self) -> Index:
44 raise AbstractMethodError(self)
46 @final
47 def __len__(self) -> int:
48 return len(self.items)
50 @property
51 def ndim(self) -> int:
52 return len(self.axes)
54 @property
55 def shape(self) -> Shape:
56 return tuple(len(ax) for ax in self.axes)
58 @final
59 def _validate_set_axis(self, axis: int, new_labels: Index) -> None:
60 # Caller is responsible for ensuring we have an Index object.
61 old_len = len(self.axes[axis])
62 new_len = len(new_labels)
64 if axis == 1 and len(self.items) == 0:
65 # If we are setting the index on a DataFrame with no columns,
66 # it is OK to change the length.
67 pass
69 elif new_len != old_len:
70 raise ValueError(
71 f"Length mismatch: Expected axis has {old_len} elements, new "
72 f"values have {new_len} elements"
73 )
75 def reindex_indexer(
76 self: T,
77 new_axis,
78 indexer,
79 axis: int,
80 fill_value=None,
81 allow_dups: bool = False,
82 copy: bool = True,
83 only_slice: bool = False,
84 ) -> T:
85 raise AbstractMethodError(self)
87 @final
88 def reindex_axis(
89 self: T,
90 new_index: Index,
91 axis: int,
92 fill_value=None,
93 only_slice: bool = False,
94 ) -> T:
95 """
96 Conform data manager to new index.
97 """
98 new_index, indexer = self.axes[axis].reindex(new_index)
100 return self.reindex_indexer(
101 new_index,
102 indexer,
103 axis=axis,
104 fill_value=fill_value,
105 copy=False,
106 only_slice=only_slice,
107 )
109 def _equal_values(self: T, other: T) -> bool:
110 """
111 To be implemented by the subclasses. Only check the column values
112 assuming shape and indexes have already been checked.
113 """
114 raise AbstractMethodError(self)
116 @final
117 def equals(self, other: object) -> bool:
118 """
119 Implementation for DataFrame.equals
120 """
121 if not isinstance(other, DataManager):
122 return False
124 self_axes, other_axes = self.axes, other.axes
125 if len(self_axes) != len(other_axes):
126 return False
127 if not all(ax1.equals(ax2) for ax1, ax2 in zip(self_axes, other_axes)):
128 return False
130 return self._equal_values(other)
132 def apply(
133 self: T,
134 f,
135 align_keys: list[str] | None = None,
136 ignore_failures: bool = False,
137 **kwargs,
138 ) -> T:
139 raise AbstractMethodError(self)
141 @final
142 def isna(self: T, func) -> T:
143 return self.apply("apply", func=func)
145 # --------------------------------------------------------------------
146 # Consolidation: No-ops for all but BlockManager
148 def is_consolidated(self) -> bool:
149 return True
151 def consolidate(self: T) -> T:
152 return self
154 def _consolidate_inplace(self) -> None:
155 return
158class SingleDataManager(DataManager):
159 @property
160 def ndim(self) -> Literal[1]:
161 return 1
163 @final
164 @property
165 def array(self) -> ArrayLike:
166 """
167 Quick access to the backing array of the Block or SingleArrayManager.
168 """
169 # error: "SingleDataManager" has no attribute "arrays"; maybe "array"
170 return self.arrays[0] # type: ignore[attr-defined]
172 def setitem_inplace(self, indexer, value) -> None:
173 """
174 Set values with indexer.
176 For Single[Block/Array]Manager, this backs s[indexer] = value
178 This is an inplace version of `setitem()`, mutating the manager/values
179 in place, not returning a new Manager (and Block), and thus never changing
180 the dtype.
181 """
182 arr = self.array
184 # EAs will do this validation in their own __setitem__ methods.
185 if isinstance(arr, np.ndarray):
186 # Note: checking for ndarray instead of np.dtype means we exclude
187 # dt64/td64, which do their own validation.
188 value = np_can_hold_element(arr.dtype, value)
190 arr[indexer] = value
192 def grouped_reduce(self, func, ignore_failures: bool = False):
193 """
194 ignore_failures : bool, default False
195 Not used; for compatibility with ArrayManager/BlockManager.
196 """
198 arr = self.array
199 res = func(arr)
200 index = default_index(len(res))
202 mgr = type(self).from_array(res, index)
203 return mgr
205 @classmethod
206 def from_array(cls, arr: ArrayLike, index: Index):
207 raise AbstractMethodError(cls)
210def interleaved_dtype(dtypes: list[DtypeObj]) -> DtypeObj | None:
211 """
212 Find the common dtype for `blocks`.
214 Parameters
215 ----------
216 blocks : List[DtypeObj]
218 Returns
219 -------
220 dtype : np.dtype, ExtensionDtype, or None
221 None is returned when `blocks` is empty.
222 """
223 if not len(dtypes):
224 return None
226 return find_common_type(dtypes)