42
42
soft_convert_objects ,
43
43
)
44
44
from pandas .core .dtypes .common import (
45
+ is_1d_only_ea_dtype ,
46
+ is_1d_only_ea_obj ,
45
47
is_categorical_dtype ,
46
48
is_dtype_equal ,
47
49
is_extension_array_dtype ,
@@ -224,7 +226,6 @@ def get_values(self, dtype: DtypeObj | None = None) -> np.ndarray:
224
226
# expected "ndarray")
225
227
return self .values # type: ignore[return-value]
226
228
227
- @final
228
229
def get_block_values_for_json (self ) -> np .ndarray :
229
230
"""
230
231
This is used in the JSON C code.
@@ -415,7 +416,11 @@ def _split_op_result(self, result) -> list[Block]:
415
416
# if we get a 2D ExtensionArray, we need to split it into 1D pieces
416
417
nbs = []
417
418
for i , loc in enumerate (self ._mgr_locs ):
418
- vals = result [i ]
419
+ if not is_1d_only_ea_obj (result ):
420
+ vals = result [i : i + 1 ]
421
+ else :
422
+ vals = result [i ]
423
+
419
424
block = self .make_block (values = vals , placement = loc )
420
425
nbs .append (block )
421
426
return nbs
@@ -1670,7 +1675,7 @@ class NumericBlock(NumpyBlock):
1670
1675
is_numeric = True
1671
1676
1672
1677
1673
- class NDArrayBackedExtensionBlock (EABackedBlock ):
1678
+ class NDArrayBackedExtensionBlock (libinternals . Block , EABackedBlock ):
1674
1679
"""
1675
1680
Block backed by an NDArrayBackedExtensionArray
1676
1681
"""
@@ -1683,11 +1688,6 @@ def is_view(self) -> bool:
1683
1688
# check the ndarray values of the DatetimeIndex values
1684
1689
return self .values ._ndarray .base is not None
1685
1690
1686
- def iget (self , key ):
1687
- # GH#31649 we need to wrap scalars in Timestamp/Timedelta
1688
- # TODO(EA2D): this can be removed if we ever have 2D EA
1689
- return self .values .reshape (self .shape )[key ]
1690
-
1691
1691
def setitem (self , indexer , value ):
1692
1692
if not self ._can_hold_element (value ):
1693
1693
# TODO: general case needs casting logic.
@@ -1707,24 +1707,21 @@ def putmask(self, mask, new) -> list[Block]:
1707
1707
if not self ._can_hold_element (new ):
1708
1708
return self .astype (object ).putmask (mask , new )
1709
1709
1710
- # TODO(EA2D): reshape unnecessary with 2D EAs
1711
- arr = self .values .reshape (self .shape )
1710
+ arr = self .values
1712
1711
arr .T .putmask (mask , new )
1713
1712
return [self ]
1714
1713
1715
1714
def where (self , other , cond , errors = "raise" ) -> list [Block ]:
1716
1715
# TODO(EA2D): reshape unnecessary with 2D EAs
1717
- arr = self .values . reshape ( self . shape )
1716
+ arr = self .values
1718
1717
1719
1718
cond = extract_bool_array (cond )
1720
1719
1721
1720
try :
1722
1721
res_values = arr .T .where (cond , other ).T
1723
1722
except (ValueError , TypeError ):
1724
- return super () .where (other , cond , errors = errors )
1723
+ return Block .where (self , other , cond , errors = errors )
1725
1724
1726
- # TODO(EA2D): reshape not needed with 2D EAs
1727
- res_values = res_values .reshape (self .values .shape )
1728
1725
nb = self .make_block_same_class (res_values )
1729
1726
return [nb ]
1730
1727
@@ -1748,15 +1745,13 @@ def diff(self, n: int, axis: int = 0) -> list[Block]:
1748
1745
The arguments here are mimicking shift so they are called correctly
1749
1746
by apply.
1750
1747
"""
1751
- # TODO(EA2D): reshape not necessary with 2D EAs
1752
- values = self .values .reshape (self .shape )
1748
+ values = self .values
1753
1749
1754
1750
new_values = values - values .shift (n , axis = axis )
1755
1751
return [self .make_block (new_values )]
1756
1752
1757
1753
def shift (self , periods : int , axis : int = 0 , fill_value : Any = None ) -> list [Block ]:
1758
- # TODO(EA2D) this is unnecessary if these blocks are backed by 2D EAs
1759
- values = self .values .reshape (self .shape )
1754
+ values = self .values
1760
1755
new_values = values .shift (periods , fill_value = fill_value , axis = axis )
1761
1756
return [self .make_block_same_class (new_values )]
1762
1757
@@ -1776,31 +1771,27 @@ def fillna(
1776
1771
return [self .make_block_same_class (values = new_values )]
1777
1772
1778
1773
1779
- class DatetimeLikeBlock (libinternals . Block , NDArrayBackedExtensionBlock ):
1774
+ class DatetimeLikeBlock (NDArrayBackedExtensionBlock ):
1780
1775
"""Block for datetime64[ns], timedelta64[ns]."""
1781
1776
1782
1777
__slots__ = ()
1783
1778
is_numeric = False
1784
1779
values : DatetimeArray | TimedeltaArray
1785
1780
1781
+ def get_block_values_for_json (self ):
1782
+ # Not necessary to override, but helps perf
1783
+ return self .values ._ndarray
1786
1784
1787
- class DatetimeTZBlock (ExtensionBlock , NDArrayBackedExtensionBlock ):
1785
+
1786
+ class DatetimeTZBlock (DatetimeLikeBlock ):
1788
1787
""" implement a datetime64 block with a tz attribute """
1789
1788
1790
1789
values : DatetimeArray
1791
1790
1792
1791
__slots__ = ()
1793
1792
is_extension = True
1794
- is_numeric = False
1795
-
1796
- diff = NDArrayBackedExtensionBlock .diff
1797
- where = NDArrayBackedExtensionBlock .where
1798
- putmask = NDArrayBackedExtensionBlock .putmask
1799
- fillna = NDArrayBackedExtensionBlock .fillna
1800
-
1801
- get_values = NDArrayBackedExtensionBlock .get_values
1802
-
1803
- is_view = NDArrayBackedExtensionBlock .is_view
1793
+ _validate_ndim = True
1794
+ _can_consolidate = False
1804
1795
1805
1796
1806
1797
class ObjectBlock (NumpyBlock ):
@@ -1967,7 +1958,7 @@ def check_ndim(values, placement: BlockPlacement, ndim: int):
1967
1958
f"values.ndim > ndim [{ values .ndim } > { ndim } ]"
1968
1959
)
1969
1960
1970
- elif isinstance (values . dtype , np .dtype ):
1961
+ elif not is_1d_only_ea_dtype (values .dtype ):
1971
1962
# TODO(EA2D): special case not needed with 2D EAs
1972
1963
if values .ndim != ndim :
1973
1964
raise ValueError (
@@ -1981,7 +1972,7 @@ def check_ndim(values, placement: BlockPlacement, ndim: int):
1981
1972
)
1982
1973
elif ndim == 2 and len (placement ) != 1 :
1983
1974
# TODO(EA2D): special case unnecessary with 2D EAs
1984
- raise AssertionError ( "block.size != values.size " )
1975
+ raise ValueError ( "need to split " )
1985
1976
1986
1977
1987
1978
def extract_pandas_array (
@@ -2026,8 +2017,9 @@ def ensure_block_shape(values: ArrayLike, ndim: int = 1) -> ArrayLike:
2026
2017
"""
2027
2018
Reshape if possible to have values.ndim == ndim.
2028
2019
"""
2020
+
2029
2021
if values .ndim < ndim :
2030
- if not is_extension_array_dtype (values .dtype ):
2022
+ if not is_1d_only_ea_dtype (values .dtype ):
2031
2023
# TODO(EA2D): https://github.com/pandas-dev/pandas/issues/23023
2032
2024
# block.shape is incorrect for "2D" ExtensionArrays
2033
2025
# We can't, and don't need to, reshape.
0 commit comments