DEPR: raise deprecation warning in numpy ufuncs on DataFrames if not … · pandas-dev/pandas@ff628b1 (original) (raw)
1
1
`import numpy as np
`
2
2
`import pytest
`
3
3
``
``
4
`+
import pandas.util._test_decorators as td
`
``
5
+
4
6
`import pandas as pd
`
5
7
`import pandas._testing as tm
`
6
8
``
`@@ -78,12 +80,19 @@ def test_binary_input_aligns_columns(request, dtype_a, dtype_b):
`
78
80
`dtype_b["C"] = dtype_b.pop("B")
`
79
81
``
80
82
`df2 = pd.DataFrame({"A": [1, 2], "C": [3, 4]}).astype(dtype_b)
`
81
``
`-
result = np.heaviside(df1, df2)
`
82
``
`-
expected = np.heaviside(
`
83
``
`-
np.array([[1, 3, np.nan], [2, 4, np.nan]]),
`
84
``
`-
np.array([[1, np.nan, 3], [2, np.nan, 4]]),
`
85
``
`-
)
`
86
``
`-
expected = pd.DataFrame(expected, index=[0, 1], columns=["A", "B", "C"])
`
``
83
`+
with tm.assert_produces_warning(FutureWarning):
`
``
84
`+
result = np.heaviside(df1, df2)
`
``
85
`+
Expected future behaviour:
`
``
86
`+
expected = np.heaviside(
`
``
87
`+
np.array([[1, 3, np.nan], [2, 4, np.nan]]),
`
``
88
`+
np.array([[1, np.nan, 3], [2, np.nan, 4]]),
`
``
89
`+
)
`
``
90
`+
expected = pd.DataFrame(expected, index=[0, 1], columns=["A", "B", "C"])
`
``
91
`+
expected = pd.DataFrame([[1.0, 1.0], [1.0, 1.0]], columns=["A", "B"])
`
``
92
`+
tm.assert_frame_equal(result, expected)
`
``
93
+
``
94
`+
ensure the expected is the same when applying with numpy array
`
``
95
`+
result = np.heaviside(df1, df2.values)
`
87
96
`tm.assert_frame_equal(result, expected)
`
88
97
``
89
98
``
`@@ -97,23 +106,35 @@ def test_binary_input_aligns_index(request, dtype):
`
97
106
` )
`
98
107
`df1 = pd.DataFrame({"A": [1, 2], "B": [3, 4]}, index=["a", "b"]).astype(dtype)
`
99
108
`df2 = pd.DataFrame({"A": [1, 2], "B": [3, 4]}, index=["a", "c"]).astype(dtype)
`
100
``
`-
result = np.heaviside(df1, df2)
`
101
``
`-
expected = np.heaviside(
`
102
``
`-
np.array([[1, 3], [3, 4], [np.nan, np.nan]]),
`
103
``
`-
np.array([[1, 3], [np.nan, np.nan], [3, 4]]),
`
``
109
`+
with tm.assert_produces_warning(FutureWarning):
`
``
110
`+
result = np.heaviside(df1, df2)
`
``
111
`+
Expected future behaviour:
`
``
112
`+
expected = np.heaviside(
`
``
113
`+
np.array([[1, 3], [3, 4], [np.nan, np.nan]]),
`
``
114
`+
np.array([[1, 3], [np.nan, np.nan], [3, 4]]),
`
``
115
`+
)
`
``
116
`+
# TODO(FloatArray): this will be Float64Dtype.
`
``
117
`+
expected = pd.DataFrame(expected, index=["a", "b", "c"], columns=["A", "B"])
`
``
118
`+
expected = pd.DataFrame(
`
``
119
`+
[[1.0, 1.0], [1.0, 1.0]], columns=["A", "B"], index=["a", "b"]
`
104
120
` )
`
105
``
`-
TODO(FloatArray): this will be Float64Dtype.
`
106
``
`-
expected = pd.DataFrame(expected, index=["a", "b", "c"], columns=["A", "B"])
`
``
121
`+
tm.assert_frame_equal(result, expected)
`
``
122
+
``
123
`+
ensure the expected is the same when applying with numpy array
`
``
124
`+
result = np.heaviside(df1, df2.values)
`
107
125
`tm.assert_frame_equal(result, expected)
`
108
126
``
109
127
``
``
128
`+
@pytest.mark.filterwarnings("ignore:Calling a ufunc on non-aligned:FutureWarning")
`
110
129
`def test_binary_frame_series_raises():
`
111
130
`# We don't currently implement
`
112
131
`df = pd.DataFrame({"A": [1, 2]})
`
113
``
`-
with pytest.raises(NotImplementedError, match="logaddexp"):
`
``
132
`+
with pytest.raises(NotImplementedError, match="logaddexp"):
`
``
133
`+
with pytest.raises(ValueError, match=""):
`
114
134
`np.logaddexp(df, df["A"])
`
115
135
``
116
``
`-
with pytest.raises(NotImplementedError, match="logaddexp"):
`
``
136
`+
with pytest.raises(NotImplementedError, match="logaddexp"):
`
``
137
`+
with pytest.raises(ValueError, match=""):
`
117
138
`np.logaddexp(df["A"], df)
`
118
139
``
119
140
``
`@@ -142,3 +163,92 @@ def test_frame_outer_deprecated():
`
142
163
`df = pd.DataFrame({"A": [1, 2]})
`
143
164
`with tm.assert_produces_warning(FutureWarning):
`
144
165
`np.subtract.outer(df, df)
`
``
166
+
``
167
+
``
168
`+
def test_alignment_deprecation():
`
``
169
`+
https://github.com/pandas-dev/pandas/issues/39184
`
``
170
`+
df1 = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
`
``
171
`+
df2 = pd.DataFrame({"b": [1, 2, 3], "c": [4, 5, 6]})
`
``
172
`+
s1 = pd.Series([1, 2], index=["a", "b"])
`
``
173
`+
s2 = pd.Series([1, 2], index=["b", "c"])
`
``
174
+
``
175
`+
binary dataframe / dataframe
`
``
176
`+
expected = pd.DataFrame({"a": [2, 4, 6], "b": [8, 10, 12]})
`
``
177
+
``
178
`+
with tm.assert_produces_warning(None):
`
``
179
`+
aligned -> no warning!
`
``
180
`+
result = np.add(df1, df1)
`
``
181
`+
tm.assert_frame_equal(result, expected)
`
``
182
+
``
183
`+
with tm.assert_produces_warning(FutureWarning):
`
``
184
`+
non-aligned -> warns
`
``
185
`+
result = np.add(df1, df2)
`
``
186
`+
tm.assert_frame_equal(result, expected)
`
``
187
+
``
188
`+
result = np.add(df1, df2.values)
`
``
189
`+
tm.assert_frame_equal(result, expected)
`
``
190
+
``
191
`+
result = np.add(df1.values, df2)
`
``
192
`+
expected = pd.DataFrame({"b": [2, 4, 6], "c": [8, 10, 12]})
`
``
193
`+
tm.assert_frame_equal(result, expected)
`
``
194
+
``
195
`+
binary dataframe / series
`
``
196
`+
expected = pd.DataFrame({"a": [2, 3, 4], "b": [6, 7, 8]})
`
``
197
+
``
198
`+
with tm.assert_produces_warning(None):
`
``
199
`+
aligned -> no warning!
`
``
200
`+
result = np.add(df1, s1)
`
``
201
`+
tm.assert_frame_equal(result, expected)
`
``
202
+
``
203
`+
with tm.assert_produces_warning(FutureWarning):
`
``
204
`+
result = np.add(df1, s2)
`
``
205
`+
tm.assert_frame_equal(result, expected)
`
``
206
+
``
207
`+
with tm.assert_produces_warning(FutureWarning):
`
``
208
`+
result = np.add(s2, df1)
`
``
209
`+
tm.assert_frame_equal(result, expected)
`
``
210
+
``
211
`+
result = np.add(df1, s2.values)
`
``
212
`+
tm.assert_frame_equal(result, expected)
`
``
213
+
``
214
+
``
215
`+
@td.skip_if_no("numba", "0.46.0")
`
``
216
`+
def test_alignment_deprecation_many_inputs():
`
``
217
`+
https://github.com/pandas-dev/pandas/issues/39184
`
``
218
`+
test that the deprecation also works with > 2 inputs -> using a numba
`
``
219
`+
written ufunc for this because numpy itself doesn't have such ufuncs
`
``
220
`+
from numba import float64, vectorize
`
``
221
+
``
222
`+
@vectorize([float64(float64, float64, float64)])
`
``
223
`+
def my_ufunc(x, y, z):
`
``
224
`+
return x + y + z
`
``
225
+
``
226
`+
df1 = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
`
``
227
`+
df2 = pd.DataFrame({"b": [1, 2, 3], "c": [4, 5, 6]})
`
``
228
`+
df3 = pd.DataFrame({"a": [1, 2, 3], "c": [4, 5, 6]})
`
``
229
+
``
230
`+
with tm.assert_produces_warning(FutureWarning):
`
``
231
`+
result = my_ufunc(df1, df2, df3)
`
``
232
`+
expected = pd.DataFrame([[3.0, 12.0], [6.0, 15.0], [9.0, 18.0]], columns=["a", "b"])
`
``
233
`+
tm.assert_frame_equal(result, expected)
`
``
234
+
``
235
`+
all aligned -> no warning
`
``
236
`+
with tm.assert_produces_warning(None):
`
``
237
`+
result = my_ufunc(df1, df1, df1)
`
``
238
`+
tm.assert_frame_equal(result, expected)
`
``
239
+
``
240
`+
mixed frame / arrays
`
``
241
`+
with tm.assert_produces_warning(FutureWarning):
`
``
242
`+
result = my_ufunc(df1, df2, df3.values)
`
``
243
`+
tm.assert_frame_equal(result, expected)
`
``
244
+
``
245
`+
single frame -> no warning
`
``
246
`+
with tm.assert_produces_warning(None):
`
``
247
`+
result = my_ufunc(df1, df2.values, df3.values)
`
``
248
`+
tm.assert_frame_equal(result, expected)
`
``
249
+
``
250
`+
takes indices of first frame
`
``
251
`+
with tm.assert_produces_warning(FutureWarning):
`
``
252
`+
result = my_ufunc(df1.values, df2, df3)
`
``
253
`+
expected = expected.set_axis(["b", "c"], axis=1)
`
``
254
`+
tm.assert_frame_equal(result, expected)
`