Numpy quick start - advanced array operation

Posted by n_wattam on Tue, 08 Feb 2022 16:45:31 +0100

1, Change the shape of the array

functioneffect
np.reshape(a, newshape)a is an array and newshape is an integer tuple; Returns an array of newshape shapes
np.ravel(a)Flatten into a one-dimensional array; Equivalent to NP reshape(a, -1)
np.flatten(a)The effect is the same as that of t ravel, but flatten is more recommended

1.1 np.reshape()

A = np.arange(6).reshape((2, 3))
print(A)
# [[0 1 2]
#  [3 4 5]]

In fact, the parentheses of the meta group can be omitted, that is, we can use reshape more concisely:

A = np.arange(6).reshape(2, 3)

A component in newshape can be - 1, and reshape will automatically calculate according to other components:

A = np.arange(6).reshape(2, -1)
print(A)
# [[0 1 2]
#  [3 4 5]]

If newshape = -1, reshape flattens it into a one-dimensional array:

A = np.arange(6).reshape(6).reshape(-1)
print(A)
# [0 1 2 3 4 5]

1.2 np.ravel()

A = np.arange(8).reshape(2, 2, 2).ravel()
print(A)
# [0 1 2 3 4 5 6 7]

1.3 np.flatten()

A = np.arange(8).reshape(2, 2, 2).flatten()
print(A)
# [0 1 2 3 4 5 6 7]

It can be seen that the effect of flatten is the same as that of t ravel. Which one is better?

Direct answer: using flatten is better. See for specific reasons Blog.

2, Transpose operation

functioneffect
ndarray.TTranspose an array, that is, invert the shape
np.swapaxes(a, axis1, axis2)Swap the two axes of the array
np.moveaxis(a, s, d)S and d are integer or integer lists; Move the axis with index s to index d

2.1 ndarray.T

A = np.arange(6).reshape(2, 3)
print(A)
print(A.T)
# [[0 1 2]
#  [3 4 5]]
# [[0 3]
#  [1 4]
#  [2 5]]

But be careful, ndarray T cannot transpose a one-dimensional array:

A = np.arange(6)
print(A)
print(A.T)
# [0 1 2 3 4 5]
# [0 1 2 3 4 5]

So how do we transpose a one-dimensional array? There are several methods:

Method 1: first convert to a two-dimensional array

Turn ndarray into a two-dimensional array and transpose it:

A = np.arange(4)
A = np.array([A])
print(A.T)
# [[0]
#  [1]
#  [2]
#  [3]]

Of course, you can also use NP Transfer (), which is the same as ndarray T equivalent:

A = np.arange(4)
print(np.transpose([A]))
# [[0]
#  [1]
#  [2]
#  [3]]

Method 2: use reshape function

A = np.arange(4)
A = A.reshape(len(A), -1)  # The second parameter can also be changed to 1
print(A)
# [[0]
#  [1]
#  [2]
#  [3]]

Method 3: use newaxis

We mentioned NP in the first article in this series Newaxis, here we will further explain its usage

The essence of newaxis is None:

print(np.newaxis == None)
# True

Just like its name, the combination of newaxis and slice can add a new dimension (axis) to the array. It can change one-dimensional array into two-dimensional array, two-dimensional array into three-dimensional array, or directly change one-dimensional array into three-dimensional array.

Remember: the length along the axis of newaxis will be 1

It may not be easy to understand. Here are A few examples. Suppose A is A one-dimensional array with A length of 3, then:

  • A [NP. Newaxis,:]: if newaxis is on the first axis, the result is a 1 × 3 1\times 3 one × Array of 3.
  • A [:, NP. Newaxis]: if newaxis is on the second axis, the result is a 3 × 1 3\times1 three × Array of 1.
  • A [:, NP. Newaxis]: if newaxis is located on the second axis and the third axis, the result is a 3 × 1 × 1 3\times1\times1 three × one × Array of 1.

