Skip to content

Commit 2026854

Browse files
authored
TST: Split/parameterize indexing tests (#45325)
1 parent e432d2a commit 2026854

File tree

4 files changed

+137
-153
lines changed

4 files changed

+137
-153
lines changed

pandas/conftest.py

+8
Original file line numberDiff line numberDiff line change
@@ -1751,6 +1751,14 @@ def indexer_al(request):
17511751
return request.param
17521752

17531753

1754+
@pytest.fixture(params=[tm.iat, tm.iloc])
1755+
def indexer_ial(request):
1756+
"""
1757+
Parametrize over iat.__setitem__, iloc.__setitem__
1758+
"""
1759+
return request.param
1760+
1761+
17541762
@pytest.fixture
17551763
def using_array_manager(request):
17561764
"""

pandas/tests/indexing/test_indexing.py

+12-12
Original file line numberDiff line numberDiff line change
@@ -704,20 +704,20 @@ def run_tests(df, rhs, right_loc, right_iloc):
704704
right_iloc["jolie"] = ["@2", -26.0, -18.0, -10.0, "@18"]
705705
run_tests(df, rhs, right_loc, right_iloc)
706706

707-
def test_str_label_slicing_with_negative_step(self):
707+
@pytest.mark.parametrize(
708+
"idx", [_mklbl("A", 20), np.arange(20) + 100, np.linspace(100, 150, 20)]
709+
)
710+
def test_str_label_slicing_with_negative_step(self, idx):
708711
SLC = pd.IndexSlice
709712

710-
for idx in [_mklbl("A", 20), np.arange(20) + 100, np.linspace(100, 150, 20)]:
711-
idx = Index(idx)
712-
ser = Series(np.arange(20), index=idx)
713-
tm.assert_indexing_slices_equivalent(ser, SLC[idx[9] :: -1], SLC[9::-1])
714-
tm.assert_indexing_slices_equivalent(ser, SLC[: idx[9] : -1], SLC[:8:-1])
715-
tm.assert_indexing_slices_equivalent(
716-
ser, SLC[idx[13] : idx[9] : -1], SLC[13:8:-1]
717-
)
718-
tm.assert_indexing_slices_equivalent(
719-
ser, SLC[idx[9] : idx[13] : -1], SLC[:0]
720-
)
713+
idx = Index(idx)
714+
ser = Series(np.arange(20), index=idx)
715+
tm.assert_indexing_slices_equivalent(ser, SLC[idx[9] :: -1], SLC[9::-1])
716+
tm.assert_indexing_slices_equivalent(ser, SLC[: idx[9] : -1], SLC[:8:-1])
717+
tm.assert_indexing_slices_equivalent(
718+
ser, SLC[idx[13] : idx[9] : -1], SLC[13:8:-1]
719+
)
720+
tm.assert_indexing_slices_equivalent(ser, SLC[idx[9] : idx[13] : -1], SLC[:0])
721721

722722
def test_slice_with_zero_step_raises(self, index, indexer_sl, frame_or_series):
723723
obj = frame_or_series(np.arange(len(index)), index=index)

pandas/tests/indexing/test_loc.py

+101-98
Original file line numberDiff line numberDiff line change
@@ -54,42 +54,45 @@ def test_loc_getitem_label(self):
5454
# label
5555
self.check_result("loc", "c", typs=["empty"], fails=KeyError)
5656

57-
def test_loc_getitem_label_out_of_range(self):
57+
@pytest.mark.parametrize(
58+
"key, typs, axes",
59+
[
60+
["f", ["ints", "uints", "labels", "mixed", "ts"], None],
61+
["f", ["floats"], None],
62+
[20, ["ints", "uints", "mixed"], None],
63+
[20, ["labels"], None],
64+
[20, ["ts"], 0],
65+
[20, ["floats"], 0],
66+
],
67+
)
68+
def test_loc_getitem_label_out_of_range(self, key, typs, axes):
5869

5970
# out of range label
60-
self.check_result(
61-
"loc", "f", typs=["ints", "uints", "labels", "mixed", "ts"], fails=KeyError
62-
)
63-
self.check_result("loc", "f", typs=["floats"], fails=KeyError)
64-
self.check_result("loc", "f", typs=["floats"], fails=KeyError)
65-
self.check_result("loc", 20, typs=["ints", "uints", "mixed"], fails=KeyError)
66-
self.check_result("loc", 20, typs=["labels"], fails=KeyError)
67-
self.check_result("loc", 20, typs=["ts"], axes=0, fails=KeyError)
68-
self.check_result("loc", 20, typs=["floats"], axes=0, fails=KeyError)
71+
self.check_result("loc", key, typs=typs, axes=axes, fails=KeyError)
6972

70-
def test_loc_getitem_label_list(self):
73+
@pytest.mark.parametrize(
74+
"key, typs",
75+
[
76+
[[0, 1, 2], ["ints", "uints", "floats"]],
77+
[[1, 3.0, "A"], ["ints", "uints", "floats"]],
78+
],
79+
)
80+
def test_loc_getitem_label_list(self, key, typs):
7181
# list of labels
72-
self.check_result(
73-
"loc", [0, 1, 2], typs=["ints", "uints", "floats"], fails=KeyError
74-
)
75-
self.check_result(
76-
"loc", [1, 3.0, "A"], typs=["ints", "uints", "floats"], fails=KeyError
77-
)
78-
79-
def test_loc_getitem_label_list_with_missing(self):
80-
self.check_result("loc", [0, 1, 2], typs=["empty"], fails=KeyError)
81-
self.check_result(
82-
"loc", [0, 2, 10], typs=["ints", "uints", "floats"], axes=0, fails=KeyError
83-
)
82+
self.check_result("loc", key, typs=typs, fails=KeyError)
8483

85-
self.check_result(
86-
"loc", [3, 6, 7], typs=["ints", "uints", "floats"], axes=1, fails=KeyError
87-
)
88-
89-
# GH 17758 - MultiIndex and missing keys
90-
self.check_result(
91-
"loc", [(1, 3), (1, 4), (2, 5)], typs=["multi"], axes=0, fails=KeyError
92-
)
84+
@pytest.mark.parametrize(
85+
"key, typs, axes",
86+
[
87+
[[0, 1, 2], ["empty"], None],
88+
[[0, 2, 10], ["ints", "uints", "floats"], 0],
89+
[[3, 6, 7], ["ints", "uints", "floats"], 1],
90+
# GH 17758 - MultiIndex and missing keys
91+
[[(1, 3), (1, 4), (2, 5)], ["multi"], 0],
92+
],
93+
)
94+
def test_loc_getitem_label_list_with_missing(self, key, typs, axes):
95+
self.check_result("loc", key, typs=typs, axes=axes, fails=KeyError)
9396

9497
def test_loc_getitem_label_list_fails(self):
9598
# fails
@@ -108,7 +111,22 @@ def test_loc_getitem_bool(self):
108111

109112
self.check_result("loc", b, typs=["empty"], fails=IndexError)
110113

111-
def test_loc_getitem_label_slice(self):
114+
@pytest.mark.parametrize(
115+
"slc, typs, axes, fails",
116+
[
117+
[
118+
slice(1, 3),
119+
["labels", "mixed", "empty", "ts", "floats"],
120+
None,
121+
TypeError,
122+
],
123+
[slice("20130102", "20130104"), ["ts"], 1, TypeError],
124+
[slice(2, 8), ["mixed"], 0, TypeError],
125+
[slice(2, 8), ["mixed"], 1, KeyError],
126+
[slice(2, 4, 2), ["mixed"], 0, TypeError],
127+
],
128+
)
129+
def test_loc_getitem_label_slice(self, slc, typs, axes, fails):
112130

113131
# label slices (with ints)
114132

@@ -118,20 +136,10 @@ def test_loc_getitem_label_slice(self):
118136

119137
self.check_result(
120138
"loc",
121-
slice(1, 3),
122-
typs=["labels", "mixed", "empty", "ts", "floats"],
123-
fails=TypeError,
124-
)
125-
126-
self.check_result(
127-
"loc", slice("20130102", "20130104"), typs=["ts"], axes=1, fails=TypeError
128-
)
129-
130-
self.check_result("loc", slice(2, 8), typs=["mixed"], axes=0, fails=TypeError)
131-
self.check_result("loc", slice(2, 8), typs=["mixed"], axes=1, fails=KeyError)
132-
133-
self.check_result(
134-
"loc", slice(2, 4, 2), typs=["mixed"], axes=0, fails=TypeError
139+
slc,
140+
typs=typs,
141+
axes=axes,
142+
fails=fails,
135143
)
136144

137145
def test_setitem_from_duplicate_axis(self):
@@ -956,55 +964,40 @@ def test_loc_non_unique(self):
956964
tm.assert_frame_equal(result, expected)
957965

958966
@pytest.mark.arm_slow
959-
def test_loc_non_unique_memory_error(self):
967+
@pytest.mark.parametrize("length, l2", [[900, 100], [900000, 100000]])
968+
def test_loc_non_unique_memory_error(self, length, l2):
960969

961970
# GH 4280
962971
# non_unique index with a large selection triggers a memory error
963972

964973
columns = list("ABCDEFG")
965974

966-
def gen_test(length, l2):
967-
return pd.concat(
968-
[
969-
DataFrame(
970-
np.random.randn(length, len(columns)),
971-
index=np.arange(length),
972-
columns=columns,
973-
),
974-
DataFrame(
975-
np.ones((l2, len(columns))), index=[0] * l2, columns=columns
976-
),
977-
]
978-
)
979-
980-
def gen_expected(df, mask):
981-
len_mask = len(mask)
982-
return pd.concat(
983-
[
984-
df.take([0]),
985-
DataFrame(
986-
np.ones((len_mask, len(columns))),
987-
index=[0] * len_mask,
988-
columns=columns,
989-
),
990-
df.take(mask[1:]),
991-
]
992-
)
993-
994-
df = gen_test(900, 100)
995-
assert df.index.is_unique is False
996-
997-
mask = np.arange(100)
998-
result = df.loc[mask]
999-
expected = gen_expected(df, mask)
1000-
tm.assert_frame_equal(result, expected)
975+
df = pd.concat(
976+
[
977+
DataFrame(
978+
np.random.randn(length, len(columns)),
979+
index=np.arange(length),
980+
columns=columns,
981+
),
982+
DataFrame(np.ones((l2, len(columns))), index=[0] * l2, columns=columns),
983+
]
984+
)
1001985

1002-
df = gen_test(900000, 100000)
1003986
assert df.index.is_unique is False
1004987

1005-
mask = np.arange(100000)
988+
mask = np.arange(l2)
1006989
result = df.loc[mask]
1007-
expected = gen_expected(df, mask)
990+
expected = pd.concat(
991+
[
992+
df.take([0]),
993+
DataFrame(
994+
np.ones((len(mask), len(columns))),
995+
index=[0] * len(mask),
996+
columns=columns,
997+
),
998+
df.take(mask[1:]),
999+
]
1000+
)
10081001
tm.assert_frame_equal(result, expected)
10091002

10101003
def test_loc_name(self):
@@ -1840,12 +1833,20 @@ def test_loc_setitem_empty_series(self):
18401833
ser.loc[3] = 3
18411834
tm.assert_series_equal(ser, Series([1, 3], index=[1, 3]))
18421835

1836+
def test_loc_setitem_empty_series_float(self):
1837+
# GH#5226
1838+
1839+
# partially set with an empty object series
18431840
ser = Series(dtype=object)
18441841
ser.loc[1] = 1.0
18451842
tm.assert_series_equal(ser, Series([1.0], index=[1]))
18461843
ser.loc[3] = 3.0
18471844
tm.assert_series_equal(ser, Series([1.0, 3.0], index=[1, 3]))
18481845

1846+
def test_loc_setitem_empty_series_str_idx(self):
1847+
# GH#5226
1848+
1849+
# partially set with an empty object series
18491850
ser = Series(dtype=object)
18501851
ser.loc["foo"] = 1
18511852
tm.assert_series_equal(ser, Series([1], index=["foo"]))
@@ -1864,24 +1865,26 @@ def test_loc_setitem_incremental_with_dst(self):
18641865
expected = Series(1, index=idxs)
18651866
tm.assert_series_equal(result, expected)
18661867

1867-
def test_loc_setitem_datetime_keys_cast(self):
1868-
# GH#9516
1869-
dt1 = Timestamp("20130101 09:00:00")
1870-
dt2 = Timestamp("20130101 10:00:00")
1871-
1872-
for conv in [
1868+
@pytest.mark.parametrize(
1869+
"conv",
1870+
[
18731871
lambda x: x,
18741872
lambda x: x.to_datetime64(),
18751873
lambda x: x.to_pydatetime(),
18761874
lambda x: np.datetime64(x),
1877-
]:
1878-
1879-
df = DataFrame()
1880-
df.loc[conv(dt1), "one"] = 100
1881-
df.loc[conv(dt2), "one"] = 200
1875+
],
1876+
ids=["self", "to_datetime64", "to_pydatetime", "np.datetime64"],
1877+
)
1878+
def test_loc_setitem_datetime_keys_cast(self, conv):
1879+
# GH#9516
1880+
dt1 = Timestamp("20130101 09:00:00")
1881+
dt2 = Timestamp("20130101 10:00:00")
1882+
df = DataFrame()
1883+
df.loc[conv(dt1), "one"] = 100
1884+
df.loc[conv(dt2), "one"] = 200
18821885

1883-
expected = DataFrame({"one": [100.0, 200.0]}, index=[dt1, dt2])
1884-
tm.assert_frame_equal(df, expected)
1886+
expected = DataFrame({"one": [100.0, 200.0]}, index=[dt1, dt2])
1887+
tm.assert_frame_equal(df, expected)
18851888

18861889
def test_loc_setitem_categorical_column_retains_dtype(self, ordered):
18871890
# GH16360

pandas/tests/indexing/test_scalar.py

+16-43
Original file line numberDiff line numberDiff line change
@@ -19,33 +19,6 @@
1919

2020

2121
class TestScalar(Base):
22-
@pytest.mark.parametrize("kind", ["series", "frame"])
23-
def test_at_and_iat_get(self, kind):
24-
def _check(f, func, values=False):
25-
26-
if f is not None:
27-
indices = self.generate_indices(f, values)
28-
for i in indices:
29-
result = getattr(f, func)[i]
30-
expected = self.get_value(func, f, i, values)
31-
tm.assert_almost_equal(result, expected)
32-
33-
d = getattr(self, kind)
34-
35-
# iat
36-
for f in [d["ints"], d["uints"]]:
37-
_check(f, "iat", values=True)
38-
39-
for f in [d["labels"], d["ts"], d["floats"]]:
40-
if f is not None:
41-
msg = "iAt based indexing can only have integer indexers"
42-
with pytest.raises(ValueError, match=msg):
43-
self.check_values(f, "iat")
44-
45-
# at
46-
for f in [d["ints"], d["uints"], d["labels"], d["ts"], d["floats"]]:
47-
_check(f, "at")
48-
4922
@pytest.mark.parametrize("kind", ["series", "frame"])
5023
@pytest.mark.parametrize("col", ["ints", "uints"])
5124
def test_iat_set_ints(self, kind, col):
@@ -103,24 +76,24 @@ def test_at_iat_coercion(self):
10376
xp = s.values[5]
10477
assert result == xp
10578

79+
@pytest.mark.parametrize(
80+
"ser, expected",
81+
[
82+
[
83+
Series(["2014-01-01", "2014-02-02"], dtype="datetime64[ns]"),
84+
Timestamp("2014-02-02"),
85+
],
86+
[
87+
Series(["1 days", "2 days"], dtype="timedelta64[ns]"),
88+
Timedelta("2 days"),
89+
],
90+
],
91+
)
92+
def test_iloc_iat_coercion_datelike(self, indexer_ial, ser, expected):
10693
# GH 7729
10794
# make sure we are boxing the returns
108-
s = Series(["2014-01-01", "2014-02-02"], dtype="datetime64[ns]")
109-
expected = Timestamp("2014-02-02")
110-
111-
for r in [lambda: s.iat[1], lambda: s.iloc[1]]:
112-
result = r()
113-
assert result == expected
114-
115-
s = Series(["1 days", "2 days"], dtype="timedelta64[ns]")
116-
expected = Timedelta("2 days")
117-
118-
for r in [lambda: s.iat[1], lambda: s.iloc[1]]:
119-
result = r()
120-
assert result == expected
121-
122-
def test_iat_invalid_args(self):
123-
pass
95+
result = indexer_ial(ser)[1]
96+
assert result == expected
12497

12598
def test_imethods_with_dups(self):
12699

0 commit comments

Comments
 (0)