Printing boolean numpy array without separators

Question:

I would like to print this array:

a = np.array([[0, 1, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]], dtype=bool)

as

.8..
8888
....
....

without iterating over each element in a double loop. A terse function like this one:

def showGrid(g):
  print(np.vectorize(lambda x: '8' if x else '.')(g))

but without standard separators:

[['.' '8' '.' '.']
 ['8' '8' '8' '8']
 ['.' '.' '.' '.']
 ['.' '.' '.' '.']]

I couldn’t find a way to make np.set_printoptions drop the standard numpy array formatting separators. Is that possible? If not, pointers to any relevant numpy trickery would be appreciated.

Asked By: Paul Jurczak

||

Answers:

First, use np.where to optimize your current code, which is the same and faster than the function wrapped with np.vectorize:

>>> np.where(a, '8', '.')
array([['.', '8', '.', '.'],
       ['8', '8', '8', '8'],
       ['.', '.', '.', '.'],
       ['.', '.', '.', '.']], dtype='<U1')

To concatenate the characters in each line, I prefer to use ndarray.view, which will create a view at a very low cost. It treats all characters in each line as a string with a length of 4:

>>> np.where(a, '8', '.').view('<U4')
array([['.8..'],
       ['8888'],
       ['....'],
       ['....']], dtype='<U4')

Then use ndarray.ravel() or ndarray.flat to unpack the flat results into the print function, with the newline character as the separator:

>>> print(*np.where(a, '8', '.').view('<U4').flat, sep='n')
.8..
8888
....
....

Or use str.join to get the complete string:

>>> print('n'.join(np.where(a, '8', '.').view('<U4').flat))
.8..
8888
....
....
Answered By: Mechanic Pig
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.