Let's give a few more examples and combine the shape method to further illustrate the effect of newaxis.

First create a 3 × 4 3\times4 three × Array of 4:

A = np.arange(12).reshape(3, 4)
print(A.shape)
# (3, 4)

Then use newaxis to add a new axis:

print(A[:, :, np.newaxis].shape)
print(A[:, np.newaxis, :].shape)
print(A[np.newaxis, :, :].shape)
print(A[np.newaxis, np.newaxis, :, :].shape)
# (3, 4, 1)
# (3, 1, 4)
# (1, 3, 4)
# (1, 1, 3, 4)

After reading these examples, I believe you have a basic understanding of newaxis, so how to transpose a dimensional array is no longer difficult.

Because the transposed one-dimensional array must be shaped like a × 1 a\times 1 a × 1, so newaxis must be located on the second axis, so you only need A[:, np.newaxis] to transpose:

A = np.arange(4)
print(A[:, np.newaxis])
# [[0]
#  [1]
#  [2]
#  [3]]

2.2 np.swapaxes()

A = np.zeros((3, 4, 5))
print(A.shape)
# (3, 4, 5)
print(np.swapaxes(A, 0, 1).shape)
print(np.swapaxes(A, 0, 2).shape)
print(np.swapaxes(A, 1, 2).shape)
# (4, 3, 5)
# (5, 4, 3)
# (3, 5, 4)

2.3 np.moveaxis()

When both s and d are integers:

A = np.zeros((3, 4, 5))
print(np.moveaxis(A, 0, 2).shape)
print(np.moveaxis(A, 0, -1).shape)
print(np.moveaxis(A, -1, -2).shape)
# (4, 5, 3)
# (4, 5, 3)
# (3, 5, 4)

When both s and d are integer lists:

A = np.zeros((3, 4, 5))
print(np.moveaxis(A, [0, 1], [1, 2]).shape)
print(np.moveaxis(A, [0, 1], [0, 2]).shape)
print(np.moveaxis(A, [1, 0], [0, 2]).shape)
# (5, 3, 4)
# (3, 5, 4)
# (4, 5, 3)

3, Merge array

functioneffect
np.concatenate((a1, a2, ...), axis=0)a1, a2, etc. are arrays, and axis controls the direction of connection; Used to connect multiple arrays together. When axis is None, the arrays to be connected will be flattened before connection
np.stack(arrays, axis=0)Arrays is a list or tuple composed of arrays; Stack these arrays in the axis direction
np.block(arrays)Combine several arrays to form a new array; It is often used to build block matrix
np.vstack((a1, a2, ...))Vertically stacked array
np.hstack((a1, a2, ...))Horizontally stacked array

3.1 np.concatenate()

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
print(np.concatenate((a, b), axis=0))
# [[1 2]
#  [3 4]
#  [5 6]]
print(np.concatenate((a, b.T), axis=1))
# [[1 2 5]
#  [3 4 6]]
print(np.concatenate((a, b), axis=None))
# [1 2 3 4 5 6]

To join two one-dimensional arrays, simply:

a = np.array([1, 2])
b = np.array([3, 4])
print(np.concatenate((a, b)))
# [1 2 3 4]

3.2 np.stack()

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(np.stack((a, b)))
# [[1 2 3]
#  [4 5 6]]
print(np.stack((a, b), axis=1))
# [[1 4]
#  [2 5]
#  [3 6]]
arrays = [np.zeros((2, 3)) for _ in range(4)]
print(np.stack(arrays, axis=0).shape)
print(np.stack(arrays, axis=1).shape)
print(np.stack(arrays, axis=2).shape)
# (4, 2, 3)
# (2, 4, 3)
# (2, 3, 4)

Note that axis=2 is actually the last axis. We can also replace it with axis=-1. The effect is the same. Other axes can also be pushed like this:

print(np.stack(arrays, axis=-3).shape)
print(np.stack(arrays, axis=-2).shape)
print(np.stack(arrays, axis=-1).shape)
# (4, 2, 3)
# (2, 4, 3)
# (2, 3, 4)

