From 960554749d054393104348fe5111aaf27234980d Mon Sep 17 00:00:00 2001 From: cgangwar11 Date: Fri, 28 Dec 2018 19:01:31 +0530 Subject: [PATCH 1/5] BUG GH20911 Passing threshold as it is instead of numpy array to preserve the columns order. --- pandas/core/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 65b219cc57f3a..ce7a866496964 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -7172,7 +7172,7 @@ def _clip_with_one_bound(self, threshold, method, axis, inplace): if isinstance(self, ABCSeries): threshold = pd.Series(threshold, index=self.index) else: - threshold = _align_method_FRAME(self, np.asarray(threshold), + threshold = _align_method_FRAME(self, threshold, axis) return self.where(subset, threshold, axis=axis, inplace=inplace) From 3dabccfae7f110b754cf42b281a736ea20357200 Mon Sep 17 00:00:00 2001 From: cgangwar11 Date: Fri, 28 Dec 2018 19:09:39 +0530 Subject: [PATCH 2/5] TST GH20911 Additional test cases to validate the fix --- pandas/tests/frame/test_analytics.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pandas/tests/frame/test_analytics.py b/pandas/tests/frame/test_analytics.py index 88262220015c7..687fcbcd5105b 100644 --- a/pandas/tests/frame/test_analytics.py +++ b/pandas/tests/frame/test_analytics.py @@ -1964,6 +1964,13 @@ def test_clip_against_frame(self, axis): tm.assert_frame_equal(clipped_df[lb_mask], lb[lb_mask]) tm.assert_frame_equal(clipped_df[ub_mask], ub[ub_mask]) tm.assert_frame_equal(clipped_df[mask], df[mask]) + # GH 20911, clipping now preserves types + df1 = DataFrame(np.random.randn(1000,4), columns=['A', 'B','C','D']) + df2 = DataFrame(np.random.randn(1000,4), columns=['D', 'A','B','C']) + + res1 = df1.clip(lower=0,upper=df2) + res2 = df1.clip(lower=0,upper=df2[df1.columns]) + tm.assert_frame_equal(res1,res2) def test_clip_with_na_args(self, float_frame): """Should process np.nan argument as None """ From cf86de440600eb0d8533756d83414b754629fdc7 Mon Sep 17 00:00:00 2001 From: cgangwar11 Date: Fri, 28 Dec 2018 20:16:42 +0530 Subject: [PATCH 3/5] Seperated test case and solved the linting errors. --- pandas/tests/frame/test_analytics.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/pandas/tests/frame/test_analytics.py b/pandas/tests/frame/test_analytics.py index 687fcbcd5105b..31ebc82ea2f65 100644 --- a/pandas/tests/frame/test_analytics.py +++ b/pandas/tests/frame/test_analytics.py @@ -1964,13 +1964,14 @@ def test_clip_against_frame(self, axis): tm.assert_frame_equal(clipped_df[lb_mask], lb[lb_mask]) tm.assert_frame_equal(clipped_df[ub_mask], ub[ub_mask]) tm.assert_frame_equal(clipped_df[mask], df[mask]) - # GH 20911, clipping now preserves types - df1 = DataFrame(np.random.randn(1000,4), columns=['A', 'B','C','D']) - df2 = DataFrame(np.random.randn(1000,4), columns=['D', 'A','B','C']) - - res1 = df1.clip(lower=0,upper=df2) - res2 = df1.clip(lower=0,upper=df2[df1.columns]) - tm.assert_frame_equal(res1,res2) + + def test_clip_against_unordered_columns(self): + # GH 20911 + df1 = DataFrame(np.random.randn(1000, 4), columns=['A', 'B', 'C', 'D']) + df2 = DataFrame(np.random.randn(1000, 4), columns=['D', 'A', 'B', 'C']) + result = df1.clip(lower=0, upper=df2) + expected = df1.clip(lower=0, upper=df2[df1.columns]) + tm.assert_frame_equal(result, expected) def test_clip_with_na_args(self, float_frame): """Should process np.nan argument as None """ From 2ddb60f58bd5b9dbf0992b3deb2b1b935619bed2 Mon Sep 17 00:00:00 2001 From: cgangwar11 Date: Sat, 29 Dec 2018 03:52:30 +0530 Subject: [PATCH 4/5] Added test cases for lower cliping as well as combined lower and upper cliping --- pandas/tests/frame/test_analytics.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/pandas/tests/frame/test_analytics.py b/pandas/tests/frame/test_analytics.py index 8cfb42d7442d6..6f68828b94a84 100644 --- a/pandas/tests/frame/test_analytics.py +++ b/pandas/tests/frame/test_analytics.py @@ -1975,9 +1975,17 @@ def test_clip_against_unordered_columns(self): # GH 20911 df1 = DataFrame(np.random.randn(1000, 4), columns=['A', 'B', 'C', 'D']) df2 = DataFrame(np.random.randn(1000, 4), columns=['D', 'A', 'B', 'C']) - result = df1.clip(lower=0, upper=df2) - expected = df1.clip(lower=0, upper=df2[df1.columns]) - tm.assert_frame_equal(result, expected) + df3 = DataFrame(df2.values - 1, columns=['B', 'D', 'C', 'A']) + result_upper = df1.clip(lower=0, upper=df2) + expected_upper = df1.clip(lower=0, upper=df2[df1.columns]) + result_lower = df1.clip(lower=df3, upper=3) + expected_lower = df1.clip(lower=df3[df1.columns], upper=3) + result_lower_upper = df1.clip(lower=df3, upper=df2) + expected_lower_upper = df1.clip(lower=df3[df1.columns], + upper=df2[df1.columns]) + tm.assert_frame_equal(result_upper, expected_upper) + tm.assert_frame_equal(result_lower, expected_lower) + tm.assert_frame_equal(result_lower_upper, expected_lower_upper) def test_clip_with_na_args(self, float_frame): """Should process np.nan argument as None """ From 9ee4b89ad38869581b190fd9bf591c9a8a92db28 Mon Sep 17 00:00:00 2001 From: cgangwar11 Date: Sat, 29 Dec 2018 04:26:10 +0530 Subject: [PATCH 5/5] whatsnew note added --- doc/source/whatsnew/v0.24.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index 0b0ba7aab49aa..3f1c2343d8130 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -1412,6 +1412,7 @@ Conversion - Bug in :meth:`DataFrame.combine_first` in which column types were unexpectedly converted to float (:issue:`20699`) - Bug in :meth:`DataFrame.clip` in which column types are not preserved and casted to float (:issue:`24162`) +- Bug in :meth:`DataFrame.clip` when order of columns of dataframes doesn't match, result observed is wrong in numeric values (:issue:`20911`) Strings ^^^^^^^