-
-
Notifications
You must be signed in to change notification settings - Fork 18k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use align_method in comp_method_FRAME #22880
Changes from 12 commits
b6e3ed9
3baa31e
aa9ca8f
92513ca
1090333
fb5b16e
499e139
73cda15
9c40569
87df9c4
b316336
1d29857
a3c8f21
46a4e95
826f2c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -487,6 +487,88 @@ Previous Behavior: | |
0 | ||
0 NaT | ||
|
||
.. _whatsnew_0240.api.dataframe_cmp_broadcasting: | ||
|
||
DataFrame Comparison Operations Broadcasting Changes | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
Previously, the broadcasting behavior of :class:`DataFrame` comparison | ||
operations (``==``, ``!=``, ...) was inconsistent with the behavior of | ||
arithmetic operations (``+``, ``-``, ...). The behavior of the comparison | ||
operations has been changed to match the arithmetic operations in these cases. | ||
(:issue:`22880`) | ||
|
||
The affected cases are: | ||
|
||
- operating against a 2-dimensional ``np.ndarray`` with either 1 row or 1 column will now broadcast the same way a ``np.ndarray`` would (:issue:`23000`). | ||
- a list or tuple with length matching the number of rows in the :class:`DataFrame` will now raise ``ValueError`` instead of operating column-by-column (:issue:`22880`. | ||
- a list or tuple with length matching the number of columns in the :class:`DataFrame` will now operate row-by-row instead of raising ``ValueError`` (:issue:`22880`). | ||
|
||
Previous Behavior: | ||
|
||
.. code-block:: ipython | ||
|
||
In [3]: arr = np.arange(6).reshape(3, 2) | ||
In [4]: df = pd.DataFrame(arr) | ||
|
||
In [5]: df == arr[[0], :] | ||
...: # comparison previously broadcast where arithmetic would raise | ||
Out[5]: | ||
0 1 | ||
0 True True | ||
1 False False | ||
2 False False | ||
In [6]: df + arr[[0], :] | ||
... | ||
ValueError: Unable to coerce to DataFrame, shape must be (3, 2): given (1, 2) | ||
|
||
In [7]: df == (1, 2) | ||
...: # length matches number of columns; | ||
...: # comparison previously raised where arithmetic would broadcast | ||
... | ||
ValueError: Invalid broadcasting comparison [(1, 2)] with block values | ||
In [8]: df + (1, 2) | ||
Out[8]: | ||
0 1 | ||
0 1 3 | ||
1 3 5 | ||
2 5 7 | ||
|
||
In [9]: df == (1, 2, 3) | ||
...: # length matches number of rows | ||
...: # comparison previously broadcast where arithmetic would raise | ||
Out[9]: | ||
0 1 | ||
0 False True | ||
1 True False | ||
2 False False | ||
In [10]: df + (1, 2, 3) | ||
... | ||
ValueError: Unable to coerce to Series, length must be 2: given 3 | ||
|
||
*Current Behavior*: | ||
|
||
.. ipython:: python | ||
:okexcept: | ||
|
||
arr = np.arange(6).reshape(3, 2) | ||
df = pd.DataFrame(arr) | ||
|
||
.. ipython:: python | ||
# comparison and arithmetic both broadcast | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd prefer you make the comments actual sentences here, which is pretty easy when you already have the blocks. |
||
df == arr[[0], :] | ||
df + arr[[0], :] | ||
|
||
.. ipython:: python | ||
# comparison and arithmetic broadcast the same way | ||
df == (1, 2) | ||
df + (1, 2) | ||
|
||
.. ipython:: python | ||
:okexcept: | ||
# comparison and arithmetic both raise | ||
df == (1, 2, 3) | ||
df + (1, 2, 3) | ||
|
||
|
||
.. _whatsnew_0240.api.dataframe_arithmetic_broadcasting: | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,15 +48,19 @@ def test_mixed_comparison(self): | |
assert result.all().all() | ||
|
||
def test_df_boolean_comparison_error(self): | ||
# GH 4576 | ||
# GH#4576, GH#22880 | ||
# boolean comparisons with a tuple/list give unexpected results | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you change this comment |
||
df = pd.DataFrame(np.arange(6).reshape((3, 2))) | ||
|
||
# not shape compatible | ||
with pytest.raises(ValueError): | ||
df == (2, 2) | ||
with pytest.raises(ValueError): | ||
df == [2, 2] | ||
expected = pd.DataFrame([[False, False], | ||
[True, False], | ||
[False, False]]) | ||
|
||
result = df == (2, 2) | ||
tm.assert_frame_equal(result, expected) | ||
|
||
result = df == [2, 2] | ||
tm.assert_frame_equal(result, expected) | ||
|
||
def test_df_float_none_comparison(self): | ||
df = pd.DataFrame(np.random.randn(8, 3), index=range(8), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -752,8 +752,9 @@ def test_comp(func): | |
result = func(df1, df2) | ||
tm.assert_numpy_array_equal(result.values, | ||
func(df1.values, df2.values)) | ||
|
||
with tm.assert_raises_regex(ValueError, | ||
'Wrong number of dimensions'): | ||
'dim must be <= 2'): | ||
func(df1, ndim_5) | ||
|
||
result2 = func(self.simple, row) | ||
|
@@ -804,12 +805,15 @@ def test_boolean_comparison(self): | |
result = df.values > b | ||
assert_numpy_array_equal(result, expected.values) | ||
|
||
result = df > l | ||
assert_frame_equal(result, expected) | ||
with pytest.raises(ValueError): | ||
# wrong shape | ||
df > l | ||
|
||
result = df > tup | ||
assert_frame_equal(result, expected) | ||
with pytest.raises(ValueError): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you assert the error messages in these |
||
# wrong shape | ||
result = df > tup | ||
|
||
# broadcasts like ndarray (GH#23000) | ||
result = df > b_r | ||
assert_frame_equal(result, expected) | ||
|
||
|
@@ -827,12 +831,13 @@ def test_boolean_comparison(self): | |
result = df == b | ||
assert_frame_equal(result, expected) | ||
|
||
result = df == l | ||
assert_frame_equal(result, expected) | ||
with pytest.raises(ValueError): | ||
result = df == l | ||
|
||
result = df == tup | ||
assert_frame_equal(result, expected) | ||
with pytest.raises(ValueError): | ||
result = df == tup | ||
|
||
# broadcasts like ndarray (GH#23000) | ||
result = df == b_r | ||
assert_frame_equal(result, expected) | ||
|
||
|
@@ -850,11 +855,11 @@ def test_boolean_comparison(self): | |
expected.index = df.index | ||
expected.columns = df.columns | ||
|
||
result = df == l | ||
assert_frame_equal(result, expected) | ||
with pytest.raises(ValueError): | ||
result = df == l | ||
|
||
result = df == tup | ||
assert_frame_equal(result, expected) | ||
with pytest.raises(ValueError): | ||
result = df == tup | ||
|
||
def test_combine_generic(self): | ||
df1 = self.frame | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will nee d an
:okexcept
here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can also remove the
In []
prefixes. And hopefully the block continues running when there's an exception in anokexcept
.