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