3.3 np.block()

A = np.eye(2) * 2
B = np.eye(3) * 3
C = np.block([
		  [A,               np.zeros((2, 3))], 
          [np.ones((3, 2)), B               ]
    ])
print(C)
# [[2. 0. 0. 0. 0.]
#  [0. 2. 0. 0. 0.]
#  [1. 1. 3. 0. 0.]
#  [1. 1. 0. 3. 0.]
#  [1. 1. 0. 0. 3.]]

3.3 np.vstack()

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(np.vstack((a, b)))
# [[1 2 3]
#  [4 5 6]]

More vivid explanation: because it is stacked vertically, so B B B on A A A below

A = [ 1 , 2 , 3 ] , B = [ 4 , 5 , 6 ] A=[1, 2, 3],\quad B=[4,5,6] A=[1,2,3],B=[4,5,6]

a = np.array([[1], [2], [3]])
b = np.array([[4], [5], [6]])
print(np.vstack((a, b)))
# [[1]
#  [2]
#  [3]
#  [4]
#  [5]
#  [6]]

Similarly B B B on A A A below

A = [ 1 2 3 ] , B = [ 4 5 6 ] A=\begin{bmatrix} 1 \\ 2\\ 3 \\ \end{bmatrix} ,\quad B=\begin{bmatrix} 4 \\ 5\\ 6 \\ \end{bmatrix} A=⎣⎡​123​⎦⎤​,B=⎣⎡​456​⎦⎤​

3.4 np.hstack()

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(np.hstack((a, b)))
# [1 2 3 4 5 6]

More vivid explanation: because it is stacked horizontally, so B B B on A A A right

A = [ 1 , 2 , 3 ] , B = [ 4 , 5 , 6 ] A=[1, 2, 3],\quad B=[4,5,6] A=[1,2,3],B=[4,5,6]

a = np.array([[1], [2], [3]])
b = np.array([[4], [5], [6]])
print(np.hstack((a, b)))
# [[1 4]
#  [2 5]
#  [3 6]]

Similarly B B B on A A A right

A = [ 1 2 3 ] , B = [ 4 5 6 ] A=\begin{bmatrix} 1 \\ 2\\ 3 \\ \end{bmatrix} ,\quad B=\begin{bmatrix} 4 \\ 5\\ 6 \\ \end{bmatrix} A=⎣⎡​123​⎦⎤​,B=⎣⎡​456​⎦⎤​

4, Partition array

functioneffect
np.split(a, indices/sections)Divide the array a into some sub arrays and return them in the form of list; sections is the number of subarrays, and indexes is the index list; It can be divided by quantity or index position
np.array_split(a, indices/sections)The only difference from split is that when selecting quantity division, it is not necessary to require the same shape of each subarray
np.vsplit(a, indices/sections)Vertically partitioned array
np.hsplit(a, indices/sections)Horizontally partitioned array

4.1 np.split()

Divided by quantity, each subarray has the same shape:

a = np.arange(9)
print(np.split(a, 3))
# [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
print(np.split(a, 4))
# ValueError: array split does not result in an equal division

The reason for the error is that you cannot quarter an array with length 9.

Of course, we can also divide by index:

a = np.arange(9)
print(np.split(a, [2, 5]))
# [array([0, 1]), array([2, 3, 4]), array([5, 6, 7, 8])]
print(np.split(a, [1, 3, 5, 7]))
# [array([0]), array([1, 2]), array([3, 4]), array([5, 6]), array([7, 8])]

4.2 np.array_split()

a = np.arange(9)
print(np.array_split(a, 4))
# [array([0, 1, 2]), array([3, 4]), array([5, 6]), array([7, 8])]

4.3 np.vsplit()

By quantity:

a = np.arange(16).reshape(4, 4)
print(np.vsplit(a, 2))
# [array([[0, 1, 2, 3],
#        [4, 5, 6, 7]]), array([[ 8,  9, 10, 11],
#        [12, 13, 14, 15]])]

