8000 Merge pull request #7346 from erensezener/generalized_flip · numpy/numpy@5b91628 · GitHub
[go: up one dir, main page]

Skip to content 8000

Commit 5b91628

Browse files
committed
Merge pull request #7346 from erensezener/generalized_flip
Generalized flip
2 parents f98b59e + e7de401 commit 5b91628

File tree

5 files changed

+167
-5
lines changed

5 files changed

+167
-5
lines changed

doc/release/1.12.0-notes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ keyword argument. It can be set to False when no write operation
9999
to the returned array is expected to avoid accidental
100100
unpredictable writes.
101101

102+
Generalized ``flip``
103+
~~~~~~~~~~~~~~~~~~~~
104+
``flipud`` and ``fliplr`` reverse the elements of an array along axis=0 and
105+
axis=1 respectively. The newly added ``flip`` function reverses the elements of
106+
an array along any given axis.
107+
102108

103109
BLIS support in ``numpy.distutils``
104110
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

doc/source/reference/routines.array-manipulation.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ Rearranging elements
109109
.. autosummary::
110110
:toctree: generated/
111111

112+
flip
112113
fliplr
113114
flipud
114115
reshape

numpy/lib/function_base.py

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
__all__ = [
3838
'select', 'piecewise', 'trim_zeros', 'copy', 'iterable', 'percentile',
39-
'diff', 'gradient', 'angle', 'unwrap', 'sort_complex', 'disp',
39+
'diff', 'gradient', 'angle', 'unwrap', 'sort_complex', 'disp', 'flip',
4040
'extract', 'place', 'vectorize', 'asarray_chkfinite', 'average',
4141
'histogram', 'histogramdd', 'bincount', 'digitize', 'cov', 'corrcoef',
4242
'msort', 'median', 'sinc', 'hamming', 'hanning', 'bartlett',
@@ -45,6 +45,78 @@
4545
]
4646

4747

