Skip to content

Commit 103f4dd

Browse files
authored
Merge pull request #26697 from charris/backport-25963
BUG: Fix bug in numpy.pad()
2 parents c193dcd + 8fa8191 commit 103f4dd

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

numpy/lib/_arraypad_impl.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,8 @@ def _get_stats(padded, axis, width_pair, length_pair, stat_func):
293293
return left_stat, right_stat
294294

295295

296-
def _set_reflect_both(padded, axis, width_pair, method, include_edge=False):
296+
def _set_reflect_both(padded, axis, width_pair, method,
297+
original_period, include_edge=False):
297298
"""
298299
Pad `axis` of `arr` with reflection.
299300
@@ -308,6 +309,8 @@ def _set_reflect_both(padded, axis, width_pair, method, include_edge=False):
308309
dimension.
309310
method : str
310311
Controls method of reflection; options are 'even' or 'odd'.
312+
original_period : int
313+
Original length of data on `axis` of `arr`.
311314
include_edge : bool
312315
If true, edge value is included in reflection, otherwise the edge
313316
value forms the symmetric axis to the reflection.
@@ -320,11 +323,20 @@ def _set_reflect_both(padded, axis, width_pair, method, include_edge=False):
320323
"""
321324
left_pad, right_pad = width_pair
322325
old_length = padded.shape[axis] - right_pad - left_pad
323-
326+
324327
if include_edge:
328+
# Avoid wrapping with only a subset of the original area
329+
# by ensuring period can only be a multiple of the original
330+
# area's length.
331+
old_length = old_length // original_period * original_period
325332
# Edge is included, we need to offset the pad amount by 1
326333
edge_offset = 1
327334
else:
335+
# Avoid wrapping with only a subset of the original area
336+
# by ensuring period can only be a multiple of the original
337+
# area's length.
338+
old_length = ((old_length - 1) // (original_period - 1)
339+
* (original_period - 1) + 1)
328340
edge_offset = 0 # Edge is not included, no need to offset pad amount
329341
old_length -= 1 # but must be omitted from the chunk
330342

@@ -865,7 +877,7 @@ def pad(array, pad_width, mode='constant', **kwargs):
865877
# the length of the original values in the current dimension.
866878
left_index, right_index = _set_reflect_both(
867879
roi, axis, (left_index, right_index),
868-
method, include_edge
880+
method, array.shape[axis], include_edge
869881
)
870882

871883
elif mode == "wrap":

numpy/lib/tests/test_arraypad.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,42 @@ def test_check_03(self):
867867
a = np.pad([1, 2, 3], 4, 'reflect')
868868
b = np.array([1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3])
869869
assert_array_equal(a, b)
870+
871+
def test_check_04(self):
872+
a = np.pad([1, 2, 3], [1, 10], 'reflect')
873+
b = np.array([2, 1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3, 2, 1])
874+
assert_array_equal(a, b)
875+
876+
def test_check_05(self):
877+
a = np.pad([1, 2, 3, 4], [45, 10], 'reflect')
878+
b = np.array(
879+
[4, 3, 2, 1, 2, 3, 4, 3, 2, 1,
880+
2, 3, 4, 3, 2, 1, 2, 3, 4, 3,
881+
2, 1, 2, 3, 4, 3, 2, 1, 2, 3,
882+
4, 3, 2, 1, 2, 3, 4, 3, 2, 1,
883+
2, 3, 4, 3, 2, 1, 2, 3, 4, 3,
884+
2, 1, 2, 3, 4, 3, 2, 1, 2])
885+
assert_array_equal(a, b)
886+
887+
def test_check_06(self):
888+
a = np.pad([1, 2, 3, 4], [15, 2], 'symmetric')
889+
b = np.array(
890+
[2, 3, 4, 4, 3, 2, 1, 1, 2, 3,
891+
4, 4, 3, 2, 1, 1, 2, 3, 4, 4,
892+
3]
893+
)
894+
assert_array_equal(a, b)
895+
896+
def test_check_07(self):
897+
a = np.pad([1, 2, 3, 4, 5, 6], [45, 3], 'symmetric')
898+
b = np.array(
899+
[4, 5, 6, 6, 5, 4, 3, 2, 1, 1,
900+
2, 3, 4, 5, 6, 6, 5, 4, 3, 2,
901+
1, 1, 2, 3, 4, 5, 6, 6, 5, 4,
902+
3, 2, 1, 1, 2, 3, 4, 5, 6, 6,
903+
5, 4, 3, 2, 1, 1, 2, 3, 4, 5,
904+
6, 6, 5, 4])
905+
assert_array_equal(a, b)
870906

871907

872908
class TestEmptyArray:

0 commit comments

Comments
 (0)