By index:

a = np.arange(16).reshape(4, 4)
print(np.vsplit(a, [1, 2]))
# [array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8,  9, 10, 11],
#        [12, 13, 14, 15]])]

When the dimension of the array is greater than or equal to 3, the division direction is still along the first axis (row):

a = np.arange(8).reshape(2, 2, 2)
print(np.vsplit(a, 2))
# [array([[[0, 1],
#         [2, 3]]]), array([[[4, 5],
#         [6, 7]]])]

4.4 np.hsplit()

By quantity:

a = np.arange(16).reshape(4, 4)
print(np.hsplit(a, 2))
# [array([[ 0,  1],
#        [ 4,  5],
#        [ 8,  9],
#        [12, 13]]), array([[ 2,  3],
#        [ 6,  7],
#        [10, 11],
 #       [14, 15]])]

By index:

a = np.arange(16).reshape(4, 4)
print(np.hsplit(a, [1, 2]))
# [array([[ 0],
#        [ 4],
#        [ 8],
#        [12]]), array([[ 1],
#        [ 5],
#        [ 9],
#        [13]]), array([[ 2,  3],
#        [ 6,  7],
#        [10, 11],
#        [14, 15]])]

When the dimension of the array is greater than or equal to 3, the division direction is still along the second axis (column):

a = np.arange(8).reshape(2, 2, 2)
print(np.hsplit(a, 2))
# [array([[[0, 1]],

#        [[4, 5]]]), array([[[2, 3]],

#        [[6, 7]]])]

5, Invert array

functioneffect
np.flip(a, axis=None)Invert array a in the axis direction; Axis is an integer or integer tuple; When axis is None, the array will be inverted along all axes. When axis is a tuple, the array will be inverted along the axis mentioned in the tuple
np.fliplr(a)Reverse along the second axis (column direction)
np.flipud(a)Reverse along the first axis (row direction)

5.1 np.flip()

Consider the one-dimensional array first:

a = np.arange(6)
print(np.flip(a))
# [5 4 3 2 1 0]

For 2D arrays:

A = np.arange(8).reshape(2, 2, 2)
print(A)
# [[[0 1]
#   [2 3]]
# 
#  [[4 5]
#   [6 7]]]
print(np.flip(A, axis=0))
# [[[4 5]
#   [6 7]]
# 
#  [[0 1]
#   [2 3]]]
print(np.flip(A, axis=1))
# [[[2 3]
#   [0 1]]
# 
#  [[6 7]
#   [4 5]]]
print(np.flip(A, axis=2))
# [[[1 0]
#   [3 2]]
# 
#  [[5 4]
#   [7 6]]]
print(np.flip(A))
# [[[7 6]
#   [5 4]]
# 
#  [[3 2]
#   [1 0]]]
print(np.flip(A, axis=(0, 2)))
# [[[5 4]
#   [7 6]]
# 
#  [[1 0]
#   [3 2]]]

5.2 np.fliplr()

A = np.diag([1, 2, 3])
print(np.fliplr(A))
# [[0 0 1]
#  [0 2 0]
#  [3 0 0]]

5.3 np.flipud()

A = np.diag([1, 2, 3])
print(np.flipud(A))
# [[0 0 3]
#  [0 2 0]
#  [1 0 0]]

Now, we can make a summary of the flip() function:

  • flip(a, 0) is equivalent to flipud(a)
  • flip(a, 1) is equivalent to fliplr(a)
  • flip(a, n) is equivalent to a [...,:: - 1,...], Where: the index of - 1 is n
  • flip(a) is equivalent to a [:: - 1,:: - 1,...,:: - 1], where all positions are:: - 1
  • flip(a, (0, 1)) is equivalent to a [:: - 1,:: - 1,...], Only indexes 0 and 1 are:: - 1

Topics: Python Data Analysis array