48+
def flip(m, axis):
49+
"""
50+
Reverse the order of elements in an array along the given axis.
51+
52+
The shape of the array is preserved, but the elements are reordered.
53+
54+
.. versionadded:: 1.12.0
55+
56+
Parameters
57+
----------
58+
m : array_like
59+
Input array.
60+
axis: integer
61+
Axis in array, which entries are reversed.
62+
63+
64+
Returns
65+
-------
66+
out : array_like
67+
A view of `m` with the entries of axis reversed. Since a view is
68+
returned, this operation is done in constant time.
69+
70+
See Also
71+
--------
72+
flipud : Flip an array vertically (axis=0).
73+
fliplr : Flip an array horizontally (axis=1).
74+
75+
Notes
76+
-----
77+
flip(m, 0) is equivalent to flipud(m).
78+
flip(m, 1) is equivalent to fliplr(m).
79+
flip(m, n) corresponds to ``m[...,::-1,...]`` with ``::-1`` at position n.
80+
81+
Examples
82+
--------
83+
>>> A = np.arange(8).reshape((2,2,2))
84+
>>> A
85+
array([[[0, 1],
86+
[2, 3]],
87+
88+
[[4, 5],
89+
[6, 7]]])
90+
91+
>>> flip(A, 0)
92+
array([[[4, 5],
93+
[6, 7]],
94+
95+
[[0, 1],
96+
[2, 3]]])
97+
98+
>>> flip(A, 1)
99+
array([[[2, 3],
100+
[0, 1]],
101+
102+
[[6, 7],
103+
[4, 5]]])
104+
105+
>>> A = np.random.randn(3,4,5)
106+
>>> np.all(flip(A,2) == A[:,:,::-1,...])
107+
True
108+
"""
109+
if not hasattr(m, 'ndim'):
110+
m = asarray(m)
111+
indexer = [slice(None)] * m.ndim
112+
try:
113+
indexer[axis] = slice(None, None, -1)
114+
except IndexError:
115+
raise ValueError("axis=%i is invalid for the %i-dimensional input array"
116+
% (axis, m.ndim))
117+
return m[tuple(indexer)]
118+
119+
48120
def iterable(y):
49121
"""
50122
Check whether or not an object can be iterated over.

numpy/lib/tests/test_function_base.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,89 @@
2323
from numpy.compat import long
2424

2525

26+
def get_mat(n):
27+
data = np.arange(n)
28+
data = np.add.outer(data, data)
29+
return data
30+
31+
32+
class TestFlip(TestCase):
33+
def test_axes(self):
34+
self.assertRaises(ValueError, np.flip, np.ones(4), axis=1)
35+
self.assertRaises(ValueError, np.flip, np.ones((4, 4)), axis=2)
36+
self.assertRaises(ValueError, np.flip, np.ones((4, 4)), axis=-3)
37+
38+
def test_basic_lr(self):
39+
a = get_mat(4)
40+
b = a[:, ::-1]
41+
assert_equal(np.flip(a, 1), b)
42+
a = [[0, 1, 2],
43+
[3, 4, 5]]
44+
b = [[2, 1, 0],
45+
[5, 4, 3]]
46+
assert_equal(np.flip(a, 1), b)
47+
48+
def test_basic_ud(self):
49+
a = get_mat(4)
50+
b = a[::-1, :]
51+
assert_equal(np.flip(a, 0), b)
52+
a = [[0, 1, 2],
53+
[3, 4, 5]]
54+
b = [[3, 4, 5],
55+
[0, 1, 2]]
56+
assert_equal(np.flip(a, 0), b)
57+
58+
def test_3d_swap_axis0(self):
59+
a = np.array([[[0, 1],
60+
[2, 3]],
61+
62+
[[4, 5],
63+
[6, 7]]])
64+
65+
b = np.array([[[4, 5],
66+
[6, 7]],
67+
68+
[[0, 1],
69+
[2, 3]]])
70+
71+
assert_equal(np.flip(a, 0), b)
72+
73+
def test_3d_swap_axis1(self):
74+
a = np.array([[[0, 1],
75+
[2, 3]],
76+
77+
[[4, 5],
78+
[6, 7]]])
79+
80+
b = np.array([[[2, 3],
81+
[0, 1]],
82+
83+
[[6, 7],
84+
[4, 5]]])
85+
86+
assert_equal(np.flip(a, 1), b)
87+
88+
def test_3d_swap_axis2(self):
89+
a = np.array([[[0, 1],
90+
[2, 3]],
91+
92+
[[4, 5],
93+
[6, 7]]])
94+
95+
b = np.array([[[1, 0],
96+
[3, 2]],
97+
98+
[[5, 4],
99+
[7, 6]]])
100+
101+
assert_equal(np.flip(a, 2), b)
102+
103+
def test_4d(self):
104+
a = np.arange(2 * 3 * 4 * 5).reshape(2, 3, 4, 5)
105+
for i in range(a.ndim):
106+
assert_equal(np.flip(a, i), np.flipud(a.swapaxes(0, i)).swapaxes(i, 0))
107+
108+
26109
class TestAny(TestCase):
27110

28111
def test_basic(self):

numpy/lib/twodim_base.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def fliplr(m):
5757
5858
Notes
5959
-----
60-
Equivalent to A[:,::-1]. Requires the array to be at least 2-D.
60+
Equivalent to m[:,::-1]. Requires the array to be at least 2-D.
6161
6262
Examples
6363
--------
@@ -72,7 +72,7 @@ def fliplr(m):
7272
[ 3., 0., 0.]])
7373
7474
>>> A = np.random.randn(2,3,5)
75-
>>> np.all(np.fliplr(A)==A[:,::-1,...])
75+
>>> np.all(np.fliplr(A) == A[:,::-1,...])
7676
True
7777
7878
"""
@@ -107,7 +107,7 @@ def flipud(m):
107107
108108
Notes
109109
-----
110-
Equivalent to ``A[::-1,...]``.
110+
Equivalent to ``m[::-1,...]``.
111111
Does not require the array to be two-dimensional.
112112
113113
Examples
@@ -123,7 +123,7 @@ def flipud(m):
123123
[ 1., 0., 0.]])
124124
125125
>>> A = np.random.randn(2,3,5)
126-
>>> np.all(np.flipud(A)==A[::-1,...])
126+
>>> np.all(np.flipud(A) == A[::-1,...])
127127
True
128128
129129
>>> np.flipud([1,2])

0 commit comments

Comments
 (0)
0