53
53
54
54
import pandas .core .algorithms as algos
55
55
from pandas .core .arrays .sparse import SparseDtype
56
- from pandas .core .construction import extract_array
56
+ from pandas .core .construction import (
57
+ ensure_wrapped_if_datetimelike ,
58
+ extract_array ,
59
+ )
57
60
from pandas .core .indexers import maybe_convert_indices
58
61
from pandas .core .indexes .api import (
59
62
Float64Index ,
@@ -991,6 +994,8 @@ def fast_xs(self, loc: int) -> ArrayLike:
991
994
# Any]]"
992
995
result = np .empty (n , dtype = dtype ) # type: ignore[arg-type]
993
996
997
+ result = ensure_wrapped_if_datetimelike (result )
998
+
994
999
for blk in self .blocks :
995
1000
# Such assignment may incorrectly coerce NaT to None
996
1001
# result[blk.mgr_locs] = blk._slice((slice(None), loc))
@@ -1693,7 +1698,7 @@ def set_values(self, values: ArrayLike):
1693
1698
1694
1699
1695
1700
def create_block_manager_from_blocks (
1696
- blocks : List [Block ], axes : List [Index ]
1701
+ blocks : List [Block ], axes : List [Index ], consolidate : bool = True
1697
1702
) -> BlockManager :
1698
1703
try :
1699
1704
mgr = BlockManager (blocks , axes )
@@ -1703,7 +1708,8 @@ def create_block_manager_from_blocks(
1703
1708
tot_items = sum (arr .shape [0 ] for arr in arrays )
1704
1709
raise construction_error (tot_items , arrays [0 ].shape [1 :], axes , err )
1705
1710
1706
- mgr ._consolidate_inplace ()
1711
+ if consolidate :
1712
+ mgr ._consolidate_inplace ()
1707
1713
return mgr
1708
1714
1709
1715
@@ -1713,7 +1719,10 @@ def _extract_array(obj):
1713
1719
1714
1720
1715
1721
def create_block_manager_from_arrays (
1716
- arrays , names : Index , axes : List [Index ]
1722
+ arrays ,
1723
+ names : Index ,
1724
+ axes : List [Index ],
1725
+ consolidate : bool = True ,
1717
1726
) -> BlockManager :
1718
1727
assert isinstance (names , Index )
1719
1728
assert isinstance (axes , list )
@@ -1722,12 +1731,13 @@ def create_block_manager_from_arrays(
1722
1731
arrays = [_extract_array (x ) for x in arrays ]
1723
1732
1724
1733
try :
1725
- blocks = _form_blocks (arrays , names , axes )
1734
+ blocks = _form_blocks (arrays , names , axes , consolidate )
1726
1735
mgr = BlockManager (blocks , axes )
1727
- mgr ._consolidate_inplace ()
1728
- return mgr
1729
1736
except ValueError as e :
1730
1737
raise construction_error (len (arrays ), arrays [0 ].shape , axes , e )
1738
+ if consolidate :
1739
+ mgr ._consolidate_inplace ()
1740
+ return mgr
1731
1741
1732
1742
1733
1743
def construction_error (
@@ -1760,7 +1770,7 @@ def construction_error(
1760
1770
1761
1771
1762
1772
def _form_blocks (
1763
- arrays : List [ArrayLike ], names : Index , axes : List [Index ]
1773
+ arrays : List [ArrayLike ], names : Index , axes : List [Index ], consolidate : bool
1764
1774
) -> List [Block ]:
1765
1775
# put "leftover" items in float bucket, where else?
1766
1776
# generalize?
@@ -1786,15 +1796,21 @@ def _form_blocks(
1786
1796
1787
1797
blocks : List [Block ] = []
1788
1798
if len (items_dict ["NumericBlock" ]):
1789
- numeric_blocks = _multi_blockify (items_dict ["NumericBlock" ])
1799
+ numeric_blocks = _multi_blockify (
1800
+ items_dict ["NumericBlock" ], consolidate = consolidate
1801
+ )
1790
1802
blocks .extend (numeric_blocks )
1791
1803
1792
1804
if len (items_dict ["TimeDeltaBlock" ]):
1793
- timedelta_blocks = _multi_blockify (items_dict ["TimeDeltaBlock" ])
1805
+ timedelta_blocks = _multi_blockify (
1806
+ items_dict ["TimeDeltaBlock" ], consolidate = consolidate
1807
+ )
1794
1808
blocks .extend (timedelta_blocks )
1795
1809
1796
1810
if len (items_dict ["DatetimeBlock" ]):
1797
- datetime_blocks = _simple_blockify (items_dict ["DatetimeBlock" ], DT64NS_DTYPE )
1811
+ datetime_blocks = _simple_blockify (
1812
+ items_dict ["DatetimeBlock" ], DT64NS_DTYPE , consolidate = consolidate
1813
+ )
1798
1814
blocks .extend (datetime_blocks )
1799
1815
1800
1816
if len (items_dict ["DatetimeTZBlock" ]):
@@ -1805,7 +1821,9 @@ def _form_blocks(
1805
1821
blocks .extend (dttz_blocks )
1806
1822
1807
1823
if len (items_dict ["ObjectBlock" ]) > 0 :
1808
- object_blocks = _simple_blockify (items_dict ["ObjectBlock" ], np .object_ )
1824
+ object_blocks = _simple_blockify (
1825
+ items_dict ["ObjectBlock" ], np .object_ , consolidate = consolidate
1826
+ )
1809
1827
blocks .extend (object_blocks )
1810
1828
1811
1829
if len (items_dict ["CategoricalBlock" ]) > 0 :
@@ -1844,11 +1862,14 @@ def _form_blocks(
1844
1862
return blocks
1845
1863
1846
1864
1847
- def _simple_blockify (tuples , dtype ) -> List [Block ]:
1865
+ def _simple_blockify (tuples , dtype , consolidate : bool ) -> List [Block ]:
1848
1866
"""
1849
1867
return a single array of a block that has a single dtype; if dtype is
1850
1868
not None, coerce to this dtype
1851
1869
"""
1870
+ if not consolidate :
1871
+ return _tuples_to_blocks_no_consolidate (tuples , dtype = dtype )
1872
+
1852
1873
values , placement = _stack_arrays (tuples , dtype )
1853
1874
1854
1875
# TODO: CHECK DTYPE?
@@ -1859,8 +1880,12 @@ def _simple_blockify(tuples, dtype) -> List[Block]:
1859
1880
return [block ]
1860
1881
1861
1882
1862
- def _multi_blockify (tuples , dtype : Optional [Dtype ] = None ):
1883
+ def _multi_blockify (tuples , dtype : Optional [DtypeObj ] = None , consolidate : bool = True ):
1863
1884
""" return an array of blocks that potentially have different dtypes """
1885
+
1886
+ if not consolidate :
1887
+ return _tuples_to_blocks_no_consolidate (tuples , dtype = dtype )
1888
+
1864
1889
# group by dtype
1865
1890
grouper = itertools .groupby (tuples , lambda x : x [1 ].dtype )
1866
1891
@@ -1880,6 +1905,18 @@ def _multi_blockify(tuples, dtype: Optional[Dtype] = None):
1880
1905
return new_blocks
1881
1906
1882
1907
1908
+ def _tuples_to_blocks_no_consolidate (tuples , dtype : Optional [DtypeObj ]) -> List [Block ]:
1909
+ # tuples produced within _form_blocks are of the form (placement, whatever, array)
1910
+ if dtype is not None :
1911
+ return [
1912
+ new_block (
1913
+ np .atleast_2d (x [1 ].astype (dtype , copy = False )), placement = x [0 ], ndim = 2
1914
+ )
1915
+ for x in tuples
1916
+ ]
1917
+ return [new_block (np .atleast_2d (x [1 ]), placement = x [0 ], ndim = 2 ) for x in tuples ]
1918
+
1919
+
1883
1920
def _stack_arrays (tuples , dtype : np .dtype ):
1884
1921
1885
1922
placement , arrays = zip (* tuples )
0 commit comments