Skip to content

Commit

Permalink
REF: handle non-list_like cases upfront in sanitize_array (#38563)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrockmendel committed Dec 18, 2020
1 parent e68016c commit cec2f5f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 23 deletions.
56 changes: 34 additions & 22 deletions pandas/core/construction.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,11 @@ def sanitize_array(
# extract ndarray or ExtensionArray, ensure we have no PandasArray
data = extract_array(data, extract_numpy=True)

if isinstance(data, np.ndarray) and data.ndim == 0:
if dtype is None:
dtype = data.dtype
data = lib.item_from_zerodim(data)

# GH#846
if isinstance(data, np.ndarray):

Expand All @@ -462,7 +467,7 @@ def sanitize_array(
else:
subarr = np.array(data, copy=False)
else:
# we will try to copy be-definition here
# we will try to copy by-definition here
subarr = _try_cast(data, dtype, copy, raise_cast_failure)

elif isinstance(data, ABCExtensionArray):
Expand Down Expand Up @@ -491,30 +496,16 @@ def sanitize_array(
# GH#16804
arr = np.arange(data.start, data.stop, data.step, dtype="int64")
subarr = _try_cast(arr, dtype, copy, raise_cast_failure)
elif lib.is_scalar(data) and index is not None and dtype is not None:

elif not is_list_like(data):
if index is None:
raise ValueError("index must be specified when data is not list-like")
subarr = construct_1d_arraylike_from_scalar(data, len(index), dtype)

else:
subarr = _try_cast(data, dtype, copy, raise_cast_failure)

# scalar like, GH
if getattr(subarr, "ndim", 0) == 0:
if isinstance(data, list): # pragma: no cover
subarr = np.array(data, dtype=object)
elif index is not None:
subarr = construct_1d_arraylike_from_scalar(data, len(index), dtype)

else:
return subarr.item()

# the result that we want
elif subarr.ndim == 1:
subarr = _maybe_repeat(subarr, index)

elif subarr.ndim > 1:
if isinstance(data, np.ndarray):
raise ValueError("Data must be 1-dimensional")
else:
subarr = com.asarray_tuplesafe(data, dtype=dtype)
subarr = _sanitize_ndim(subarr, data, dtype, index)

if not (is_extension_array_dtype(subarr.dtype) or is_extension_array_dtype(dtype)):
subarr = _sanitize_str_dtypes(subarr, data, dtype, copy)
Expand All @@ -528,6 +519,27 @@ def sanitize_array(
return subarr


def _sanitize_ndim(
result: ArrayLike, data, dtype: Optional[DtypeObj], index: Optional[Index]
) -> ArrayLike:
"""
Ensure we have a 1-dimensional result array.
"""
if getattr(result, "ndim", 0) == 0:
raise ValueError("result should be arraylike with ndim > 0")

elif result.ndim == 1:
# the result that we want
result = _maybe_repeat(result, index)

elif result.ndim > 1:
if isinstance(data, np.ndarray):
raise ValueError("Data must be 1-dimensional")
else:
result = com.asarray_tuplesafe(data, dtype=dtype)
return result


def _sanitize_str_dtypes(
result: np.ndarray, data, dtype: Optional[DtypeObj], copy: bool
) -> np.ndarray:
Expand Down Expand Up @@ -565,7 +577,7 @@ def _try_cast(arr, dtype: Optional[DtypeObj], copy: bool, raise_cast_failure: bo
Parameters
----------
arr : ndarray, scalar, list, tuple, iterator (catchall)
arr : ndarray, list, tuple, iterator (catchall)
Excludes: ExtensionArray, Series, Index.
dtype : np.dtype, ExtensionDtype or None
copy : bool
Expand Down
5 changes: 4 additions & 1 deletion pandas/core/dtypes/cast.py
Original file line number Diff line number Diff line change
Expand Up @@ -1543,7 +1543,10 @@ def construct_1d_arraylike_from_scalar(
"""

if dtype is None:
dtype, value = infer_dtype_from_scalar(value, pandas_dtype=True)
try:
dtype, value = infer_dtype_from_scalar(value, pandas_dtype=True)
except OutOfBoundsDatetime:
dtype = np.dtype(object)

if is_extension_array_dtype(dtype):
cls = dtype.construct_array_type()
Expand Down

0 comments on commit cec2f5f

Please sign in to comment.