test_arraypad.py 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427
  1. """Tests for the array padding functions.
  2. """
  3. import pytest
  4. import numpy as np
  5. from numpy.lib._arraypad_impl import _as_pairs
  6. from numpy.testing import assert_allclose, assert_array_equal, assert_equal
  7. _numeric_dtypes = (
  8. np._core.sctypes["uint"]
  9. + np._core.sctypes["int"]
  10. + np._core.sctypes["float"]
  11. + np._core.sctypes["complex"]
  12. )
  13. _all_modes = {
  14. 'constant': {'constant_values': 0},
  15. 'edge': {},
  16. 'linear_ramp': {'end_values': 0},
  17. 'maximum': {'stat_length': None},
  18. 'mean': {'stat_length': None},
  19. 'median': {'stat_length': None},
  20. 'minimum': {'stat_length': None},
  21. 'reflect': {'reflect_type': 'even'},
  22. 'symmetric': {'reflect_type': 'even'},
  23. 'wrap': {},
  24. 'empty': {}
  25. }
  26. class TestAsPairs:
  27. def test_single_value(self):
  28. """Test casting for a single value."""
  29. expected = np.array([[3, 3]] * 10)
  30. for x in (3, [3], [[3]]):
  31. result = _as_pairs(x, 10)
  32. assert_equal(result, expected)
  33. # Test with dtype=object
  34. obj = object()
  35. assert_equal(
  36. _as_pairs(obj, 10),
  37. np.array([[obj, obj]] * 10)
  38. )
  39. def test_two_values(self):
  40. """Test proper casting for two different values."""
  41. # Broadcasting in the first dimension with numbers
  42. expected = np.array([[3, 4]] * 10)
  43. for x in ([3, 4], [[3, 4]]):
  44. result = _as_pairs(x, 10)
  45. assert_equal(result, expected)
  46. # and with dtype=object
  47. obj = object()
  48. assert_equal(
  49. _as_pairs(["a", obj], 10),
  50. np.array([["a", obj]] * 10)
  51. )
  52. # Broadcasting in the second / last dimension with numbers
  53. assert_equal(
  54. _as_pairs([[3], [4]], 2),
  55. np.array([[3, 3], [4, 4]])
  56. )
  57. # and with dtype=object
  58. assert_equal(
  59. _as_pairs([["a"], [obj]], 2),
  60. np.array([["a", "a"], [obj, obj]])
  61. )
  62. def test_with_none(self):
  63. expected = ((None, None), (None, None), (None, None))
  64. assert_equal(
  65. _as_pairs(None, 3, as_index=False),
  66. expected
  67. )
  68. assert_equal(
  69. _as_pairs(None, 3, as_index=True),
  70. expected
  71. )
  72. def test_pass_through(self):
  73. """Test if `x` already matching desired output are passed through."""
  74. expected = np.arange(12).reshape((6, 2))
  75. assert_equal(
  76. _as_pairs(expected, 6),
  77. expected
  78. )
  79. def test_as_index(self):
  80. """Test results if `as_index=True`."""
  81. assert_equal(
  82. _as_pairs([2.6, 3.3], 10, as_index=True),
  83. np.array([[3, 3]] * 10, dtype=np.intp)
  84. )
  85. assert_equal(
  86. _as_pairs([2.6, 4.49], 10, as_index=True),
  87. np.array([[3, 4]] * 10, dtype=np.intp)
  88. )
  89. for x in (-3, [-3], [[-3]], [-3, 4], [3, -4], [[-3, 4]], [[4, -3]],
  90. [[1, 2]] * 9 + [[1, -2]]):
  91. with pytest.raises(ValueError, match="negative values"):
  92. _as_pairs(x, 10, as_index=True)
  93. def test_exceptions(self):
  94. """Ensure faulty usage is discovered."""
  95. with pytest.raises(ValueError, match="more dimensions than allowed"):
  96. _as_pairs([[[3]]], 10)
  97. with pytest.raises(ValueError, match="could not be broadcast"):
  98. _as_pairs([[1, 2], [3, 4]], 3)
  99. with pytest.raises(ValueError, match="could not be broadcast"):
  100. _as_pairs(np.ones((2, 3)), 3)
  101. class TestConditionalShortcuts:
  102. @pytest.mark.parametrize("mode", _all_modes.keys())
  103. def test_zero_padding_shortcuts(self, mode):
  104. test = np.arange(120).reshape(4, 5, 6)
  105. pad_amt = [(0, 0) for _ in test.shape]
  106. assert_array_equal(test, np.pad(test, pad_amt, mode=mode))
  107. @pytest.mark.parametrize("mode", ['maximum', 'mean', 'median', 'minimum',])
  108. def test_shallow_statistic_range(self, mode):
  109. test = np.arange(120).reshape(4, 5, 6)
  110. pad_amt = [(1, 1) for _ in test.shape]
  111. assert_array_equal(np.pad(test, pad_amt, mode='edge'),
  112. np.pad(test, pad_amt, mode=mode, stat_length=1))
  113. @pytest.mark.parametrize("mode", ['maximum', 'mean', 'median', 'minimum',])
  114. def test_clip_statistic_range(self, mode):
  115. test = np.arange(30).reshape(5, 6)
  116. pad_amt = [(3, 3) for _ in test.shape]
  117. assert_array_equal(np.pad(test, pad_amt, mode=mode),
  118. np.pad(test, pad_amt, mode=mode, stat_length=30))
  119. class TestStatistic:
  120. def test_check_mean_stat_length(self):
  121. a = np.arange(100).astype('f')
  122. a = np.pad(a, ((25, 20), ), 'mean', stat_length=((2, 3), ))
  123. b = np.array(
  124. [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
  125. 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
  126. 0.5, 0.5, 0.5, 0.5, 0.5,
  127. 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.,
  128. 10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
  129. 20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
  130. 30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
  131. 40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
  132. 50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
  133. 60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
  134. 70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
  135. 80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
  136. 90., 91., 92., 93., 94., 95., 96., 97., 98., 99.,
  137. 98., 98., 98., 98., 98., 98., 98., 98., 98., 98.,
  138. 98., 98., 98., 98., 98., 98., 98., 98., 98., 98.
  139. ])
  140. assert_array_equal(a, b)
  141. def test_check_maximum_1(self):
  142. a = np.arange(100)
  143. a = np.pad(a, (25, 20), 'maximum')
  144. b = np.array(
  145. [99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
  146. 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
  147. 99, 99, 99, 99, 99,
  148. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  149. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  150. 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  151. 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  152. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  153. 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  154. 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
  155. 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  156. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
  157. 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
  158. 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
  159. 99, 99, 99, 99, 99, 99, 99, 99, 99, 99]
  160. )
  161. assert_array_equal(a, b)
  162. def test_check_maximum_2(self):
  163. a = np.arange(100) + 1
  164. a = np.pad(a, (25, 20), 'maximum')
  165. b = np.array(
  166. [100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
  167. 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
  168. 100, 100, 100, 100, 100,
  169. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
  170. 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
  171. 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
  172. 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  173. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
  174. 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
  175. 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
  176. 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
  177. 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
  178. 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
  179. 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
  180. 100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
  181. )
  182. assert_array_equal(a, b)
  183. def test_check_maximum_stat_length(self):
  184. a = np.arange(100) + 1
  185. a = np.pad(a, (25, 20), 'maximum', stat_length=10)
  186. b = np.array(
  187. [10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  188. 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  189. 10, 10, 10, 10, 10,
  190. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
  191. 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
  192. 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
  193. 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  194. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
  195. 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
  196. 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
  197. 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
  198. 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
  199. 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
  200. 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
  201. 100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
  202. )
  203. assert_array_equal(a, b)
  204. def test_check_minimum_1(self):
  205. a = np.arange(100)
  206. a = np.pad(a, (25, 20), 'minimum')
  207. b = np.array(
  208. [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  209. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  210. 0, 0, 0, 0, 0,
  211. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  212. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  213. 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  214. 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  215. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  216. 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  217. 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
  218. 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  219. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
  220. 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
  221. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  222. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  223. )
  224. assert_array_equal(a, b)
  225. def test_check_minimum_2(self):
  226. a = np.arange(100) + 2
  227. a = np.pad(a, (25, 20), 'minimum')
  228. b = np.array(
  229. [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  230. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  231. 2, 2, 2, 2, 2,
  232. 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
  233. 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
  234. 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  235. 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
  236. 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
  237. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
  238. 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
  239. 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
  240. 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
  241. 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
  242. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  243. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
  244. )
  245. assert_array_equal(a, b)
  246. def test_check_minimum_stat_length(self):
  247. a = np.arange(100) + 1
  248. a = np.pad(a, (25, 20), 'minimum', stat_length=10)
  249. b = np.array(
  250. [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  251. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  252. 1, 1, 1, 1, 1,
  253. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
  254. 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
  255. 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
  256. 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  257. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
  258. 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
  259. 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
  260. 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
  261. 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
  262. 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
  263. 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
  264. 91, 91, 91, 91, 91, 91, 91, 91, 91, 91]
  265. )
  266. assert_array_equal(a, b)
  267. def test_check_median(self):
  268. a = np.arange(100).astype('f')
  269. a = np.pad(a, (25, 20), 'median')
  270. b = np.array(
  271. [49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
  272. 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
  273. 49.5, 49.5, 49.5, 49.5, 49.5,
  274. 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.,
  275. 10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
  276. 20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
  277. 30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
  278. 40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
  279. 50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
  280. 60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
  281. 70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
  282. 80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
  283. 90., 91., 92., 93., 94., 95., 96., 97., 98., 99.,
  284. 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
  285. 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5]
  286. )
  287. assert_array_equal(a, b)
  288. def test_check_median_01(self):
  289. a = np.array([[3, 1, 4], [4, 5, 9], [9, 8, 2]])
  290. a = np.pad(a, 1, 'median')
  291. b = np.array(
  292. [[4, 4, 5, 4, 4],
  293. [3, 3, 1, 4, 3],
  294. [5, 4, 5, 9, 5],
  295. [8, 9, 8, 2, 8],
  296. [4, 4, 5, 4, 4]]
  297. )
  298. assert_array_equal(a, b)
  299. def test_check_median_02(self):
  300. a = np.array([[3, 1, 4], [4, 5, 9], [9, 8, 2]])
  301. a = np.pad(a.T, 1, 'median').T
  302. b = np.array(
  303. [[5, 4, 5, 4, 5],
  304. [3, 3, 1, 4, 3],
  305. [5, 4, 5, 9, 5],
  306. [8, 9, 8, 2, 8],
  307. [5, 4, 5, 4, 5]]
  308. )
  309. assert_array_equal(a, b)
  310. def test_check_median_stat_length(self):
  311. a = np.arange(100).astype('f')
  312. a[1] = 2.
  313. a[97] = 96.
  314. a = np.pad(a, (25, 20), 'median', stat_length=(3, 5))
  315. b = np.array(
  316. [ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.,
  317. 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.,
  318. 2., 2., 2., 2., 2.,
  319. 0., 2., 2., 3., 4., 5., 6., 7., 8., 9.,
  320. 10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
  321. 20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
  322. 30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
  323. 40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
  324. 50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
  325. 60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
  326. 70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
  327. 80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
  328. 90., 91., 92., 93., 94., 95., 96., 96., 98., 99.,
  329. 96., 96., 96., 96., 96., 96., 96., 96., 96., 96.,
  330. 96., 96., 96., 96., 96., 96., 96., 96., 96., 96.]
  331. )
  332. assert_array_equal(a, b)
  333. def test_check_mean_shape_one(self):
  334. a = [[4, 5, 6]]
  335. a = np.pad(a, (5, 7), 'mean', stat_length=2)
  336. b = np.array(
  337. [[4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
  338. [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
  339. [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
  340. [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
  341. [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
  342. [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
  343. [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
  344. [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
  345. [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
  346. [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
  347. [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
  348. [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
  349. [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6]]
  350. )
  351. assert_array_equal(a, b)
  352. def test_check_mean_2(self):
  353. a = np.arange(100).astype('f')
  354. a = np.pad(a, (25, 20), 'mean')
  355. b = np.array(
  356. [49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
  357. 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
  358. 49.5, 49.5, 49.5, 49.5, 49.5,
  359. 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.,
  360. 10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
  361. 20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
  362. 30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
  363. 40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
  364. 50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
  365. 60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
  366. 70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
  367. 80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
  368. 90., 91., 92., 93., 94., 95., 96., 97., 98., 99.,
  369. 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
  370. 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5]
  371. )
  372. assert_array_equal(a, b)
  373. @pytest.mark.parametrize("mode", [
  374. "mean",
  375. "median",
  376. "minimum",
  377. "maximum"
  378. ])
  379. def test_same_prepend_append(self, mode):
  380. """ Test that appended and prepended values are equal """
  381. # This test is constructed to trigger floating point rounding errors in
  382. # a way that caused gh-11216 for mode=='mean'
  383. a = np.array([-1, 2, -1]) + np.array([0, 1e-12, 0], dtype=np.float64)
  384. a = np.pad(a, (1, 1), mode)
  385. assert_equal(a[0], a[-1])
  386. @pytest.mark.parametrize("mode", ["mean", "median", "minimum", "maximum"])
  387. @pytest.mark.parametrize(
  388. "stat_length", [-2, (-2,), (3, -1), ((5, 2), (-2, 3)), ((-4,), (2,))]
  389. )
  390. def test_check_negative_stat_length(self, mode, stat_length):
  391. arr = np.arange(30).reshape((6, 5))
  392. match = "index can't contain negative values"
  393. with pytest.raises(ValueError, match=match):
  394. np.pad(arr, 2, mode, stat_length=stat_length)
  395. def test_simple_stat_length(self):
  396. a = np.arange(30)
  397. a = np.reshape(a, (6, 5))
  398. a = np.pad(a, ((2, 3), (3, 2)), mode='mean', stat_length=(3,))
  399. b = np.array(
  400. [[6, 6, 6, 5, 6, 7, 8, 9, 8, 8],
  401. [6, 6, 6, 5, 6, 7, 8, 9, 8, 8],
  402. [1, 1, 1, 0, 1, 2, 3, 4, 3, 3],
  403. [6, 6, 6, 5, 6, 7, 8, 9, 8, 8],
  404. [11, 11, 11, 10, 11, 12, 13, 14, 13, 13],
  405. [16, 16, 16, 15, 16, 17, 18, 19, 18, 18],
  406. [21, 21, 21, 20, 21, 22, 23, 24, 23, 23],
  407. [26, 26, 26, 25, 26, 27, 28, 29, 28, 28],
  408. [21, 21, 21, 20, 21, 22, 23, 24, 23, 23],
  409. [21, 21, 21, 20, 21, 22, 23, 24, 23, 23],
  410. [21, 21, 21, 20, 21, 22, 23, 24, 23, 23]]
  411. )
  412. assert_array_equal(a, b)
  413. @pytest.mark.filterwarnings("ignore:Mean of empty slice:RuntimeWarning")
  414. @pytest.mark.filterwarnings(
  415. "ignore:invalid value encountered in( scalar)? divide:RuntimeWarning"
  416. )
  417. @pytest.mark.parametrize("mode", ["mean", "median"])
  418. def test_zero_stat_length_valid(self, mode):
  419. arr = np.pad([1., 2.], (1, 2), mode, stat_length=0)
  420. expected = np.array([np.nan, 1., 2., np.nan, np.nan])
  421. assert_equal(arr, expected)
  422. @pytest.mark.parametrize("mode", ["minimum", "maximum"])
  423. def test_zero_stat_length_invalid(self, mode):
  424. match = "stat_length of 0 yields no value for padding"
  425. with pytest.raises(ValueError, match=match):
  426. np.pad([1., 2.], 0, mode, stat_length=0)
  427. with pytest.raises(ValueError, match=match):
  428. np.pad([1., 2.], 0, mode, stat_length=(1, 0))
  429. with pytest.raises(ValueError, match=match):
  430. np.pad([1., 2.], 1, mode, stat_length=0)
  431. with pytest.raises(ValueError, match=match):
  432. np.pad([1., 2.], 1, mode, stat_length=(1, 0))
  433. class TestConstant:
  434. def test_check_constant(self):
  435. a = np.arange(100)
  436. a = np.pad(a, (25, 20), 'constant', constant_values=(10, 20))
  437. b = np.array(
  438. [10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  439. 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  440. 10, 10, 10, 10, 10,
  441. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  442. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  443. 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  444. 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  445. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  446. 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  447. 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
  448. 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  449. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
  450. 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
  451. 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
  452. 20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
  453. )
  454. assert_array_equal(a, b)
  455. def test_check_constant_zeros(self):
  456. a = np.arange(100)
  457. a = np.pad(a, (25, 20), 'constant')
  458. b = np.array(
  459. [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  460. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  461. 0, 0, 0, 0, 0,
  462. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  463. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  464. 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  465. 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  466. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  467. 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  468. 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
  469. 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  470. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
  471. 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
  472. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  473. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  474. )
  475. assert_array_equal(a, b)
  476. def test_check_constant_float(self):
  477. # If input array is int, but constant_values are float, the dtype of
  478. # the array to be padded is kept
  479. arr = np.arange(30).reshape(5, 6)
  480. test = np.pad(arr, (1, 2), mode='constant',
  481. constant_values=1.1)
  482. expected = np.array(
  483. [[1, 1, 1, 1, 1, 1, 1, 1, 1],
  484. [1, 0, 1, 2, 3, 4, 5, 1, 1],
  485. [1, 6, 7, 8, 9, 10, 11, 1, 1],
  486. [1, 12, 13, 14, 15, 16, 17, 1, 1],
  487. [1, 18, 19, 20, 21, 22, 23, 1, 1],
  488. [1, 24, 25, 26, 27, 28, 29, 1, 1],
  489. [1, 1, 1, 1, 1, 1, 1, 1, 1],
  490. [1, 1, 1, 1, 1, 1, 1, 1, 1]]
  491. )
  492. assert_allclose(test, expected)
  493. def test_check_constant_float2(self):
  494. # If input array is float, and constant_values are float, the dtype of
  495. # the array to be padded is kept - here retaining the float constants
  496. arr = np.arange(30).reshape(5, 6)
  497. arr_float = arr.astype(np.float64)
  498. test = np.pad(arr_float, ((1, 2), (1, 2)), mode='constant',
  499. constant_values=1.1)
  500. expected = np.array(
  501. [[1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1],
  502. [1.1, 0. , 1. , 2. , 3. , 4. , 5. , 1.1, 1.1], # noqa: E203
  503. [1.1, 6. , 7. , 8. , 9. , 10. , 11. , 1.1, 1.1], # noqa: E203
  504. [1.1, 12. , 13. , 14. , 15. , 16. , 17. , 1.1, 1.1], # noqa: E203
  505. [1.1, 18. , 19. , 20. , 21. , 22. , 23. , 1.1, 1.1], # noqa: E203
  506. [1.1, 24. , 25. , 26. , 27. , 28. , 29. , 1.1, 1.1], # noqa: E203
  507. [1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1],
  508. [1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1]]
  509. )
  510. assert_allclose(test, expected)
  511. def test_check_constant_float3(self):
  512. a = np.arange(100, dtype=float)
  513. a = np.pad(a, (25, 20), 'constant', constant_values=(-1.1, -1.2))
  514. b = np.array(
  515. [-1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1,
  516. -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1,
  517. -1.1, -1.1, -1.1, -1.1, -1.1,
  518. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  519. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  520. 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  521. 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  522. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  523. 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  524. 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
  525. 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  526. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
  527. 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
  528. -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2,
  529. -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2]
  530. )
  531. assert_allclose(a, b)
  532. def test_check_constant_odd_pad_amount(self):
  533. arr = np.arange(30).reshape(5, 6)
  534. test = np.pad(arr, ((1,), (2,)), mode='constant',
  535. constant_values=3)
  536. expected = np.array(
  537. [[3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
  538. [3, 3, 0, 1, 2, 3, 4, 5, 3, 3],
  539. [3, 3, 6, 7, 8, 9, 10, 11, 3, 3],
  540. [3, 3, 12, 13, 14, 15, 16, 17, 3, 3],
  541. [3, 3, 18, 19, 20, 21, 22, 23, 3, 3],
  542. [3, 3, 24, 25, 26, 27, 28, 29, 3, 3],
  543. [3, 3, 3, 3, 3, 3, 3, 3, 3, 3]]
  544. )
  545. assert_allclose(test, expected)
  546. def test_check_constant_pad_2d(self):
  547. arr = np.arange(4).reshape(2, 2)
  548. test = np.pad(arr, ((1, 2), (1, 3)), mode='constant',
  549. constant_values=((1, 2), (3, 4)))
  550. expected = np.array(
  551. [[3, 1, 1, 4, 4, 4],
  552. [3, 0, 1, 4, 4, 4],
  553. [3, 2, 3, 4, 4, 4],
  554. [3, 2, 2, 4, 4, 4],
  555. [3, 2, 2, 4, 4, 4]]
  556. )
  557. assert_allclose(test, expected)
  558. def test_check_large_integers(self):
  559. uint64_max = 2 ** 64 - 1
  560. arr = np.full(5, uint64_max, dtype=np.uint64)
  561. test = np.pad(arr, 1, mode="constant", constant_values=arr.min())
  562. expected = np.full(7, uint64_max, dtype=np.uint64)
  563. assert_array_equal(test, expected)
  564. int64_max = 2 ** 63 - 1
  565. arr = np.full(5, int64_max, dtype=np.int64)
  566. test = np.pad(arr, 1, mode="constant", constant_values=arr.min())
  567. expected = np.full(7, int64_max, dtype=np.int64)
  568. assert_array_equal(test, expected)
  569. def test_check_object_array(self):
  570. arr = np.empty(1, dtype=object)
  571. obj_a = object()
  572. arr[0] = obj_a
  573. obj_b = object()
  574. obj_c = object()
  575. arr = np.pad(arr, pad_width=1, mode='constant',
  576. constant_values=(obj_b, obj_c))
  577. expected = np.empty((3,), dtype=object)
  578. expected[0] = obj_b
  579. expected[1] = obj_a
  580. expected[2] = obj_c
  581. assert_array_equal(arr, expected)
  582. def test_pad_empty_dimension(self):
  583. arr = np.zeros((3, 0, 2))
  584. result = np.pad(arr, [(0,), (2,), (1,)], mode="constant")
  585. assert result.shape == (3, 4, 4)
  586. class TestLinearRamp:
  587. def test_check_simple(self):
  588. a = np.arange(100).astype('f')
  589. a = np.pad(a, (25, 20), 'linear_ramp', end_values=(4, 5))
  590. b = np.array(
  591. [4.00, 3.84, 3.68, 3.52, 3.36, 3.20, 3.04, 2.88, 2.72, 2.56,
  592. 2.40, 2.24, 2.08, 1.92, 1.76, 1.60, 1.44, 1.28, 1.12, 0.96,
  593. 0.80, 0.64, 0.48, 0.32, 0.16,
  594. 0.00, 1.00, 2.00, 3.00, 4.00, 5.00, 6.00, 7.00, 8.00, 9.00,
  595. 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0,
  596. 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0,
  597. 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0,
  598. 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0,
  599. 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0,
  600. 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0,
  601. 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
  602. 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0,
  603. 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0,
  604. 94.3, 89.6, 84.9, 80.2, 75.5, 70.8, 66.1, 61.4, 56.7, 52.0,
  605. 47.3, 42.6, 37.9, 33.2, 28.5, 23.8, 19.1, 14.4, 9.7, 5.]
  606. )
  607. assert_allclose(a, b, rtol=1e-5, atol=1e-5)
  608. def test_check_2d(self):
  609. arr = np.arange(20).reshape(4, 5).astype(np.float64)
  610. test = np.pad(arr, (2, 2), mode='linear_ramp', end_values=(0, 0))
  611. expected = np.array(
  612. [[0., 0., 0., 0., 0., 0., 0., 0., 0.],
  613. [0., 0., 0., 0.5, 1., 1.5, 2., 1., 0.],
  614. [0., 0., 0., 1., 2., 3., 4., 2., 0.],
  615. [0., 2.5, 5., 6., 7., 8., 9., 4.5, 0.],
  616. [0., 5., 10., 11., 12., 13., 14., 7., 0.],
  617. [0., 7.5, 15., 16., 17., 18., 19., 9.5, 0.],
  618. [0., 3.75, 7.5, 8., 8.5, 9., 9.5, 4.75, 0.],
  619. [0., 0., 0., 0., 0., 0., 0., 0., 0.]])
  620. assert_allclose(test, expected)
  621. @pytest.mark.xfail(exceptions=(AssertionError,))
  622. def test_object_array(self):
  623. from fractions import Fraction
  624. arr = np.array([Fraction(1, 2), Fraction(-1, 2)])
  625. actual = np.pad(arr, (2, 3), mode='linear_ramp', end_values=0)
  626. # deliberately chosen to have a non-power-of-2 denominator such that
  627. # rounding to floats causes a failure.
  628. expected = np.array([
  629. Fraction( 0, 12),
  630. Fraction( 3, 12),
  631. Fraction( 6, 12),
  632. Fraction(-6, 12),
  633. Fraction(-4, 12),
  634. Fraction(-2, 12),
  635. Fraction(-0, 12),
  636. ])
  637. assert_equal(actual, expected)
  638. def test_end_values(self):
  639. """Ensure that end values are exact."""
  640. a = np.pad(np.ones(10).reshape(2, 5), (223, 123), mode="linear_ramp")
  641. assert_equal(a[:, 0], 0.)
  642. assert_equal(a[:, -1], 0.)
  643. assert_equal(a[0, :], 0.)
  644. assert_equal(a[-1, :], 0.)
  645. @pytest.mark.parametrize("dtype", _numeric_dtypes)
  646. def test_negative_difference(self, dtype):
  647. """
  648. Check correct behavior of unsigned dtypes if there is a negative
  649. difference between the edge to pad and `end_values`. Check both cases
  650. to be independent of implementation. Test behavior for all other dtypes
  651. in case dtype casting interferes with complex dtypes. See gh-14191.
  652. """
  653. x = np.array([3], dtype=dtype)
  654. result = np.pad(x, 3, mode="linear_ramp", end_values=0)
  655. expected = np.array([0, 1, 2, 3, 2, 1, 0], dtype=dtype)
  656. assert_equal(result, expected)
  657. x = np.array([0], dtype=dtype)
  658. result = np.pad(x, 3, mode="linear_ramp", end_values=3)
  659. expected = np.array([3, 2, 1, 0, 1, 2, 3], dtype=dtype)
  660. assert_equal(result, expected)
  661. class TestReflect:
  662. def test_check_simple(self):
  663. a = np.arange(100)
  664. a = np.pad(a, (25, 20), 'reflect')
  665. b = np.array(
  666. [25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
  667. 15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
  668. 5, 4, 3, 2, 1,
  669. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  670. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  671. 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  672. 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  673. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  674. 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  675. 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
  676. 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  677. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
  678. 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
  679. 98, 97, 96, 95, 94, 93, 92, 91, 90, 89,
  680. 88, 87, 86, 85, 84, 83, 82, 81, 80, 79]
  681. )
  682. assert_array_equal(a, b)
  683. def test_check_odd_method(self):
  684. a = np.arange(100)
  685. a = np.pad(a, (25, 20), 'reflect', reflect_type='odd')
  686. b = np.array(
  687. [-25, -24, -23, -22, -21, -20, -19, -18, -17, -16,
  688. -15, -14, -13, -12, -11, -10, -9, -8, -7, -6,
  689. -5, -4, -3, -2, -1,
  690. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  691. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  692. 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  693. 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  694. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  695. 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  696. 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
  697. 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  698. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
  699. 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
  700. 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
  701. 110, 111, 112, 113, 114, 115, 116, 117, 118, 119]
  702. )
  703. assert_array_equal(a, b)
  704. def test_check_large_pad(self):
  705. a = [[4, 5, 6], [6, 7, 8]]
  706. a = np.pad(a, (5, 7), 'reflect')
  707. b = np.array(
  708. [[7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
  709. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  710. [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
  711. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  712. [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
  713. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  714. [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
  715. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  716. [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
  717. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  718. [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
  719. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  720. [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
  721. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5]]
  722. )
  723. assert_array_equal(a, b)
  724. def test_check_shape(self):
  725. a = [[4, 5, 6]]
  726. a = np.pad(a, (5, 7), 'reflect')
  727. b = np.array(
  728. [[5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  729. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  730. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  731. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  732. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  733. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  734. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  735. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  736. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  737. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  738. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  739. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
  740. [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5]]
  741. )
  742. assert_array_equal(a, b)
  743. def test_check_01(self):
  744. a = np.pad([1, 2, 3], 2, 'reflect')
  745. b = np.array([3, 2, 1, 2, 3, 2, 1])
  746. assert_array_equal(a, b)
  747. def test_check_02(self):
  748. a = np.pad([1, 2, 3], 3, 'reflect')
  749. b = np.array([2, 3, 2, 1, 2, 3, 2, 1, 2])
  750. assert_array_equal(a, b)
  751. def test_check_03(self):
  752. a = np.pad([1, 2, 3], 4, 'reflect')
  753. b = np.array([1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3])
  754. assert_array_equal(a, b)
  755. def test_check_04(self):
  756. a = np.pad([1, 2, 3], [1, 10], 'reflect')
  757. b = np.array([2, 1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3, 2, 1])
  758. assert_array_equal(a, b)
  759. def test_check_05(self):
  760. a = np.pad([1, 2, 3, 4], [45, 10], 'reflect')
  761. b = np.array(
  762. [4, 3, 2, 1, 2, 3, 4, 3, 2, 1,
  763. 2, 3, 4, 3, 2, 1, 2, 3, 4, 3,
  764. 2, 1, 2, 3, 4, 3, 2, 1, 2, 3,
  765. 4, 3, 2, 1, 2, 3, 4, 3, 2, 1,
  766. 2, 3, 4, 3, 2, 1, 2, 3, 4, 3,
  767. 2, 1, 2, 3, 4, 3, 2, 1, 2])
  768. assert_array_equal(a, b)
  769. def test_check_06(self):
  770. a = np.pad([1, 2, 3, 4], [15, 2], 'symmetric')
  771. b = np.array(
  772. [2, 3, 4, 4, 3, 2, 1, 1, 2, 3,
  773. 4, 4, 3, 2, 1, 1, 2, 3, 4, 4,
  774. 3]
  775. )
  776. assert_array_equal(a, b)
  777. def test_check_07(self):
  778. a = np.pad([1, 2, 3, 4, 5, 6], [45, 3], 'symmetric')
  779. b = np.array(
  780. [4, 5, 6, 6, 5, 4, 3, 2, 1, 1,
  781. 2, 3, 4, 5, 6, 6, 5, 4, 3, 2,
  782. 1, 1, 2, 3, 4, 5, 6, 6, 5, 4,
  783. 3, 2, 1, 1, 2, 3, 4, 5, 6, 6,
  784. 5, 4, 3, 2, 1, 1, 2, 3, 4, 5,
  785. 6, 6, 5, 4])
  786. assert_array_equal(a, b)
  787. class TestEmptyArray:
  788. """Check how padding behaves on arrays with an empty dimension."""
  789. @pytest.mark.parametrize(
  790. # Keep parametrization ordered, otherwise pytest-xdist might believe
  791. # that different tests were collected during parallelization
  792. "mode", sorted(_all_modes.keys() - {"constant", "empty"})
  793. )
  794. def test_pad_empty_dimension(self, mode):
  795. match = ("can't extend empty axis 0 using modes other than 'constant' "
  796. "or 'empty'")
  797. with pytest.raises(ValueError, match=match):
  798. np.pad([], 4, mode=mode)
  799. with pytest.raises(ValueError, match=match):
  800. np.pad(np.ndarray(0), 4, mode=mode)
  801. with pytest.raises(ValueError, match=match):
  802. np.pad(np.zeros((0, 3)), ((1,), (0,)), mode=mode)
  803. @pytest.mark.parametrize("mode", _all_modes.keys())
  804. def test_pad_non_empty_dimension(self, mode):
  805. result = np.pad(np.ones((2, 0, 2)), ((3,), (0,), (1,)), mode=mode)
  806. assert result.shape == (8, 0, 4)
  807. class TestSymmetric:
  808. def test_check_simple(self):
  809. a = np.arange(100)
  810. a = np.pad(a, (25, 20), 'symmetric')
  811. b = np.array(
  812. [24, 23, 22, 21, 20, 19, 18, 17, 16, 15,
  813. 14, 13, 12, 11, 10, 9, 8, 7, 6, 5,
  814. 4, 3, 2, 1, 0,
  815. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  816. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  817. 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  818. 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  819. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  820. 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  821. 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
  822. 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  823. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
  824. 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
  825. 99, 98, 97, 96, 95, 94, 93, 92, 91, 90,
  826. 89, 88, 87, 86, 85, 84, 83, 82, 81, 80]
  827. )
  828. assert_array_equal(a, b)
  829. def test_check_odd_method(self):
  830. a = np.arange(100)
  831. a = np.pad(a, (25, 20), 'symmetric', reflect_type='odd')
  832. b = np.array(
  833. [-24, -23, -22, -21, -20, -19, -18, -17, -16, -15,
  834. -14, -13, -12, -11, -10, -9, -8, -7, -6, -5,
  835. -4, -3, -2, -1, 0,
  836. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  837. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  838. 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  839. 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  840. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  841. 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  842. 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
  843. 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  844. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
  845. 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
  846. 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
  847. 109, 110, 111, 112, 113, 114, 115, 116, 117, 118]
  848. )
  849. assert_array_equal(a, b)
  850. def test_check_large_pad(self):
  851. a = [[4, 5, 6], [6, 7, 8]]
  852. a = np.pad(a, (5, 7), 'symmetric')
  853. b = np.array(
  854. [[5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  855. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  856. [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
  857. [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
  858. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  859. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  860. [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
  861. [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
  862. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  863. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  864. [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
  865. [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
  866. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  867. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6]]
  868. )
  869. assert_array_equal(a, b)
  870. def test_check_large_pad_odd(self):
  871. a = [[4, 5, 6], [6, 7, 8]]
  872. a = np.pad(a, (5, 7), 'symmetric', reflect_type='odd')
  873. b = np.array(
  874. [[-3, -2, -2, -1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6],
  875. [-3, -2, -2, -1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6],
  876. [-1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8],
  877. [-1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8],
  878. [ 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10],
  879. [ 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10],
  880. [ 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12],
  881. [ 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12],
  882. [ 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14],
  883. [ 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14],
  884. [ 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16],
  885. [ 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16],
  886. [ 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18],
  887. [ 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18]]
  888. )
  889. assert_array_equal(a, b)
  890. def test_check_shape(self):
  891. a = [[4, 5, 6]]
  892. a = np.pad(a, (5, 7), 'symmetric')
  893. b = np.array(
  894. [[5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  895. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  896. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  897. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  898. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  899. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  900. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  901. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  902. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  903. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  904. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  905. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
  906. [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6]]
  907. )
  908. assert_array_equal(a, b)
  909. def test_check_01(self):
  910. a = np.pad([1, 2, 3], 2, 'symmetric')
  911. b = np.array([2, 1, 1, 2, 3, 3, 2])
  912. assert_array_equal(a, b)
  913. def test_check_02(self):
  914. a = np.pad([1, 2, 3], 3, 'symmetric')
  915. b = np.array([3, 2, 1, 1, 2, 3, 3, 2, 1])
  916. assert_array_equal(a, b)
  917. def test_check_03(self):
  918. a = np.pad([1, 2, 3], 6, 'symmetric')
  919. b = np.array([1, 2, 3, 3, 2, 1, 1, 2, 3, 3, 2, 1, 1, 2, 3])
  920. assert_array_equal(a, b)
  921. class TestWrap:
  922. def test_check_simple(self):
  923. a = np.arange(100)
  924. a = np.pad(a, (25, 20), 'wrap')
  925. b = np.array(
  926. [75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
  927. 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
  928. 95, 96, 97, 98, 99,
  929. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  930. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  931. 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  932. 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  933. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  934. 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  935. 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
  936. 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  937. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
  938. 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
  939. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  940. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
  941. )
  942. assert_array_equal(a, b)
  943. def test_check_large_pad(self):
  944. a = np.arange(12)
  945. a = np.reshape(a, (3, 4))
  946. a = np.pad(a, (10, 12), 'wrap')
  947. b = np.array(
  948. [[10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
  949. 11, 8, 9, 10, 11, 8, 9, 10, 11],
  950. [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
  951. 3, 0, 1, 2, 3, 0, 1, 2, 3],
  952. [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
  953. 7, 4, 5, 6, 7, 4, 5, 6, 7],
  954. [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
  955. 11, 8, 9, 10, 11, 8, 9, 10, 11],
  956. [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
  957. 3, 0, 1, 2, 3, 0, 1, 2, 3],
  958. [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
  959. 7, 4, 5, 6, 7, 4, 5, 6, 7],
  960. [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
  961. 11, 8, 9, 10, 11, 8, 9, 10, 11],
  962. [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
  963. 3, 0, 1, 2, 3, 0, 1, 2, 3],
  964. [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
  965. 7, 4, 5, 6, 7, 4, 5, 6, 7],
  966. [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
  967. 11, 8, 9, 10, 11, 8, 9, 10, 11],
  968. [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
  969. 3, 0, 1, 2, 3, 0, 1, 2, 3],
  970. [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
  971. 7, 4, 5, 6, 7, 4, 5, 6, 7],
  972. [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
  973. 11, 8, 9, 10, 11, 8, 9, 10, 11],
  974. [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
  975. 3, 0, 1, 2, 3, 0, 1, 2, 3],
  976. [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
  977. 7, 4, 5, 6, 7, 4, 5, 6, 7],
  978. [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
  979. 11, 8, 9, 10, 11, 8, 9, 10, 11],
  980. [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
  981. 3, 0, 1, 2, 3, 0, 1, 2, 3],
  982. [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
  983. 7, 4, 5, 6, 7, 4, 5, 6, 7],
  984. [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
  985. 11, 8, 9, 10, 11, 8, 9, 10, 11],
  986. [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
  987. 3, 0, 1, 2, 3, 0, 1, 2, 3],
  988. [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
  989. 7, 4, 5, 6, 7, 4, 5, 6, 7],
  990. [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
  991. 11, 8, 9, 10, 11, 8, 9, 10, 11],
  992. [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
  993. 3, 0, 1, 2, 3, 0, 1, 2, 3],
  994. [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
  995. 7, 4, 5, 6, 7, 4, 5, 6, 7],
  996. [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
  997. 11, 8, 9, 10, 11, 8, 9, 10, 11]]
  998. )
  999. assert_array_equal(a, b)
  1000. def test_check_01(self):
  1001. a = np.pad([1, 2, 3], 3, 'wrap')
  1002. b = np.array([1, 2, 3, 1, 2, 3, 1, 2, 3])
  1003. assert_array_equal(a, b)
  1004. def test_check_02(self):
  1005. a = np.pad([1, 2, 3], 4, 'wrap')
  1006. b = np.array([3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1])
  1007. assert_array_equal(a, b)
  1008. def test_pad_with_zero(self):
  1009. a = np.ones((3, 5))
  1010. b = np.pad(a, (0, 5), mode="wrap")
  1011. assert_array_equal(a, b[:-5, :-5])
  1012. def test_repeated_wrapping(self):
  1013. """
  1014. Check wrapping on each side individually if the wrapped area is longer
  1015. than the original array.
  1016. """
  1017. a = np.arange(5)
  1018. b = np.pad(a, (12, 0), mode="wrap")
  1019. assert_array_equal(np.r_[a, a, a, a][3:], b)
  1020. a = np.arange(5)
  1021. b = np.pad(a, (0, 12), mode="wrap")
  1022. assert_array_equal(np.r_[a, a, a, a][:-3], b)
  1023. def test_repeated_wrapping_multiple_origin(self):
  1024. """
  1025. Assert that 'wrap' pads only with multiples of the original area if
  1026. the pad width is larger than the original array.
  1027. """
  1028. a = np.arange(4).reshape(2, 2)
  1029. a = np.pad(a, [(1, 3), (3, 1)], mode='wrap')
  1030. b = np.array(
  1031. [[3, 2, 3, 2, 3, 2],
  1032. [1, 0, 1, 0, 1, 0],
  1033. [3, 2, 3, 2, 3, 2],
  1034. [1, 0, 1, 0, 1, 0],
  1035. [3, 2, 3, 2, 3, 2],
  1036. [1, 0, 1, 0, 1, 0]]
  1037. )
  1038. assert_array_equal(a, b)
  1039. class TestEdge:
  1040. def test_check_simple(self):
  1041. a = np.arange(12)
  1042. a = np.reshape(a, (4, 3))
  1043. a = np.pad(a, ((2, 3), (3, 2)), 'edge')
  1044. b = np.array(
  1045. [[0, 0, 0, 0, 1, 2, 2, 2],
  1046. [0, 0, 0, 0, 1, 2, 2, 2],
  1047. [0, 0, 0, 0, 1, 2, 2, 2],
  1048. [3, 3, 3, 3, 4, 5, 5, 5],
  1049. [6, 6, 6, 6, 7, 8, 8, 8],
  1050. [9, 9, 9, 9, 10, 11, 11, 11],
  1051. [9, 9, 9, 9, 10, 11, 11, 11],
  1052. [9, 9, 9, 9, 10, 11, 11, 11],
  1053. [9, 9, 9, 9, 10, 11, 11, 11]]
  1054. )
  1055. assert_array_equal(a, b)
  1056. def test_check_width_shape_1_2(self):
  1057. # Check a pad_width of the form ((1, 2),).
  1058. # Regression test for issue gh-7808.
  1059. a = np.array([1, 2, 3])
  1060. padded = np.pad(a, ((1, 2),), 'edge')
  1061. expected = np.array([1, 1, 2, 3, 3, 3])
  1062. assert_array_equal(padded, expected)
  1063. a = np.array([[1, 2, 3], [4, 5, 6]])
  1064. padded = np.pad(a, ((1, 2),), 'edge')
  1065. expected = np.pad(a, ((1, 2), (1, 2)), 'edge')
  1066. assert_array_equal(padded, expected)
  1067. a = np.arange(24).reshape(2, 3, 4)
  1068. padded = np.pad(a, ((1, 2),), 'edge')
  1069. expected = np.pad(a, ((1, 2), (1, 2), (1, 2)), 'edge')
  1070. assert_array_equal(padded, expected)
  1071. class TestEmpty:
  1072. def test_simple(self):
  1073. arr = np.arange(24).reshape(4, 6)
  1074. result = np.pad(arr, [(2, 3), (3, 1)], mode="empty")
  1075. assert result.shape == (9, 10)
  1076. assert_equal(arr, result[2:-3, 3:-1])
  1077. def test_pad_empty_dimension(self):
  1078. arr = np.zeros((3, 0, 2))
  1079. result = np.pad(arr, [(0,), (2,), (1,)], mode="empty")
  1080. assert result.shape == (3, 4, 4)
  1081. def test_legacy_vector_functionality():
  1082. def _padwithtens(vector, pad_width, iaxis, kwargs):
  1083. vector[:pad_width[0]] = 10
  1084. vector[-pad_width[1]:] = 10
  1085. a = np.arange(6).reshape(2, 3)
  1086. a = np.pad(a, 2, _padwithtens)
  1087. b = np.array(
  1088. [[10, 10, 10, 10, 10, 10, 10],
  1089. [10, 10, 10, 10, 10, 10, 10],
  1090. [10, 10, 0, 1, 2, 10, 10],
  1091. [10, 10, 3, 4, 5, 10, 10],
  1092. [10, 10, 10, 10, 10, 10, 10],
  1093. [10, 10, 10, 10, 10, 10, 10]]
  1094. )
  1095. assert_array_equal(a, b)
  1096. def test_unicode_mode():
  1097. a = np.pad([1], 2, mode='constant')
  1098. b = np.array([0, 0, 1, 0, 0])
  1099. assert_array_equal(a, b)
  1100. @pytest.mark.parametrize("mode", ["edge", "symmetric", "reflect", "wrap"])
  1101. def test_object_input(mode):
  1102. # Regression test for issue gh-11395.
  1103. a = np.full((4, 3), fill_value=None)
  1104. pad_amt = ((2, 3), (3, 2))
  1105. b = np.full((9, 8), fill_value=None)
  1106. assert_array_equal(np.pad(a, pad_amt, mode=mode), b)
  1107. class TestPadWidth:
  1108. @pytest.mark.parametrize("pad_width", [
  1109. (4, 5, 6, 7),
  1110. ((1,), (2,), (3,)),
  1111. ((1, 2), (3, 4), (5, 6)),
  1112. ((3, 4, 5), (0, 1, 2)),
  1113. ])
  1114. @pytest.mark.parametrize("mode", _all_modes.keys())
  1115. def test_misshaped_pad_width(self, pad_width, mode):
  1116. arr = np.arange(30).reshape((6, 5))
  1117. match = "operands could not be broadcast together"
  1118. with pytest.raises(ValueError, match=match):
  1119. np.pad(arr, pad_width, mode)
  1120. @pytest.mark.parametrize("mode", _all_modes.keys())
  1121. def test_misshaped_pad_width_2(self, mode):
  1122. arr = np.arange(30).reshape((6, 5))
  1123. match = ("input operand has more dimensions than allowed by the axis "
  1124. "remapping")
  1125. with pytest.raises(ValueError, match=match):
  1126. np.pad(arr, (((3,), (4,), (5,)), ((0,), (1,), (2,))), mode)
  1127. @pytest.mark.parametrize(
  1128. "pad_width", [-2, (-2,), (3, -1), ((5, 2), (-2, 3)), ((-4,), (2,))])
  1129. @pytest.mark.parametrize("mode", _all_modes.keys())
  1130. def test_negative_pad_width(self, pad_width, mode):
  1131. arr = np.arange(30).reshape((6, 5))
  1132. match = "index can't contain negative values"
  1133. with pytest.raises(ValueError, match=match):
  1134. np.pad(arr, pad_width, mode)
  1135. @pytest.mark.parametrize("pad_width, dtype", [
  1136. ("3", None),
  1137. ("word", None),
  1138. (None, None),
  1139. (object(), None),
  1140. (3.4, None),
  1141. (((2, 3, 4), (3, 2)), object),
  1142. (complex(1, -1), None),
  1143. (((-2.1, 3), (3, 2)), None),
  1144. ])
  1145. @pytest.mark.parametrize("mode", _all_modes.keys())
  1146. def test_bad_type(self, pad_width, dtype, mode):
  1147. arr = np.arange(30).reshape((6, 5))
  1148. match = "`pad_width` must be of integral type."
  1149. if dtype is not None:
  1150. # avoid DeprecationWarning when not specifying dtype
  1151. with pytest.raises(TypeError, match=match):
  1152. np.pad(arr, np.array(pad_width, dtype=dtype), mode)
  1153. else:
  1154. with pytest.raises(TypeError, match=match):
  1155. np.pad(arr, pad_width, mode)
  1156. with pytest.raises(TypeError, match=match):
  1157. np.pad(arr, np.array(pad_width), mode)
  1158. def test_pad_width_as_ndarray(self):
  1159. a = np.arange(12)
  1160. a = np.reshape(a, (4, 3))
  1161. a = np.pad(a, np.array(((2, 3), (3, 2))), 'edge')
  1162. b = np.array(
  1163. [[0, 0, 0, 0, 1, 2, 2, 2],
  1164. [0, 0, 0, 0, 1, 2, 2, 2],
  1165. [0, 0, 0, 0, 1, 2, 2, 2],
  1166. [3, 3, 3, 3, 4, 5, 5, 5],
  1167. [6, 6, 6, 6, 7, 8, 8, 8],
  1168. [9, 9, 9, 9, 10, 11, 11, 11],
  1169. [9, 9, 9, 9, 10, 11, 11, 11],
  1170. [9, 9, 9, 9, 10, 11, 11, 11],
  1171. [9, 9, 9, 9, 10, 11, 11, 11]]
  1172. )
  1173. assert_array_equal(a, b)
  1174. @pytest.mark.parametrize("pad_width", [0, (0, 0), ((0, 0), (0, 0))])
  1175. @pytest.mark.parametrize("mode", _all_modes.keys())
  1176. def test_zero_pad_width(self, pad_width, mode):
  1177. arr = np.arange(30).reshape(6, 5)
  1178. assert_array_equal(arr, np.pad(arr, pad_width, mode=mode))
  1179. @pytest.mark.parametrize("mode", _all_modes.keys())
  1180. def test_kwargs(mode):
  1181. """Test behavior of pad's kwargs for the given mode."""
  1182. allowed = _all_modes[mode]
  1183. not_allowed = {}
  1184. for kwargs in _all_modes.values():
  1185. if kwargs != allowed:
  1186. not_allowed.update(kwargs)
  1187. # Test if allowed keyword arguments pass
  1188. np.pad([1, 2, 3], 1, mode, **allowed)
  1189. # Test if prohibited keyword arguments of other modes raise an error
  1190. for key, value in not_allowed.items():
  1191. match = f"unsupported keyword arguments for mode '{mode}'"
  1192. with pytest.raises(ValueError, match=match):
  1193. np.pad([1, 2, 3], 1, mode, **{key: value})
  1194. def test_constant_zero_default():
  1195. arr = np.array([1, 1])
  1196. assert_array_equal(np.pad(arr, 2), [0, 0, 1, 1, 0, 0])
  1197. @pytest.mark.parametrize("mode", [1, "const", object(), None, True, False])
  1198. def test_unsupported_mode(mode):
  1199. match = f"mode '{mode}' is not supported"
  1200. with pytest.raises(ValueError, match=match):
  1201. np.pad([1, 2, 3], 4, mode=mode)
  1202. @pytest.mark.parametrize("mode", _all_modes.keys())
  1203. def test_non_contiguous_array(mode):
  1204. arr = np.arange(24).reshape(4, 6)[::2, ::2]
  1205. result = np.pad(arr, (2, 3), mode)
  1206. assert result.shape == (7, 8)
  1207. assert_equal(result[2:-3, 2:-3], arr)
  1208. @pytest.mark.parametrize("mode", _all_modes.keys())
  1209. def test_memory_layout_persistence(mode):
  1210. """Test if C and F order is preserved for all pad modes."""
  1211. x = np.ones((5, 10), order='C')
  1212. assert np.pad(x, 5, mode).flags["C_CONTIGUOUS"]
  1213. x = np.ones((5, 10), order='F')
  1214. assert np.pad(x, 5, mode).flags["F_CONTIGUOUS"]
  1215. @pytest.mark.parametrize("dtype", _numeric_dtypes)
  1216. @pytest.mark.parametrize("mode", _all_modes.keys())
  1217. def test_dtype_persistence(dtype, mode):
  1218. arr = np.zeros((3, 2, 1), dtype=dtype)
  1219. result = np.pad(arr, 1, mode=mode)
  1220. assert result.dtype == dtype
  1221. @pytest.mark.parametrize("input_shape, pad_width, expected_shape", [
  1222. ((3, 4, 5), {-2: (1, 3)}, (3, 4 + 1 + 3, 5)),
  1223. ((3, 4, 5), {0: (5, 2)}, (3 + 5 + 2, 4, 5)),
  1224. ((3, 4, 5), {0: (5, 2), -1: (3, 4)}, (3 + 5 + 2, 4, 5 + 3 + 4)),
  1225. ((3, 4, 5), {1: 5}, (3, 4 + 2 * 5, 5)),
  1226. ])
  1227. def test_pad_dict_pad_width(input_shape, pad_width, expected_shape):
  1228. a = np.zeros(input_shape)
  1229. result = np.pad(a, pad_width)
  1230. assert result.shape == expected_shape