|
19 | 19 | from pandas.core.dtypes.common import (
|
20 | 20 | DT64NS_DTYPE,
|
21 | 21 | is_datetimelike_v_numeric,
|
| 22 | + is_dtype_equal, |
22 | 23 | is_extension_array_dtype,
|
23 | 24 | is_list_like,
|
24 | 25 | is_numeric_v_string_like,
|
|
27 | 28 | from pandas.core.dtypes.concat import concat_compat
|
28 | 29 | from pandas.core.dtypes.dtypes import ExtensionDtype
|
29 | 30 | from pandas.core.dtypes.generic import ABCDataFrame, ABCSeries
|
30 |
| -from pandas.core.dtypes.missing import isna |
| 31 | +from pandas.core.dtypes.missing import array_equivalent, isna |
31 | 32 |
|
32 | 33 | import pandas.core.algorithms as algos
|
| 34 | +from pandas.core.arrays import ExtensionArray |
33 | 35 | from pandas.core.arrays.sparse import SparseDtype
|
34 | 36 | from pandas.core.base import PandasObject
|
35 | 37 | import pandas.core.common as com
|
@@ -1409,29 +1411,39 @@ def take(self, indexer, axis: int = 1, verify: bool = True, convert: bool = True
|
1409 | 1411 | new_axis=new_labels, indexer=indexer, axis=axis, allow_dups=True
|
1410 | 1412 | )
|
1411 | 1413 |
|
1412 |
| - def equals(self, other) -> bool: |
| 1414 | + def equals(self, other: "BlockManager") -> bool: |
1413 | 1415 | self_axes, other_axes = self.axes, other.axes
|
1414 | 1416 | if len(self_axes) != len(other_axes):
|
1415 | 1417 | return False
|
1416 | 1418 | if not all(ax1.equals(ax2) for ax1, ax2 in zip(self_axes, other_axes)):
|
1417 | 1419 | return False
|
1418 |
| - self._consolidate_inplace() |
1419 |
| - other._consolidate_inplace() |
1420 |
| - if len(self.blocks) != len(other.blocks): |
1421 |
| - return False |
1422 | 1420 |
|
1423 |
| - # canonicalize block order, using a tuple combining the mgr_locs |
1424 |
| - # then type name because there might be unconsolidated |
1425 |
| - # blocks (say, Categorical) which can only be distinguished by |
1426 |
| - # the iteration order |
1427 |
| - def canonicalize(block): |
1428 |
| - return (block.mgr_locs.as_array.tolist(), block.dtype.name) |
1429 |
| - |
1430 |
| - self_blocks = sorted(self.blocks, key=canonicalize) |
1431 |
| - other_blocks = sorted(other.blocks, key=canonicalize) |
1432 |
| - return all( |
1433 |
| - block.equals(oblock) for block, oblock in zip(self_blocks, other_blocks) |
1434 |
| - ) |
| 1421 | + if self.ndim == 1: |
| 1422 | + # For SingleBlockManager (i.e.Series) |
| 1423 | + if other.ndim != 1: |
| 1424 | + return False |
| 1425 | + left = self.blocks[0].values |
| 1426 | + right = other.blocks[0].values |
| 1427 | + if not is_dtype_equal(left.dtype, right.dtype): |
| 1428 | + return False |
| 1429 | + elif isinstance(left, ExtensionArray): |
| 1430 | + return left.equals(right) |
| 1431 | + else: |
| 1432 | + return array_equivalent(left, right) |
| 1433 | + |
| 1434 | + for i in range(len(self.items)): |
| 1435 | + # Check column-wise, return False if any column doesnt match |
| 1436 | + left = self.iget_values(i) |
| 1437 | + right = other.iget_values(i) |
| 1438 | + if not is_dtype_equal(left.dtype, right.dtype): |
| 1439 | + return False |
| 1440 | + elif isinstance(left, ExtensionArray): |
| 1441 | + if not left.equals(right): |
| 1442 | + return False |
| 1443 | + else: |
| 1444 | + if not array_equivalent(left, right): |
| 1445 | + return False |
| 1446 | + return True |
1435 | 1447 |
|
1436 | 1448 | def unstack(self, unstacker, fill_value) -> "BlockManager":
|
1437 | 1449 | """
|
|
0 commit comments