From 5385bc89f316f91f83d7a7b461eed68a5507891c Mon Sep 17 00:00:00 2001 From: LucasG0 Date: Wed, 20 Mar 2024 00:52:38 +0100 Subject: [PATCH 1/2] Fix empy slicing an array backwards by relying on slice.indices --- python/pyarrow/array.pxi | 38 +++--------------------------- python/pyarrow/tests/test_array.py | 1 + 2 files changed, 4 insertions(+), 35 deletions(-) diff --git a/python/pyarrow/array.pxi b/python/pyarrow/array.pxi index 59d2e91ef6c70..131a9e2b993c3 100644 --- a/python/pyarrow/array.pxi +++ b/python/pyarrow/array.pxi @@ -561,41 +561,9 @@ def _normalize_slice(object arrow_obj, slice key): Py_ssize_t start, stop, step Py_ssize_t n = len(arrow_obj) - step = key.step or 1 - - if key.start is None: - if step < 0: - start = n - 1 - else: - start = 0 - elif key.start < 0: - start = key.start + n - if start < 0: - start = 0 - elif key.start >= n: - start = n - else: - start = key.start - - if step < 0 and (key.stop is None or key.stop < -n): - stop = -1 - elif key.stop is None: - stop = n - elif key.stop < 0: - stop = key.stop + n - if stop < 0: # step > 0 in this case. - stop = 0 - elif key.stop >= n: - stop = n - else: - stop = key.stop - - if step != 1: - indices = np.arange(start, stop, step) - return arrow_obj.take(indices) - else: - length = max(stop - start, 0) - return arrow_obj.slice(start, length) + start, stop, step = key.indices(n) + indices = np.arange(start, stop, step) + return arrow_obj.take(indices) cdef Py_ssize_t _normalize_index(Py_ssize_t index, diff --git a/python/pyarrow/tests/test_array.py b/python/pyarrow/tests/test_array.py index 60794ebef3281..472a6c5dce750 100644 --- a/python/pyarrow/tests/test_array.py +++ b/python/pyarrow/tests/test_array.py @@ -486,6 +486,7 @@ def test_array_slice_negative_step(): slice(None, None, 2), slice(0, 10, 2), slice(15, -25, -1), # GH-38768 + slice(-22, -22, -1), # GH-40642 ] for case in cases: From b9df1e60a3b5704d22072e58dab2c476cdffad8e Mon Sep 17 00:00:00 2001 From: LucasG0 Date: Mon, 25 Mar 2024 01:04:41 +0100 Subject: [PATCH 2/2] Use zero-copy slice when step=1 --- python/pyarrow/array.pxi | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/python/pyarrow/array.pxi b/python/pyarrow/array.pxi index 131a9e2b993c3..45fd29ad3b3f3 100644 --- a/python/pyarrow/array.pxi +++ b/python/pyarrow/array.pxi @@ -562,8 +562,13 @@ def _normalize_slice(object arrow_obj, slice key): Py_ssize_t n = len(arrow_obj) start, stop, step = key.indices(n) - indices = np.arange(start, stop, step) - return arrow_obj.take(indices) + + if step != 1: + indices = np.arange(start, stop, step) + return arrow_obj.take(indices) + else: + length = max(stop - start, 0) + return arrow_obj.slice(start, length) cdef Py_ssize_t _normalize_index(Py_ssize_t index,