Contents

Python NumPy For Your Grandma - 4.5 Stacking

In this section, we’ll see how the functions hstack(), vstack(), and stack() are a lot like the concatenate() function with some subtle differences that can come in handy.

Let’s start by building some helper arrays. We’ll make a (2,) array called foo, another (2,) array called bar, a (1,2) array called baz, a (1,3) array called bingo, and a (2,2) array called bongo.

import numpy as np

foo = np.array(['a', 'b'])
bar = np.array(['c', 'd'])
baz = np.array([['e', 'f']])
bingo = np.array([['g', 'h', 'i']])
bongo = np.array(
    [['j', 'k'],
     ['l', 'm']]
)

Now let’s take a look at vstack(). vstack() takes one argument - a sequence of arrays, and you could describe its algorithm in pseudocode as the following.

for each array in the sequence:
  if the array is 1d
    then promote the array to 2d by giving it a new front axis
if every array in the sequence has the same shape:
  then concatenate the arrays along axis 0
otherwise throw an error

Visually, you could imagine vstack() as vertically stacking 1-d or 2-d arrays. So if we vstack() foo and bar, we’ll get back a 2x2 array like this.

np.vstack((foo, bar))
## array([['a', 'b'],
##        ['c', 'd']], dtype='<U1')

And if we vstack() foo, bar, and baz, we’ll get back a 3x2 array like this.

np.vstack((foo, bar, baz))
## array([['a', 'b'],
##        ['c', 'd'],
##        ['e', 'f']], dtype='<U1')

And if vstack() baz and bingo, we’ll get an error because their shapes don’t align for vstack().

np.vstack((baz, bingo))  # error

Now let’s take a look at hstack(). hstack() also takes one argument - a sequence of arrays, and you could describe its algorithm in pseudocode as the following.

if every array in the sequence is 1d:
  then concatenate the arrays along axis 0
else: 
  if every array has the same shape excluding axis 1:
    then concatenate arrays along axis 1
  otherwise throw an error

Visually, you could imagine hstack() as horizontally stacking 1-d or 2-d arrays. So if we hstack() foo and bar, we’ll get back a 4x array like this.

np.hstack((foo, bar))
## array(['a', 'b', 'c', 'd'], dtype='<U1')

If we hstack() baz and bingo, we’ll get back a 5x array like this.

np.hstack((baz, bingo))
## array([['e', 'f', 'g', 'h', 'i']], dtype='<U1')

If we hstack() foo and bingo, we’ll get back an error because their shapes don’t align for hstack().

np.hstack((foo, bingo))  # error

And if we hstack() bingo and bongo, we’ll get another error because their shapes also don’t align for hstack().

np.hstack((bingo, bongo))  # error

Lastly, stack() takes two arguments, a sequence of arrays to combine, and axis, which tells stack to create a new axis along which to combine the arrays. In pseudocode, you could write stack’s algorithm as the following.

if every array is the same shape and axis is less than or equal to the dimensionality of the arrays:
  then for each array: 
    insert a new axis where specified
  then concatenate the arrays along the new axis
otherwise throw an error

So, let’s see what happens if we stack() foo and bar with axis=0. Remember the algorithm. foo and bar each get a new axis 0, promoting them from 2x arrays to 1x2 arrays, and then they’re stacked along that new axis; so, row-wise, resulting in a new 2x2 array.

np.stack((foo, bar), axis = 0)
## array([['a', 'b'],
##        ['c', 'd']], dtype='<U1')

If we stack() them along axis 1, they go from 2x arrays to 2x1 arrays and then get stacked column-wise into a new 2x2 array.

np.stack((foo, bar), axis = 1)
## array([['a', 'c'],
##        ['b', 'd']], dtype='<U1')

If we try to stack() foo and bar with axis=2 we’ll get an out of bounds error. Remember, the new axis must be in range of the arrays’ existing dimensionality.

np.stack((foo, bar), axis = 2)  # error

You can also use the axis = -1 shortcut to make the new axis the last axis. For foo and bar, it’d be like using axis = 1.

np.stack((foo, bar), axis = -1)
## array([['a', 'c'],
##        ['b', 'd']], dtype='<U1')

Course Curriculum

  1. Introduction
    1.1 Introduction
  2. Basic Array Stuff
    2.1 NumPy Array Motivation
    2.2 NumPy Array Basics
    2.3 Creating NumPy Arrays
    2.4 Indexing 1-D Arrays
    2.5 Indexing Multidimensional Arrays
    2.6 Basic Math On Arrays
    2.7 Challenge: High School Reunion
    2.8 Challenge: Gold Miner
    2.9 Challenge: Chic-fil-A
  3. Intermediate Array Stuff
    3.1 Broadcasting
    3.2 newaxis
    3.3 reshape()
    3.4 Boolean Indexing
    3.5 nan
    3.6 infinity
    3.7 random
    3.8 Challenge: Love Distance
    3.9 Challenge: Professor Prick
    3.10 Challenge: Psycho Parent
  4. Common Operations
    4.1 where()
    4.2 Math Functions
    4.3 all() and any()
    4.4 concatenate()
    4.5 Stacking
    4.6 Sorting
    4.7 unique()
    4.8 Challenge: Movie Ratings
    4.9 Challenge: Big Fish
    4.10 Challenge: Taco Truck
  5. Advanced Array Stuff
    5.1 Advanced Array Indexing
    5.2 View vs Copy
    5.3 Challenge: Population Verification
    5.4 Challenge: Prime Locations
    5.5 Challenge: The Game of Doors
    5.6 Challenge: Peanut Butter
  6. Final Boss
    6.1 as_strided()
    6.2 einsum()
    6.3 Challenge: One-Hot-Encoding
    6.4 Challenge: Cumulative Rainfall
    6.5 Challenge: Table Tennis
    6.6 Challenge: Where’s Waldo
    6.7 Challenge: Outer Product

Additional Content

  1. Python Pandas For Your Grandpa
  2. Neural Networks For Your Dog
  3. Introduction To Google Colab