Skip to content

Commit 6a78014

Browse files
minggliPingviinituutti
authored andcommitted
BUG: clip doesn't preserve dtype by column (pandas-dev#24458)
1 parent 4c369f1 commit 6a78014

File tree

3 files changed

+16
-16
lines changed

3 files changed

+16
-16
lines changed

doc/source/whatsnew/v0.24.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,7 @@ Conversion
14091409
^^^^^^^^^^
14101410

14111411
- Bug in :meth:`DataFrame.combine_first` in which column types were unexpectedly converted to float (:issue:`20699`)
1412+
- Bug in :meth:`DataFrame.clip` in which column types are not preserved and casted to float (:issue:`24162`)
14121413

14131414
Strings
14141415
^^^^^^^

pandas/core/generic.py

+7-14
Original file line numberDiff line numberDiff line change
@@ -7132,19 +7132,13 @@ def _clip_with_scalar(self, lower, upper, inplace=False):
71327132
(upper is not None and np.any(isna(upper)))):
71337133
raise ValueError("Cannot use an NA value as a clip threshold")
71347134

7135-
result = self.values
7136-
mask = isna(result)
7137-
7138-
with np.errstate(all='ignore'):
7139-
if upper is not None:
7140-
result = np.where(result >= upper, upper, result)
7141-
if lower is not None:
7142-
result = np.where(result <= lower, lower, result)
7143-
if np.any(mask):
7144-
result[mask] = np.nan
7145-
7146-
axes_dict = self._construct_axes_dict()
7147-
result = self._constructor(result, **axes_dict).__finalize__(self)
7135+
result = self
7136+
if upper is not None:
7137+
subset = self.le(upper, axis=None) | isna(result)
7138+
result = result.where(subset, upper, axis=None, inplace=False)
7139+
if lower is not None:
7140+
subset = self.ge(lower, axis=None) | isna(result)
7141+
result = result.where(subset, lower, axis=None, inplace=False)
71487142

71497143
if inplace:
71507144
self._update_inplace(result)
@@ -7153,7 +7147,6 @@ def _clip_with_scalar(self, lower, upper, inplace=False):
71537147

71547148
def _clip_with_one_bound(self, threshold, method, axis, inplace):
71557149

7156-
inplace = validate_bool_kwarg(inplace, 'inplace')
71577150
if axis is not None:
71587151
axis = self._get_axis_number(axis)
71597152

pandas/tests/frame/test_analytics.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -1836,7 +1836,6 @@ def test_pct_change(self):
18361836
tm.assert_frame_equal(result, expected)
18371837

18381838
# Clip
1839-
18401839
def test_clip(self, float_frame):
18411840
median = float_frame.median().median()
18421841
original = float_frame.copy()
@@ -1895,10 +1894,17 @@ def test_clip_mixed_numeric(self):
18951894
df = DataFrame({'A': [1, 2, 3],
18961895
'B': [1., np.nan, 3.]})
18971896
result = df.clip(1, 2)
1898-
expected = DataFrame({'A': [1, 2, 2.],
1897+
expected = DataFrame({'A': [1, 2, 2],
18991898
'B': [1., np.nan, 2.]})
19001899
tm.assert_frame_equal(result, expected, check_like=True)
19011900

1901+
# GH 24162, clipping now preserves numeric types per column
1902+
df = DataFrame([[1, 2, 3.4], [3, 4, 5.6]],
1903+
columns=['foo', 'bar', 'baz'])
1904+
expected = df.dtypes
1905+
result = df.clip(upper=3).dtypes
1906+
tm.assert_series_equal(result, expected)
1907+
19021908
@pytest.mark.parametrize("inplace", [True, False])
19031909
def test_clip_against_series(self, inplace):
19041910
# GH 6966

0 commit comments

Comments
 (0)