98 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
"""
 | 
						|
This is a pseudo-public API for downstream libraries.  We ask that downstream
 | 
						|
authors
 | 
						|
 | 
						|
1) Try to avoid using internals directly altogether, and failing that,
 | 
						|
2) Use only functions exposed here (or in core.internals)
 | 
						|
 | 
						|
"""
 | 
						|
from __future__ import annotations
 | 
						|
 | 
						|
import numpy as np
 | 
						|
 | 
						|
from pandas._libs.internals import BlockPlacement
 | 
						|
from pandas._typing import Dtype
 | 
						|
 | 
						|
from pandas.core.dtypes.common import (
 | 
						|
    is_datetime64tz_dtype,
 | 
						|
    is_period_dtype,
 | 
						|
    pandas_dtype,
 | 
						|
)
 | 
						|
 | 
						|
from pandas.core.arrays import DatetimeArray
 | 
						|
from pandas.core.construction import extract_array
 | 
						|
from pandas.core.internals.blocks import (
 | 
						|
    Block,
 | 
						|
    DatetimeTZBlock,
 | 
						|
    ExtensionBlock,
 | 
						|
    check_ndim,
 | 
						|
    ensure_block_shape,
 | 
						|
    extract_pandas_array,
 | 
						|
    get_block_type,
 | 
						|
    maybe_coerce_values,
 | 
						|
)
 | 
						|
 | 
						|
 | 
						|
def make_block(
 | 
						|
    values, placement, klass=None, ndim=None, dtype: Dtype | None = None
 | 
						|
) -> Block:
 | 
						|
    """
 | 
						|
    This is a pseudo-public analogue to blocks.new_block.
 | 
						|
 | 
						|
    We ask that downstream libraries use this rather than any fully-internal
 | 
						|
    APIs, including but not limited to:
 | 
						|
 | 
						|
    - core.internals.blocks.make_block
 | 
						|
    - Block.make_block
 | 
						|
    - Block.make_block_same_class
 | 
						|
    - Block.__init__
 | 
						|
    """
 | 
						|
    if dtype is not None:
 | 
						|
        dtype = pandas_dtype(dtype)
 | 
						|
 | 
						|
    values, dtype = extract_pandas_array(values, dtype, ndim)
 | 
						|
 | 
						|
    if klass is ExtensionBlock and is_period_dtype(values.dtype):
 | 
						|
        # GH-44681 changed PeriodArray to be stored in the 2D
 | 
						|
        # NDArrayBackedExtensionBlock instead of ExtensionBlock
 | 
						|
        # -> still allow ExtensionBlock to be passed in this case for back compat
 | 
						|
        klass = None
 | 
						|
 | 
						|
    if klass is None:
 | 
						|
        dtype = dtype or values.dtype
 | 
						|
        klass = get_block_type(dtype)
 | 
						|
 | 
						|
    elif klass is DatetimeTZBlock and not is_datetime64tz_dtype(values.dtype):
 | 
						|
        # pyarrow calls get here
 | 
						|
        values = DatetimeArray._simple_new(values, dtype=dtype)
 | 
						|
 | 
						|
    if not isinstance(placement, BlockPlacement):
 | 
						|
        placement = BlockPlacement(placement)
 | 
						|
 | 
						|
    ndim = maybe_infer_ndim(values, placement, ndim)
 | 
						|
    if is_datetime64tz_dtype(values.dtype) or is_period_dtype(values.dtype):
 | 
						|
        # GH#41168 ensure we can pass 1D dt64tz values
 | 
						|
        # More generally, any EA dtype that isn't is_1d_only_ea_dtype
 | 
						|
        values = extract_array(values, extract_numpy=True)
 | 
						|
        values = ensure_block_shape(values, ndim)
 | 
						|
 | 
						|
    check_ndim(values, placement, ndim)
 | 
						|
    values = maybe_coerce_values(values)
 | 
						|
    return klass(values, ndim=ndim, placement=placement)
 | 
						|
 | 
						|
 | 
						|
def maybe_infer_ndim(values, placement: BlockPlacement, ndim: int | None) -> int:
 | 
						|
    """
 | 
						|
    If `ndim` is not provided, infer it from placment and values.
 | 
						|
    """
 | 
						|
    if ndim is None:
 | 
						|
        # GH#38134 Block constructor now assumes ndim is not None
 | 
						|
        if not isinstance(values.dtype, np.dtype):
 | 
						|
            if len(placement) != 1:
 | 
						|
                ndim = 1
 | 
						|
            else:
 | 
						|
                ndim = 2
 | 
						|
        else:
 | 
						|
            ndim = values.ndim
 | 
						|
    return ndim
 |