Lesson 3 - Shape Manipulation

The Original Tutorial may be found here.

In [1]:
import numpy as np

Changing the shape of an array

The Original Tutorial may be found here

An array has a shape given by the number of elements along each axis:

In [5]:
a = np.floor(10*np.random.random((3,4)))
In [6]:
a
Out[6]:
array([[ 3.,  6.,  5.,  5.],
       [ 1.,  6.,  1.,  6.],
       [ 0.,  5.,  2.,  2.]])
In [7]:
a.shape
Out[7]:
(3L, 4L)

The shape of an array can be changed with various commands:

In [8]:
a.ravel() # flatten the array
Out[8]:
array([ 3.,  6.,  5.,  5.,  1.,  6.,  1.,  6.,  0.,  5.,  2.,  2.])
In [12]:
a.shape = (6, 2)
In [13]:
a
Out[13]:
array([[ 3.,  6.],
       [ 5.,  5.],
       [ 1.,  6.],
       [ 1.,  6.],
       [ 0.,  5.],
       [ 2.,  2.]])
In [14]:
a.transpose()
Out[14]:
array([[ 3.,  5.,  1.,  1.,  0.,  2.],
       [ 6.,  5.,  6.,  6.,  5.,  2.]])

The reshape (non-mutative) method returns its argument with a modified shape, whereas the resize (mutative) method modifies the array itself:

In [15]:
a
Out[15]:
array([[ 3.,  6.],
       [ 5.,  5.],
       [ 1.,  6.],
       [ 1.,  6.],
       [ 0.,  5.],
       [ 2.,  2.]])
In [39]:
b = a.resize((2,6))
In [42]:
a
Out[42]:
array([[ 3.,  6.,  5.,  5.,  1.,  6.],
       [ 1.,  6.,  0.,  5.,  2.,  2.]])
In [43]:
b

Note that the resize method has mutated a. It does not return anything. It just mutate (a side effect).

If a dimension is given as -1 in a reshaping operation, the other dimensions are automatically calculated:

In [44]:
b = a.reshape(3,-1)
In [46]:
a
Out[46]:
array([[ 3.,  6.,  5.,  5.,  1.,  6.],
       [ 1.,  6.,  0.,  5.,  2.,  2.]])
In [47]:
b
Out[47]:
array([[ 3.,  6.,  5.,  5.],
       [ 1.,  6.,  1.,  6.],
       [ 0.,  5.,  2.,  2.]])

Note that the reshape method does not mutate a. It merely return the reshaped array.

Stacking together different arrays

The Original Tutorial may be found here

In [73]:
a = np.floor(10*np.random.random((2,2)))
In [74]:
a
Out[74]:
array([[ 1.,  9.],
       [ 7.,  7.]])
In [75]:
b = np.floor(10*np.random.random((2,2)))
In [76]:
b
Out[76]:
array([[ 9.,  5.],
       [ 4.,  1.]])
In [77]:
np.vstack((a, b))
Out[77]:
array([[ 1.,  9.],
       [ 7.,  7.],
       [ 9.,  5.],
       [ 4.,  1.]])
In [78]:
np.hstack((a, b))
Out[78]:
array([[ 1.,  9.,  9.,  5.],
       [ 7.,  7.,  4.,  1.]])

The function column_stack stacks 1D arrays as columns into a 2D array. It is equivalent to vstack only for 1D arrays:

In [79]:
np.column_stack((a,b))   # With 2D arrays
Out[79]:
array([[ 1.,  9.,  9.,  5.],
       [ 7.,  7.,  4.,  1.]])

Let's create two 1D arrays.

In [80]:
a = np.array((4., 2.))
In [81]:
b = np.array((2., 8.))

This is to quickly illustrate using the newaxis argument to increase a dimension for the array.

In [82]:
a[:,np.newaxis]
Out[82]:
array([[ 4.],
       [ 2.]])
In [83]:
b[:,np.newaxis]
Out[83]:
array([[ 2.],
       [ 8.]])

Let's column_stack them!

In [84]:
np.column_stack((a[:, np.newaxis], b[:, np.newaxis]))
Out[84]:
array([[ 4.,  2.],
       [ 2.,  8.]])
In [67]:
np.vstack((a[:, np.newaxis], b[:, np.newaxis]))   # The behavior of vstack is different
Out[67]:
array([[ 4.],
       [ 2.],
       [ 2.],
       [ 8.]])

let's try concatenate:

In [68]:
a
Out[68]:
array([ 4.,  2.])
In [69]:
b
Out[69]:
array([ 2.,  8.])
In [70]:
np.concatenate((a, b))
Out[70]:
array([ 4.,  2.,  2.,  8.])

Sort of similar to column stack.

let's try to create array using the r_[] and c_[]

In [87]:
np.r_[1:4, 0, 4]
Out[87]:
array([1, 2, 3, 0, 4])
In [89]:
np.c_[1:4, 2:5]
Out[89]:
array([[1, 2],
       [2, 3],
       [3, 4]])

Splitting one array into serveral smaller ones

Using hsplit, you can split an array along its horizontal axis, either by specifying the number of equally shaped arrays to return, or by specifying the columns after which the division should occur:

In [90]:
a = np.floor(10*np.random.random((2,12)))
In [91]:
a
Out[91]:
array([[ 9.,  9.,  4.,  3.,  4.,  5.,  3.,  8.,  0.,  6.,  6.,  8.],
       [ 7.,  8.,  9.,  7.,  1.,  6.,  8.,  6.,  5.,  2.,  6.,  7.]])
In [99]:
a_hsplit = np.hsplit(a, 3)    # Split a into 3
In [101]:
for i in a_hsplit:
    print i
    print ""
[[ 9.  9.  4.  3.]
 [ 7.  8.  9.  7.]]

[[ 4.  5.  3.  8.]
 [ 1.  6.  8.  6.]]

[[ 0.  6.  6.  8.]
 [ 5.  2.  6.  7.]]

In [102]:
a_vsplit = np.vsplit(a,2)   # Split a into 2
In [113]:
for i in a_vsplit:
    print i
    print 
[[ 9.  9.  4.  3.  4.  5.  3.  8.  0.  6.  6.  8.]]

[[ 7.  8.  9.  7.  1.  6.  8.  6.  5.  2.  6.  7.]]

(Recall axis 0 is out-most). Split along axis 1 (column).

In [109]:
a_as0 = np.array_split(a, 3, axis=1)
In [115]:
for i in a_as0:
    print i
    print "" 
[[ 9.  9.  4.  3.]
 [ 7.  8.  9.  7.]]

[[ 4.  5.  3.  8.]
 [ 1.  6.  8.  6.]]

[[ 0.  6.  6.  8.]
 [ 5.  2.  6.  7.]]

(Recall axis 0 is out-most). Split along axis 0 (row).

In [116]:
a_as1 = np.array_split(a, 2, axis=0)
In [117]:
for i in a_as1:
    print i
    print 
[[ 9.  9.  4.  3.  4.  5.  3.  8.  0.  6.  6.  8.]]

[[ 7.  8.  9.  7.  1.  6.  8.  6.  5.  2.  6.  7.]]

Conclusion

We have now completed Lesson 3 - Shape Manipulation.