Skip to content

Commit b6a18e9

Browse files
jbrockmendelrhshadrach
authored andcommitted
BUG: DataFrame[object] + Series[dt64], test parametrization (pandas-dev#33824)
1 parent 4568a79 commit b6a18e9

File tree

4 files changed

+44
-86
lines changed

4 files changed

+44
-86
lines changed

pandas/core/ops/dispatch.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ def should_series_dispatch(left, right, op):
7171
# numpy integer dtypes as timedelta64 dtypes in this scenario
7272
return True
7373

74-
if is_datetime64_dtype(ldtype) and is_object_dtype(rdtype):
75-
# in particular case where right is an array of DateOffsets
74+
if (is_datetime64_dtype(ldtype) and is_object_dtype(rdtype)) or (
75+
is_datetime64_dtype(rdtype) and is_object_dtype(ldtype)
76+
):
77+
# in particular case where one is an array of DateOffsets
7678
return True
7779

7880
return False

pandas/tests/arithmetic/conftest.py

+12
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ def id_func(x):
1717

1818

1919
# ------------------------------------------------------------------
20+
@pytest.fixture(
21+
params=[
22+
("foo", None, None),
23+
("Egon", "Venkman", None),
24+
("NCC1701D", "NCC1701D", "NCC1701D"),
25+
]
26+
)
27+
def names(request):
28+
"""
29+
A 3-tuple of names, the first two for operands, the last for a result.
30+
"""
31+
return request.param
2032

2133

2234
@pytest.fixture(params=[1, np.array(1, dtype=np.int64)])

pandas/tests/arithmetic/test_datetime64.py

+26-55
Original file line numberDiff line numberDiff line change
@@ -1438,64 +1438,41 @@ def test_dt64arr_add_sub_DateOffset(self, box_with_array):
14381438
tm.assert_equal(result, exp)
14391439
tm.assert_equal(result2, exp)
14401440

1441-
# TODO: __sub__, __rsub__
1442-
def test_dt64arr_add_mixed_offset_array(self, box_with_array):
1443-
# GH#10699
1444-
# array of offsets
1445-
s = DatetimeIndex([Timestamp("2000-1-1"), Timestamp("2000-2-1")])
1446-
s = tm.box_expected(s, box_with_array)
1447-
1448-
warn = None if box_with_array is pd.DataFrame else PerformanceWarning
1449-
with tm.assert_produces_warning(warn):
1450-
other = pd.Index([pd.offsets.DateOffset(years=1), pd.offsets.MonthEnd()])
1451-
other = tm.box_expected(other, box_with_array)
1452-
result = s + other
1453-
exp = DatetimeIndex([Timestamp("2001-1-1"), Timestamp("2000-2-29")])
1454-
exp = tm.box_expected(exp, box_with_array)
1455-
tm.assert_equal(result, exp)
1456-
1457-
# same offset
1458-
other = pd.Index(
1441+
@pytest.mark.parametrize(
1442+
"other",
1443+
[
1444+
np.array([pd.offsets.MonthEnd(), pd.offsets.Day(n=2)]),
1445+
np.array([pd.offsets.DateOffset(years=1), pd.offsets.MonthEnd()]),
1446+
np.array( # matching offsets
14591447
[pd.offsets.DateOffset(years=1), pd.offsets.DateOffset(years=1)]
1460-
)
1461-
other = tm.box_expected(other, box_with_array)
1462-
result = s + other
1463-
exp = DatetimeIndex([Timestamp("2001-1-1"), Timestamp("2001-2-1")])
1464-
exp = tm.box_expected(exp, box_with_array)
1465-
tm.assert_equal(result, exp)
1466-
1467-
# TODO: overlap with test_dt64arr_add_mixed_offset_array?
1468-
def test_dt64arr_add_sub_offset_ndarray(self, tz_naive_fixture, box_with_array):
1448+
),
1449+
],
1450+
)
1451+
@pytest.mark.parametrize("op", [operator.add, roperator.radd, operator.sub])
1452+
@pytest.mark.parametrize("box_other", [True, False])
1453+
def test_dt64arr_add_sub_offset_array(
1454+
self, tz_naive_fixture, box_with_array, box_other, op, other
1455+
):
14691456
# GH#18849
1457+
# GH#10699 array of offsets
14701458

14711459
tz = tz_naive_fixture
14721460
dti = pd.date_range("2017-01-01", periods=2, tz=tz)
14731461
dtarr = tm.box_expected(dti, box_with_array)
14741462

14751463
other = np.array([pd.offsets.MonthEnd(), pd.offsets.Day(n=2)])
1464+
expected = DatetimeIndex([op(dti[n], other[n]) for n in range(len(dti))])
1465+
expected = tm.box_expected(expected, box_with_array)
1466+
1467+
if box_other:
1468+
other = tm.box_expected(other, box_with_array)
14761469

14771470
warn = PerformanceWarning
1478-
if box_with_array is pd.DataFrame and tz is not None:
1471+
if box_with_array is pd.DataFrame and not (tz is None and not box_other):
14791472
warn = None
1480-
1481-
with tm.assert_produces_warning(warn):
1482-
res = dtarr + other
1483-
expected = DatetimeIndex(
1484-
[dti[n] + other[n] for n in range(len(dti))], name=dti.name, freq="infer"
1485-
)
1486-
expected = tm.box_expected(expected, box_with_array)
1487-
tm.assert_equal(res, expected)
1488-
14891473
with tm.assert_produces_warning(warn):
1490-
res2 = other + dtarr
1491-
tm.assert_equal(res2, expected)
1474+
res = op(dtarr, other)
14921475

1493-
with tm.assert_produces_warning(warn):
1494-
res = dtarr - other
1495-
expected = DatetimeIndex(
1496-
[dti[n] - other[n] for n in range(len(dti))], name=dti.name, freq="infer"
1497-
)
1498-
expected = tm.box_expected(expected, box_with_array)
14991476
tm.assert_equal(res, expected)
15001477

15011478
@pytest.mark.parametrize(
@@ -1905,9 +1882,9 @@ def test_dt64_mul_div_numeric_invalid(self, one, dt64_series):
19051882

19061883
# TODO: parametrize over box
19071884
@pytest.mark.parametrize("op", ["__add__", "__radd__", "__sub__", "__rsub__"])
1908-
@pytest.mark.parametrize("tz", [None, "Asia/Tokyo"])
1909-
def test_dt64_series_add_intlike(self, tz, op):
1885+
def test_dt64_series_add_intlike(self, tz_naive_fixture, op):
19101886
# GH#19123
1887+
tz = tz_naive_fixture
19111888
dti = pd.DatetimeIndex(["2016-01-02", "2016-02-03", "NaT"], tz=tz)
19121889
ser = Series(dti)
19131890

@@ -2376,12 +2353,9 @@ def test_ufunc_coercions(self):
23762353
tm.assert_index_equal(result, exp)
23772354
assert result.freq == exp.freq
23782355

2379-
@pytest.mark.parametrize(
2380-
"names", [("foo", None, None), ("baz", "bar", None), ("bar", "bar", "bar")]
2381-
)
2382-
@pytest.mark.parametrize("tz", [None, "America/Chicago"])
2383-
def test_dti_add_series(self, tz, names):
2356+
def test_dti_add_series(self, tz_naive_fixture, names):
23842357
# GH#13905
2358+
tz = tz_naive_fixture
23852359
index = DatetimeIndex(
23862360
["2016-06-28 05:30", "2016-06-28 05:31"], tz=tz, name=names[0]
23872361
)
@@ -2403,9 +2377,6 @@ def test_dti_add_series(self, tz, names):
24032377
tm.assert_index_equal(result4, expected)
24042378

24052379
@pytest.mark.parametrize("op", [operator.add, roperator.radd, operator.sub])
2406-
@pytest.mark.parametrize(
2407-
"names", [(None, None, None), ("foo", "bar", None), ("foo", "foo", "foo")]
2408-
)
24092380
def test_dti_addsub_offset_arraylike(
24102381
self, tz_naive_fixture, names, op, index_or_series
24112382
):

pandas/tests/arithmetic/test_timedelta64.py

+2-29
Original file line numberDiff line numberDiff line change
@@ -1195,18 +1195,10 @@ def test_td64arr_sub_td64_array(self, box_with_array):
11951195
result = tdarr - tdi
11961196
tm.assert_equal(result, expected)
11971197

1198-
@pytest.mark.parametrize(
1199-
"names",
1200-
[
1201-
(None, None, None),
1202-
("Egon", "Venkman", None),
1203-
("NCC1701D", "NCC1701D", "NCC1701D"),
1204-
],
1205-
)
12061198
def test_td64arr_add_sub_tdi(self, box, names):
12071199
# GH#17250 make sure result dtype is correct
12081200
# GH#19043 make sure names are propagated correctly
1209-
if box is pd.DataFrame and names[1] == "Venkman":
1201+
if box is pd.DataFrame and names[1] != names[0]:
12101202
pytest.skip(
12111203
"Name propagation for DataFrame does not behave like "
12121204
"it does for Index/Series"
@@ -1307,12 +1299,9 @@ def test_td64arr_sub_timedeltalike(self, two_hours, box_with_array):
13071299
# ------------------------------------------------------------------
13081300
# __add__/__sub__ with DateOffsets and arrays of DateOffsets
13091301

1310-
@pytest.mark.parametrize(
1311-
"names", [(None, None, None), ("foo", "bar", None), ("foo", "foo", "foo")]
1312-
)
13131302
def test_td64arr_add_offset_index(self, names, box):
13141303
# GH#18849, GH#19744
1315-
if box is pd.DataFrame and names[1] == "bar":
1304+
if box is pd.DataFrame and names[1] != names[0]:
13161305
pytest.skip(
13171306
"Name propagation for DataFrame does not behave like "
13181307
"it does for Index/Series"
@@ -2041,14 +2030,6 @@ def test_td64arr_div_numeric_array(self, box_with_array, vector, any_real_dtype)
20412030
with pytest.raises(TypeError, match=pattern):
20422031
vector.astype(object) / tdser
20432032

2044-
@pytest.mark.parametrize(
2045-
"names",
2046-
[
2047-
(None, None, None),
2048-
("Egon", "Venkman", None),
2049-
("NCC1701D", "NCC1701D", "NCC1701D"),
2050-
],
2051-
)
20522033
def test_td64arr_mul_int_series(self, box_df_fail, names):
20532034
# GH#19042 test for correct name attachment
20542035
box = box_df_fail # broadcasts along wrong axis, but doesn't raise
@@ -2078,14 +2059,6 @@ def test_td64arr_mul_int_series(self, box_df_fail, names):
20782059
tm.assert_equal(result, expected)
20792060

20802061
# TODO: Should we be parametrizing over types for `ser` too?
2081-
@pytest.mark.parametrize(
2082-
"names",
2083-
[
2084-
(None, None, None),
2085-
("Egon", "Venkman", None),
2086-
("NCC1701D", "NCC1701D", "NCC1701D"),
2087-
],
2088-
)
20892062
def test_float_series_rdiv_td64arr(self, box_with_array, names):
20902063
# GH#19042 test for correct name attachment
20912064
# TODO: the direct operation TimedeltaIndex / Series still

0 commit comments

Comments
 (0)