Skip to content

Commit 51ac022

Browse files
committed
BUG: ensure coercing scalars to when setting as numpy
closes #12850 Author: Jeff Reback <[email protected]> Closes #12852 from jreback/fix and squashes the following commits: ca90fcc [Jeff Reback] BUG: ensure coercing scalars to when setting as numpy
1 parent 083db2a commit 51ac022

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed

pandas/core/common.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ def _infer_dtype_from_scalar(val):
473473
dtype = np.dtype('M8[ns]')
474474

475475
elif isinstance(val, (np.timedelta64, timedelta)):
476-
val = tslib.convert_to_timedelta(val, 'ns')
476+
val = lib.Timedelta(val).value
477477
dtype = np.dtype('m8[ns]')
478478

479479
elif is_bool(val):
@@ -826,6 +826,7 @@ def trans(x): # noqa
826826

827827
def _maybe_convert_string_to_object(values):
828828
"""
829+
829830
Convert string-like and string-like array to convert object dtype.
830831
This is to avoid numpy to handle the array as str dtype.
831832
"""
@@ -837,6 +838,20 @@ def _maybe_convert_string_to_object(values):
837838
return values
838839

839840

841+
def _maybe_convert_scalar(values):
842+
"""
843+
Convert a python scalar to the appropriate numpy dtype if possible
844+
This avoids numpy directly converting according to platform preferences
845+
"""
846+
if lib.isscalar(values):
847+
dtype, values = _infer_dtype_from_scalar(values)
848+
try:
849+
values = dtype(values)
850+
except TypeError:
851+
pass
852+
return values
853+
854+
840855
def _lcd_dtypes(a_dtype, b_dtype):
841856
""" return the lcd dtype to hold these types """
842857

pandas/core/internals.py

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
is_datetime64_dtype, is_datetimetz, is_sparse,
1919
array_equivalent, _is_na_compat,
2020
_maybe_convert_string_to_object,
21+
_maybe_convert_scalar,
2122
is_categorical, is_datetimelike_v_numeric,
2223
is_numeric_v_string_like, is_internal_type)
2324
import pandas.core.algorithms as algos
@@ -1201,6 +1202,7 @@ def where(self, other, cond, align=True, raise_on_error=True,
12011202
"like")
12021203

12031204
other = _maybe_convert_string_to_object(other)
1205+
other = _maybe_convert_scalar(other)
12041206

12051207
# our where function
12061208
def func(cond, values, other):

pandas/tests/test_common.py

+30
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,36 @@ def test_maybe_convert_string_to_array(self):
770770
tm.assert_numpy_array_equal(result, np.array(['x', 2], dtype=object))
771771
self.assertTrue(result.dtype == object)
772772

773+
def test_maybe_convert_scalar(self):
774+
775+
# pass thru
776+
result = com._maybe_convert_scalar('x')
777+
self.assertEqual(result, 'x')
778+
result = com._maybe_convert_scalar(np.array([1]))
779+
self.assertEqual(result, np.array([1]))
780+
781+
# leave scalar dtype
782+
result = com._maybe_convert_scalar(np.int64(1))
783+
self.assertEqual(result, np.int64(1))
784+
result = com._maybe_convert_scalar(np.int32(1))
785+
self.assertEqual(result, np.int32(1))
786+
result = com._maybe_convert_scalar(np.float32(1))
787+
self.assertEqual(result, np.float32(1))
788+
result = com._maybe_convert_scalar(np.int64(1))
789+
self.assertEqual(result, np.float64(1))
790+
791+
# coerce
792+
result = com._maybe_convert_scalar(1)
793+
self.assertEqual(result, np.int64(1))
794+
result = com._maybe_convert_scalar(1.0)
795+
self.assertEqual(result, np.float64(1))
796+
result = com._maybe_convert_scalar(pd.Timestamp('20130101'))
797+
self.assertEqual(result, pd.Timestamp('20130101').value)
798+
result = com._maybe_convert_scalar(datetime(2013, 1, 1))
799+
self.assertEqual(result, pd.Timestamp('20130101').value)
800+
result = com._maybe_convert_scalar(pd.Timedelta('1 day 1 min'))
801+
self.assertEqual(result, pd.Timedelta('1 day 1 min').value)
802+
773803

774804
class TestConvert(tm.TestCase):
775805

0 commit comments

Comments
 (0)