Home > Software design >  Is there a method of vectorizing the printing of elements in a Numpy array?
Is there a method of vectorizing the printing of elements in a Numpy array?

Time:09-23

I have a numpy array named "a":

a = numpy.array([
                [[1, 2, 3], [11, 22, 33]],
                [[4, 5, 6], [44, 55, 66]],
                ])

I want to print the following (in this exact format):
1 2 3
11 22 33
4 5 6
44 55 66

To accomplish this, I wrote the following:

for i in range(len(A)):
    a = A[i]
    for j in range(len(a)):
        a1 = a[j][0]
        a2 = a[j][1]
        a3 = a[j][2]
        print(a1, a2, a3)

The output is:
1 2 3
11 22 33
4 5 6
44 55 66

I would like to vectorize my solution (if possible) and discard the for loop. I understand that this problem might not benefit from vectorization. In reality (for work-related purposes), the array "a" has 52 elements and each element contains hundreds of arrays stored inside. I'd like to solve a basic/trivial case and move onto a more advanced, realistic case.

Also, I know that Numpy arrays were not meant to be iterated through. I could have used Python lists to accomplish the following, but I really want to vectorize this (if possible, of course).

CodePudding user response:

You could use np.apply_along_axis which maps the array with a function on an arbitrary axis. Applying it on axis=2 to get the desired result.

Using print directly as the callback:

>>> np.apply_along_axis(print, 2, a)
[1 2 3]
[11 22 33]
[4 5 6]
[44 55 66]

Or with a lambda wrapper:

>>> np.apply_along_axis(lambda r: print(' '.join([str(x) for x in r])), 2, a)
1 2 3
11 22 33
4 5 6
44 55 66

CodePudding user response:

In [146]: a = numpy.array([
     ...:                 [[1, 2, 3], [11, 22, 33]],
     ...:                 [[4, 5, 6], [44, 55, 66]],
     ...:                 ])
     ...: 
In [147]: a
Out[147]: 
array([[[ 1,  2,  3],
        [11, 22, 33]],

       [[ 4,  5,  6],
        [44, 55, 66]]])

A proper "vectorized" numpy output is:

In [148]: a.reshape(-1,3)
Out[148]: 
array([[ 1,  2,  3],
       [11, 22, 33],
       [ 4,  5,  6],
       [44, 55, 66]])

You could also convert that to a list of lists:

In [149]: a.reshape(-1,3).tolist()
Out[149]: [[1, 2, 3], [11, 22, 33], [4, 5, 6], [44, 55, 66]]

But you want a print without the standard numpy formatting (nor list formatting)

But this iteration is easy:

In [150]: for row in a.reshape(-1,3):
     ...:     print(*row)
     ...: 
1 2 3
11 22 33
4 5 6
44 55 66

Since your desired output is a print, or at least "unformatted" strings, there's no "vectorized", i.e. whole-array, option. You have to iterate on each line!

np.savetxt creates a csv output by iterating on rows and writing a format tuple, e.g. f.write(fmt%tuple(row)).

In [155]: np.savetxt('test', a.reshape(-1,3), fmt='%d')
In [156]: cat test
1 2 3
11 22 33
4 5 6
44 55 66
  • Related