The
ndarray
class has a strides
field, which is a tuple indicating the number of bytes to step in each dimension when going through an array. Let's apply some stride tricks to the problem of splitting a Sudoku puzzle to the 3 by 3 squares of which it is composed.
Explaining the Sudoku rules is outside the scope of this book. For more information see http://en.wikipedia.org/wiki/Sudoku.
Let's define the Sudoku puzzle array. This one is filled with the contents of an actual, solved Sudoku puzzle:
sudoku = numpy.array([ [2, 8, 7, 1, 6, 5, 9, 4, 3], [9, 5, 4, 7, 3, 2, 1, 6, 8], [6, 1, 3, 8, 4, 9, 7, 5, 2], [8, 7, 9, 6, 5, 1, 2, 3, 4], [4, 2, 1, 3, 9, 8, 6, 7, 5], [3, 6, 5, 4, 2, 7, 8, 9, 1], [1, 9, 8, 5, 7, 3, 4, 2, 6], [5, 4, 2, 9, 1, 6, 3, 8, 7], [7, 3, 6, 2, 8, 4, 5, 1, 9] ])
itemsize
field of ndarray
gives us the number of bytes in an array. Using the itemsize
, calculate the strides:strides = sudoku.itemsize * numpy.array([27, 3, 9, 1])
Now we can split the puzzle into
squares with the as_strided
function of the numpy.lib.stride_tricks
module:
squares = numpy.lib.stride_tricks.as_strided(sudoku, shape=shape, strides=strides) print(squares)
This prints separate Sudoku squares:
[[[[2 8 7] [9 5 4] [6 1 3]] [[1 6 5] [7 3 2] [8 4 9]] [[9 4 3] [1 6 8] [7 5 2]]] [[[8 7 9] [4 2 1] [3 6 5]] [[6 5 1] [3 9 8] [4 2 7]] [[2 3 4] [6 7 5] [8 9 1]]] [[[1 9 8] [5 4 2] [7 3 6]] [[5 7 3] [9 1 6] [2 8 4]] [[4 2 6] [3 8 7] [5 1 9]]]]
The following is the complete source code for this recipe:
import numpy sudoku = numpy.array([ [2, 8, 7, 1, 6, 5, 9, 4, 3], [9, 5, 4, 7, 3, 2, 1, 6, 8], [6, 1, 3, 8, 4, 9, 7, 5, 2], [8, 7, 9, 6, 5, 1, 2, 3, 4], [4, 2, 1, 3, 9, 8, 6, 7, 5], [3, 6, 5, 4, 2, 7, 8, 9, 1], [1, 9, 8, 5, 7, 3, 4, 2, 6], [5, 4, 2, 9, 1, 6, 3, 8, 7], [7, 3, 6, 2, 8, 4, 5, 1, 9] ]) shape = (3, 3, 3, 3) strides = sudoku.itemsize * numpy.array([27, 3, 9, 1]) squares = numpy.lib.stride_tricks.as_strided(sudoku, shape=shape, strides=strides) print(squares)