def __from_arrow__( self, array: pyarrow.Array | pyarrow.ChunkedArray) -> IntervalArray: """ Construct IntervalArray from pyarrow Array/ChunkedArray. """ import pyarrow from pandas.core.arrays import IntervalArray if isinstance(array, pyarrow.Array): chunks = [array] else: chunks = array.chunks results = [] for arr in chunks: left = np.asarray(arr.storage.field("left"), dtype=self.subtype) right = np.asarray(arr.storage.field("right"), dtype=self.subtype) iarr = IntervalArray.from_arrays(left, right, closed=array.type.closed) results.append(iarr) if not results: return IntervalArray.from_arrays( np.array([], dtype=self.subtype), np.array([], dtype=self.subtype), closed=array.type.closed, ) return IntervalArray._concat_same_type(results)
def test_set_na(self, left_right_dtypes): left, right = left_right_dtypes left = left.copy(deep=True) right = right.copy(deep=True) result = IntervalArray.from_arrays(left, right) if result.dtype.subtype.kind not in ["m", "M"]: msg = "'value' should be an interval type, got <.*NaTType'> instead." with pytest.raises(TypeError, match=msg): result[0] = pd.NaT if result.dtype.subtype.kind in ["i", "u"]: msg = "Cannot set float NaN to integer-backed IntervalArray" # GH#45484 TypeError, not ValueError, matches what we get with # non-NA un-holdable value. with pytest.raises(TypeError, match=msg): result[0] = np.NaN return result[0] = np.nan expected_left = Index([left._na_value] + list(left[1:])) expected_right = Index([right._na_value] + list(right[1:])) expected = IntervalArray.from_arrays(expected_left, expected_right) tm.assert_extension_array_equal(result, expected)
def test_set_na(self, left_right_dtypes): left, right = left_right_dtypes result = IntervalArray.from_arrays(left, right) result[0] = np.nan expected_left = Index([left._na_value] + list(left[1:])) expected_right = Index([right._na_value] + list(right[1:])) expected = IntervalArray.from_arrays(expected_left, expected_right) tm.assert_extension_array_equal(result, expected)
def test_set_na(self, left_right_dtypes): left, right = left_right_dtypes result = IntervalArray.from_arrays(left, right) result[0] = np.nan expected_left = Index([left._na_value] + list(left[1:])) expected_right = Index([right._na_value] + list(right[1:])) expected = IntervalArray.from_arrays(expected_left, expected_right) self.assert_extension_array_equal(result, expected)
def test_compare_scalar_interval_mixed_closed(self, op, closed, other_closed): interval_array = IntervalArray.from_arrays(range(2), range(1, 3), closed=closed) other = Interval(0, 1, closed=other_closed) result = op(interval_array, other) expected = self.elementwise_comparison(op, interval_array, other) tm.assert_numpy_array_equal(result, expected)
def test_set_na(self, left_right_dtypes): left, right = left_right_dtypes result = IntervalArray.from_arrays(left, right) if result.dtype.subtype.kind in ["i", "u"]: msg = "Cannot set float NaN to integer-backed IntervalArray" with pytest.raises(ValueError, match=msg): result[0] = np.NaN return result[0] = np.nan expected_left = Index([left._na_value] + list(left[1:])) expected_right = Index([right._na_value] + list(right[1:])) expected = IntervalArray.from_arrays(expected_left, expected_right) tm.assert_extension_array_equal(result, expected)
def test_compare_list_like_interval_mixed_closed( self, op, interval_constructor, closed, other_closed ): interval_array = IntervalArray.from_arrays(range(2), range(1, 3), closed=closed) other = interval_constructor(range(2), range(1, 3), closed=other_closed) result = op(interval_array, other) expected = self.elementwise_comparison(op, interval_array, other) tm.assert_equal(result, expected)
def test_min_max_invalid_axis(self, left_right_dtypes): left, right = left_right_dtypes left = left.copy(deep=True) right = right.copy(deep=True) arr = IntervalArray.from_arrays(left, right) msg = "`axis` must be fewer than the number of dimensions" for axis in [-2, 1]: with pytest.raises(ValueError, match=msg): arr.min(axis=axis) with pytest.raises(ValueError, match=msg): arr.max(axis=axis) msg = "'>=' not supported between" with pytest.raises(TypeError, match=msg): arr.min(axis="foo") with pytest.raises(TypeError, match=msg): arr.max(axis="foo")
def test_min_max(self, left_right_dtypes, index_or_series_or_array): # GH#44746 left, right = left_right_dtypes left = left.copy(deep=True) right = right.copy(deep=True) arr = IntervalArray.from_arrays(left, right) # The expected results below are only valid if monotonic assert left.is_monotonic_increasing assert Index(arr).is_monotonic_increasing MIN = arr[0] MAX = arr[-1] indexer = np.arange(len(arr)) np.random.shuffle(indexer) arr = arr.take(indexer) arr_na = arr.insert(2, np.nan) arr = index_or_series_or_array(arr) arr_na = index_or_series_or_array(arr_na) for skipna in [True, False]: res = arr.min(skipna=skipna) assert res == MIN assert type(res) == type(MIN) res = arr.max(skipna=skipna) assert res == MAX assert type(res) == type(MAX) res = arr_na.min(skipna=False) assert np.isnan(res) res = arr_na.max(skipna=False) assert np.isnan(res) res = arr_na.min(skipna=True) assert res == MIN assert type(res) == type(MIN) res = arr_na.max(skipna=True) assert res == MAX assert type(res) == type(MAX)
def create_series_intervals(left, right, closed="right"): return Series(IntervalArray.from_arrays(left, right, closed))
def array(left_right_dtypes): """ Fixture to generate an IntervalArray of various dtypes containing NA if possible """ left, right = left_right_dtypes return IntervalArray.from_arrays(left, right)
def test_compare_length_mismatch_errors(self, op, other_constructor, length): array = IntervalArray.from_arrays(range(4), range(1, 5)) other = other_constructor([Interval(0, 1)] * length) with pytest.raises(ValueError, match="Lengths must match to compare"): op(array, other)
def test_repeat(self, left_right_dtypes, repeats): left, right = left_right_dtypes result = IntervalArray.from_arrays(left, right).repeat(repeats) expected = IntervalArray.from_arrays(left.repeat(repeats), right.repeat(repeats)) tm.assert_extension_array_equal(result, expected)
def test_repeat(self, left_right_dtypes, repeats): left, right = left_right_dtypes result = IntervalArray.from_arrays(left, right).repeat(repeats) expected = IntervalArray.from_arrays( left.repeat(repeats), right.repeat(repeats)) tm.assert_extension_array_equal(result, expected)
def test_from_arrays_deprecation(): # GH#40245 with tm.assert_produces_warning(FutureWarning): IntervalArray.from_arrays([0, 1, 2], [1, 2, 3], closed="right")