27
27
writers ,
28
28
)
29
29
from pandas ._libs .internals import BlockPlacement
30
- from pandas ._libs .tslibs import conversion
31
30
from pandas ._typing import (
32
31
ArrayLike ,
33
32
Dtype ,
47
46
maybe_downcast_numeric ,
48
47
maybe_downcast_to_dtype ,
49
48
maybe_upcast ,
50
- sanitize_to_nanoseconds ,
51
49
soft_convert_objects ,
52
50
)
53
51
from pandas .core .dtypes .common import (
@@ -938,7 +936,11 @@ def setitem(self, indexer, value):
938
936
return self .coerce_to_target_dtype (value ).setitem (indexer , value )
939
937
940
938
if self .dtype .kind in ["m" , "M" ]:
941
- arr = self .array_values .T
939
+ arr = self .values
940
+ if self .ndim > 1 :
941
+ # Dont transpose with ndim=1 bc we would fail to invalidate
942
+ # arr.freq
943
+ arr = arr .T
942
944
arr [indexer ] = value
943
945
return self
944
946
@@ -1172,6 +1174,7 @@ def _interpolate_with_fill(
1172
1174
limit_area = limit_area ,
1173
1175
)
1174
1176
1177
+ values = maybe_coerce_values (values )
1175
1178
blocks = [self .make_block_same_class (values )]
1176
1179
return self ._maybe_downcast (blocks , downcast )
1177
1180
@@ -1227,6 +1230,7 @@ def func(yvalues: np.ndarray) -> np.ndarray:
1227
1230
1228
1231
# interp each column independently
1229
1232
interp_values = np .apply_along_axis (func , axis , data )
1233
+ interp_values = maybe_coerce_values (interp_values )
1230
1234
1231
1235
blocks = [self .make_block_same_class (interp_values )]
1232
1236
return self ._maybe_downcast (blocks , downcast )
@@ -1788,27 +1792,32 @@ class NDArrayBackedExtensionBlock(HybridMixin, Block):
1788
1792
Block backed by an NDArrayBackedExtensionArray
1789
1793
"""
1790
1794
1795
+ values : NDArrayBackedExtensionArray
1796
+
1797
+ @property
1798
+ def is_view (self ) -> bool :
1799
+ """ return a boolean if I am possibly a view """
1800
+ # check the ndarray values of the DatetimeIndex values
1801
+ return self .values ._ndarray .base is not None
1802
+
1791
1803
def internal_values (self ):
1792
1804
# Override to return DatetimeArray and TimedeltaArray
1793
- return self .array_values
1805
+ return self .values
1794
1806
1795
1807
def get_values (self , dtype : Optional [DtypeObj ] = None ) -> np .ndarray :
1796
1808
"""
1797
1809
return object dtype as boxed values, such as Timestamps/Timedelta
1798
1810
"""
1799
- values = self .array_values
1811
+ values = self .values
1800
1812
if is_object_dtype (dtype ):
1801
- # DTA/TDA constructor and astype can handle 2D
1802
- # error: "Callable[..., Any]" has no attribute "astype"
1803
- values = values .astype (object ) # type: ignore[attr-defined]
1813
+ values = values .astype (object )
1804
1814
# TODO(EA2D): reshape not needed with 2D EAs
1805
1815
return np .asarray (values ).reshape (self .shape )
1806
1816
1807
1817
def iget (self , key ):
1808
1818
# GH#31649 we need to wrap scalars in Timestamp/Timedelta
1809
1819
# TODO(EA2D): this can be removed if we ever have 2D EA
1810
- # error: "Callable[..., Any]" has no attribute "reshape"
1811
- return self .array_values .reshape (self .shape )[key ] # type: ignore[attr-defined]
1820
+ return self .values .reshape (self .shape )[key ]
1812
1821
1813
1822
def putmask (self , mask , new ) -> List [Block ]:
1814
1823
mask = extract_bool_array (mask )
@@ -1817,16 +1826,13 @@ def putmask(self, mask, new) -> List[Block]:
1817
1826
return self .astype (object ).putmask (mask , new )
1818
1827
1819
1828
# TODO(EA2D): reshape unnecessary with 2D EAs
1820
- # error: "Callable[..., Any]" has no attribute "reshape"
1821
- arr = self .array_values .reshape (self .shape ) # type: ignore[attr-defined]
1822
- arr = cast ("NDArrayBackedExtensionArray" , arr )
1829
+ arr = self .values .reshape (self .shape )
1823
1830
arr .T .putmask (mask , new )
1824
1831
return [self ]
1825
1832
1826
1833
def where (self , other , cond , errors = "raise" ) -> List [Block ]:
1827
1834
# TODO(EA2D): reshape unnecessary with 2D EAs
1828
- # error: "Callable[..., Any]" has no attribute "reshape"
1829
- arr = self .array_values .reshape (self .shape ) # type: ignore[attr-defined]
1835
+ arr = self .values .reshape (self .shape )
1830
1836
1831
1837
cond = extract_bool_array (cond )
1832
1838
@@ -1837,7 +1843,6 @@ def where(self, other, cond, errors="raise") -> List[Block]:
1837
1843
1838
1844
# TODO(EA2D): reshape not needed with 2D EAs
1839
1845
res_values = res_values .reshape (self .values .shape )
1840
- res_values = maybe_coerce_values (res_values )
1841
1846
nb = self .make_block_same_class (res_values )
1842
1847
return [nb ]
1843
1848
@@ -1862,19 +1867,15 @@ def diff(self, n: int, axis: int = 0) -> List[Block]:
1862
1867
by apply.
1863
1868
"""
1864
1869
# TODO(EA2D): reshape not necessary with 2D EAs
1865
- # error: "Callable[..., Any]" has no attribute "reshape"
1866
- values = self .array_values .reshape (self .shape ) # type: ignore[attr-defined]
1870
+ values = self .values .reshape (self .shape )
1867
1871
1868
1872
new_values = values - values .shift (n , axis = axis )
1869
- new_values = maybe_coerce_values (new_values )
1870
1873
return [self .make_block (new_values )]
1871
1874
1872
1875
def shift (self , periods : int , axis : int = 0 , fill_value : Any = None ) -> List [Block ]:
1873
- # TODO(EA2D) this is unnecessary if these blocks are backed by 2D EA
1874
- # error: "Callable[..., Any]" has no attribute "reshape"
1875
- values = self .array_values .reshape (self .shape ) # type: ignore[attr-defined]
1876
+ # TODO(EA2D) this is unnecessary if these blocks are backed by 2D EAs
1877
+ values = self .values .reshape (self .shape )
1876
1878
new_values = values .shift (periods , fill_value = fill_value , axis = axis )
1877
- new_values = maybe_coerce_values (new_values )
1878
1879
return [self .make_block_same_class (new_values )]
1879
1880
1880
1881
def fillna (
@@ -1887,38 +1888,27 @@ def fillna(
1887
1888
# TODO: don't special-case td64
1888
1889
return self .astype (object ).fillna (value , limit , inplace , downcast )
1889
1890
1890
- values = self .array_values
1891
- # error: "Callable[..., Any]" has no attribute "copy"
1892
- values = values if inplace else values .copy () # type: ignore[attr-defined]
1893
- # error: "Callable[..., Any]" has no attribute "fillna"
1894
- new_values = values .fillna ( # type: ignore[attr-defined]
1895
- value = value , limit = limit
1896
- )
1897
- new_values = maybe_coerce_values (new_values )
1891
+ values = self .values
1892
+ values = values if inplace else values .copy ()
1893
+ new_values = values .fillna (value = value , limit = limit )
1898
1894
return [self .make_block_same_class (values = new_values )]
1899
1895
1900
1896
1901
1897
class DatetimeLikeBlockMixin (NDArrayBackedExtensionBlock ):
1902
1898
"""Mixin class for DatetimeBlock, DatetimeTZBlock, and TimedeltaBlock."""
1903
1899
1900
+ values : Union [DatetimeArray , TimedeltaArray ]
1901
+
1904
1902
is_numeric = False
1905
1903
1906
1904
@cache_readonly
1907
1905
def array_values (self ):
1908
- return ensure_wrapped_if_datetimelike ( self .values )
1906
+ return self .values
1909
1907
1910
1908
1911
1909
class DatetimeBlock (DatetimeLikeBlockMixin ):
1912
1910
__slots__ = ()
1913
1911
1914
- def set_inplace (self , locs , values ):
1915
- """
1916
- See Block.set.__doc__
1917
- """
1918
- values = conversion .ensure_datetime64ns (values , copy = False )
1919
-
1920
- self .values [locs ] = values
1921
-
1922
1912
1923
1913
class DatetimeTZBlock (ExtensionBlock , DatetimeLikeBlockMixin ):
1924
1914
""" implement a datetime64 block with a tz attribute """
@@ -1936,13 +1926,10 @@ class DatetimeTZBlock(ExtensionBlock, DatetimeLikeBlockMixin):
1936
1926
putmask = DatetimeLikeBlockMixin .putmask
1937
1927
fillna = DatetimeLikeBlockMixin .fillna
1938
1928
1939
- array_values = ExtensionBlock .array_values
1940
-
1941
- @property
1942
- def is_view (self ) -> bool :
1943
- """ return a boolean if I am possibly a view """
1944
- # check the ndarray values of the DatetimeIndex values
1945
- return self .values ._data .base is not None
1929
+ # error: Incompatible types in assignment (expression has type
1930
+ # "Callable[[NDArrayBackedExtensionBlock], bool]", base class "ExtensionBlock"
1931
+ # defined the type as "bool") [assignment]
1932
+ is_view = NDArrayBackedExtensionBlock .is_view # type: ignore[assignment]
1946
1933
1947
1934
1948
1935
class TimeDeltaBlock (DatetimeLikeBlockMixin ):
@@ -2029,15 +2016,11 @@ def maybe_coerce_values(values) -> ArrayLike:
2029
2016
values = extract_array (values , extract_numpy = True )
2030
2017
2031
2018
if isinstance (values , np .ndarray ):
2032
- values = sanitize_to_nanoseconds (values )
2019
+ values = ensure_wrapped_if_datetimelike (values )
2033
2020
2034
2021
if issubclass (values .dtype .type , str ):
2035
2022
values = np .array (values , dtype = object )
2036
2023
2037
- elif isinstance (values .dtype , np .dtype ):
2038
- # i.e. not datetime64tz, extract DTA/TDA -> ndarray
2039
- values = values ._data
2040
-
2041
2024
return values
2042
2025
2043
2026
0 commit comments