Skip to content

Commit 8fb9ca9

Browse files
jbrockmendelphofl
authored andcommitted
TST: collect Interval tests (pandas-dev#56072)
* TST: collect scalar Interval tests * TST: collect IntervalIndex tests * TST: collect Interval tests
1 parent 5e60c70 commit 8fb9ca9

12 files changed

+545
-536
lines changed

pandas/tests/arrays/interval/test_interval.py

-175
Original file line numberDiff line numberDiff line change
@@ -229,178 +229,3 @@ def test_min_max(self, left_right_dtypes, index_or_series_or_array):
229229
res = arr_na.max(skipna=True)
230230
assert res == MAX
231231
assert type(res) == type(MAX)
232-
233-
234-
# ----------------------------------------------------------------------------
235-
# Arrow interaction
236-
237-
238-
def test_arrow_extension_type():
239-
pa = pytest.importorskip("pyarrow")
240-
241-
from pandas.core.arrays.arrow.extension_types import ArrowIntervalType
242-
243-
p1 = ArrowIntervalType(pa.int64(), "left")
244-
p2 = ArrowIntervalType(pa.int64(), "left")
245-
p3 = ArrowIntervalType(pa.int64(), "right")
246-
247-
assert p1.closed == "left"
248-
assert p1 == p2
249-
assert p1 != p3
250-
assert hash(p1) == hash(p2)
251-
assert hash(p1) != hash(p3)
252-
253-
254-
def test_arrow_array():
255-
pa = pytest.importorskip("pyarrow")
256-
257-
from pandas.core.arrays.arrow.extension_types import ArrowIntervalType
258-
259-
intervals = pd.interval_range(1, 5, freq=1).array
260-
261-
result = pa.array(intervals)
262-
assert isinstance(result.type, ArrowIntervalType)
263-
assert result.type.closed == intervals.closed
264-
assert result.type.subtype == pa.int64()
265-
assert result.storage.field("left").equals(pa.array([1, 2, 3, 4], type="int64"))
266-
assert result.storage.field("right").equals(pa.array([2, 3, 4, 5], type="int64"))
267-
268-
expected = pa.array([{"left": i, "right": i + 1} for i in range(1, 5)])
269-
assert result.storage.equals(expected)
270-
271-
# convert to its storage type
272-
result = pa.array(intervals, type=expected.type)
273-
assert result.equals(expected)
274-
275-
# unsupported conversions
276-
with pytest.raises(TypeError, match="Not supported to convert IntervalArray"):
277-
pa.array(intervals, type="float64")
278-
279-
with pytest.raises(TypeError, match="Not supported to convert IntervalArray"):
280-
pa.array(intervals, type=ArrowIntervalType(pa.float64(), "left"))
281-
282-
283-
def test_arrow_array_missing():
284-
pa = pytest.importorskip("pyarrow")
285-
286-
from pandas.core.arrays.arrow.extension_types import ArrowIntervalType
287-
288-
arr = IntervalArray.from_breaks([0.0, 1.0, 2.0, 3.0])
289-
arr[1] = None
290-
291-
result = pa.array(arr)
292-
assert isinstance(result.type, ArrowIntervalType)
293-
assert result.type.closed == arr.closed
294-
assert result.type.subtype == pa.float64()
295-
296-
# fields have missing values (not NaN)
297-
left = pa.array([0.0, None, 2.0], type="float64")
298-
right = pa.array([1.0, None, 3.0], type="float64")
299-
assert result.storage.field("left").equals(left)
300-
assert result.storage.field("right").equals(right)
301-
302-
# structarray itself also has missing values on the array level
303-
vals = [
304-
{"left": 0.0, "right": 1.0},
305-
{"left": None, "right": None},
306-
{"left": 2.0, "right": 3.0},
307-
]
308-
expected = pa.StructArray.from_pandas(vals, mask=np.array([False, True, False]))
309-
assert result.storage.equals(expected)
310-
311-
312-
@pytest.mark.filterwarnings(
313-
"ignore:Passing a BlockManager to DataFrame:DeprecationWarning"
314-
)
315-
@pytest.mark.parametrize(
316-
"breaks",
317-
[[0.0, 1.0, 2.0, 3.0], date_range("2017", periods=4, freq="D")],
318-
ids=["float", "datetime64[ns]"],
319-
)
320-
def test_arrow_table_roundtrip(breaks):
321-
pa = pytest.importorskip("pyarrow")
322-
323-
from pandas.core.arrays.arrow.extension_types import ArrowIntervalType
324-
325-
arr = IntervalArray.from_breaks(breaks)
326-
arr[1] = None
327-
df = pd.DataFrame({"a": arr})
328-
329-
table = pa.table(df)
330-
assert isinstance(table.field("a").type, ArrowIntervalType)
331-
result = table.to_pandas()
332-
assert isinstance(result["a"].dtype, pd.IntervalDtype)
333-
tm.assert_frame_equal(result, df)
334-
335-
table2 = pa.concat_tables([table, table])
336-
result = table2.to_pandas()
337-
expected = pd.concat([df, df], ignore_index=True)
338-
tm.assert_frame_equal(result, expected)
339-
340-
# GH-41040
341-
table = pa.table(
342-
[pa.chunked_array([], type=table.column(0).type)], schema=table.schema
343-
)
344-
result = table.to_pandas()
345-
tm.assert_frame_equal(result, expected[0:0])
346-
347-
348-
@pytest.mark.filterwarnings(
349-
"ignore:Passing a BlockManager to DataFrame:DeprecationWarning"
350-
)
351-
@pytest.mark.parametrize(
352-
"breaks",
353-
[[0.0, 1.0, 2.0, 3.0], date_range("2017", periods=4, freq="D")],
354-
ids=["float", "datetime64[ns]"],
355-
)
356-
def test_arrow_table_roundtrip_without_metadata(breaks):
357-
pa = pytest.importorskip("pyarrow")
358-
359-
arr = IntervalArray.from_breaks(breaks)
360-
arr[1] = None
361-
df = pd.DataFrame({"a": arr})
362-
363-
table = pa.table(df)
364-
# remove the metadata
365-
table = table.replace_schema_metadata()
366-
assert table.schema.metadata is None
367-
368-
result = table.to_pandas()
369-
assert isinstance(result["a"].dtype, pd.IntervalDtype)
370-
tm.assert_frame_equal(result, df)
371-
372-
373-
def test_from_arrow_from_raw_struct_array():
374-
# in case pyarrow lost the Interval extension type (eg on parquet roundtrip
375-
# with datetime64[ns] subtype, see GH-45881), still allow conversion
376-
# from arrow to IntervalArray
377-
pa = pytest.importorskip("pyarrow")
378-
379-
arr = pa.array([{"left": 0, "right": 1}, {"left": 1, "right": 2}])
380-
dtype = pd.IntervalDtype(np.dtype("int64"), closed="neither")
381-
382-
result = dtype.__from_arrow__(arr)
383-
expected = IntervalArray.from_breaks(
384-
np.array([0, 1, 2], dtype="int64"), closed="neither"
385-
)
386-
tm.assert_extension_array_equal(result, expected)
387-
388-
result = dtype.__from_arrow__(pa.chunked_array([arr]))
389-
tm.assert_extension_array_equal(result, expected)
390-
391-
392-
@pytest.mark.parametrize("timezone", ["UTC", "US/Pacific", "GMT"])
393-
def test_interval_index_subtype(timezone, inclusive_endpoints_fixture):
394-
# GH 46999
395-
dates = date_range("2022", periods=3, tz=timezone)
396-
dtype = f"interval[datetime64[ns, {timezone}], {inclusive_endpoints_fixture}]"
397-
result = IntervalIndex.from_arrays(
398-
["2022-01-01", "2022-01-02"],
399-
["2022-01-02", "2022-01-03"],
400-
closed=inclusive_endpoints_fixture,
401-
dtype=dtype,
402-
)
403-
expected = IntervalIndex.from_arrays(
404-
dates[:-1], dates[1:], closed=inclusive_endpoints_fixture
405-
)
406-
tm.assert_index_equal(result, expected)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import numpy as np
2+
import pytest
3+
4+
import pandas as pd
5+
import pandas._testing as tm
6+
from pandas.core.arrays import IntervalArray
7+
8+
9+
def test_arrow_extension_type():
10+
pa = pytest.importorskip("pyarrow")
11+
12+
from pandas.core.arrays.arrow.extension_types import ArrowIntervalType
13+
14+
p1 = ArrowIntervalType(pa.int64(), "left")
15+
p2 = ArrowIntervalType(pa.int64(), "left")
16+
p3 = ArrowIntervalType(pa.int64(), "right")
17+
18+
assert p1.closed == "left"
19+
assert p1 == p2
20+
assert p1 != p3
21+
assert hash(p1) == hash(p2)
22+
assert hash(p1) != hash(p3)
23+
24+
25+
def test_arrow_array():
26+
pa = pytest.importorskip("pyarrow")
27+
28+
from pandas.core.arrays.arrow.extension_types import ArrowIntervalType
29+
30+
intervals = pd.interval_range(1, 5, freq=1).array
31+
32+
result = pa.array(intervals)
33+
assert isinstance(result.type, ArrowIntervalType)
34+
assert result.type.closed == intervals.closed
35+
assert result.type.subtype == pa.int64()
36+
assert result.storage.field("left").equals(pa.array([1, 2, 3, 4], type="int64"))
37+
assert result.storage.field("right").equals(pa.array([2, 3, 4, 5], type="int64"))
38+
39+
expected = pa.array([{"left": i, "right": i + 1} for i in range(1, 5)])
40+
assert result.storage.equals(expected)
41+
42+
# convert to its storage type
43+
result = pa.array(intervals, type=expected.type)
44+
assert result.equals(expected)
45+
46+
# unsupported conversions
47+
with pytest.raises(TypeError, match="Not supported to convert IntervalArray"):
48+
pa.array(intervals, type="float64")
49+
50+
with pytest.raises(TypeError, match="Not supported to convert IntervalArray"):
51+
pa.array(intervals, type=ArrowIntervalType(pa.float64(), "left"))
52+
53+
54+
def test_arrow_array_missing():
55+
pa = pytest.importorskip("pyarrow")
56+
57+
from pandas.core.arrays.arrow.extension_types import ArrowIntervalType
58+
59+
arr = IntervalArray.from_breaks([0.0, 1.0, 2.0, 3.0])
60+
arr[1] = None
61+
62+
result = pa.array(arr)
63+
assert isinstance(result.type, ArrowIntervalType)
64+
assert result.type.closed == arr.closed
65+
assert result.type.subtype == pa.float64()
66+
67+
# fields have missing values (not NaN)
68+
left = pa.array([0.0, None, 2.0], type="float64")
69+
right = pa.array([1.0, None, 3.0], type="float64")
70+
assert result.storage.field("left").equals(left)
71+
assert result.storage.field("right").equals(right)
72+
73+
# structarray itself also has missing values on the array level
74+
vals = [
75+
{"left": 0.0, "right": 1.0},
76+
{"left": None, "right": None},
77+
{"left": 2.0, "right": 3.0},
78+
]
79+
expected = pa.StructArray.from_pandas(vals, mask=np.array([False, True, False]))
80+
assert result.storage.equals(expected)
81+
82+
83+
@pytest.mark.filterwarnings(
84+
"ignore:Passing a BlockManager to DataFrame:DeprecationWarning"
85+
)
86+
@pytest.mark.parametrize(
87+
"breaks",
88+
[[0.0, 1.0, 2.0, 3.0], pd.date_range("2017", periods=4, freq="D")],
89+
ids=["float", "datetime64[ns]"],
90+
)
91+
def test_arrow_table_roundtrip(breaks):
92+
pa = pytest.importorskip("pyarrow")
93+
94+
from pandas.core.arrays.arrow.extension_types import ArrowIntervalType
95+
96+
arr = IntervalArray.from_breaks(breaks)
97+
arr[1] = None
98+
df = pd.DataFrame({"a": arr})
99+
100+
table = pa.table(df)
101+
assert isinstance(table.field("a").type, ArrowIntervalType)
102+
result = table.to_pandas()
103+
assert isinstance(result["a"].dtype, pd.IntervalDtype)
104+
tm.assert_frame_equal(result, df)
105+
106+
table2 = pa.concat_tables([table, table])
107+
result = table2.to_pandas()
108+
expected = pd.concat([df, df], ignore_index=True)
109+
tm.assert_frame_equal(result, expected)
110+
111+
# GH#41040
112+
table = pa.table(
113+
[pa.chunked_array([], type=table.column(0).type)], schema=table.schema
114+
)
115+
result = table.to_pandas()
116+
tm.assert_frame_equal(result, expected[0:0])
117+
118+
119+
@pytest.mark.filterwarnings(
120+
"ignore:Passing a BlockManager to DataFrame:DeprecationWarning"
121+
)
122+
@pytest.mark.parametrize(
123+
"breaks",
124+
[[0.0, 1.0, 2.0, 3.0], pd.date_range("2017", periods=4, freq="D")],
125+
ids=["float", "datetime64[ns]"],
126+
)
127+
def test_arrow_table_roundtrip_without_metadata(breaks):
128+
pa = pytest.importorskip("pyarrow")
129+
130+
arr = IntervalArray.from_breaks(breaks)
131+
arr[1] = None
132+
df = pd.DataFrame({"a": arr})
133+
134+
table = pa.table(df)
135+
# remove the metadata
136+
table = table.replace_schema_metadata()
137+
assert table.schema.metadata is None
138+
139+
result = table.to_pandas()
140+
assert isinstance(result["a"].dtype, pd.IntervalDtype)
141+
tm.assert_frame_equal(result, df)
142+
143+
144+
def test_from_arrow_from_raw_struct_array():
145+
# in case pyarrow lost the Interval extension type (eg on parquet roundtrip
146+
# with datetime64[ns] subtype, see GH-45881), still allow conversion
147+
# from arrow to IntervalArray
148+
pa = pytest.importorskip("pyarrow")
149+
150+
arr = pa.array([{"left": 0, "right": 1}, {"left": 1, "right": 2}])
151+
dtype = pd.IntervalDtype(np.dtype("int64"), closed="neither")
152+
153+
result = dtype.__from_arrow__(arr)
154+
expected = IntervalArray.from_breaks(
155+
np.array([0, 1, 2], dtype="int64"), closed="neither"
156+
)
157+
tm.assert_extension_array_equal(result, expected)
158+
159+
result = dtype.__from_arrow__(pa.chunked_array([arr]))
160+
tm.assert_extension_array_equal(result, expected)

pandas/tests/indexes/interval/test_base.py

-56
This file was deleted.

0 commit comments

Comments
 (0)