Writing string from numpy structured array with different delimiter

I have some data stored in a numpy structured array that I would like to write to a file. Since I am generating some code to match an existing output format that exported a more visually pleasing table, I need to output this data using a different space delimiter.

Using a basic example:

import numpy as np

x = np.zeros((2,),dtype=('i4,f4,a10'))
x[:] = [(1,2.,'Hello'),(2,3.,'World')]

      

With the desired output:

1 2.00    Hello
2 3.00    World

      

Now I know I can do this:

for row in x:
    print('%i %.2f    %s' % (row[0], row[1], row[2]))

      

Which works great, but seems too verbose if you have a lot of columns. Now my output is 8.

I'm new to Python (from MATLAB), is there a more general operator I could use to "collapse" all columns? I was thinking something like strings print('%i %.2f %s' % val for val in row)

, but this just prints 2 generators. When I came across a generator in use re.split

, I could use list()

to get the desired output, but I don't think using something similar, say str()

for this case, would do what I'm looking for.

+3


source to share


2 answers


If you wrap row

in tuple

, you don't need to list all the elements. %

formats are accepted tuple

. row

may appear like tuple

, but it actually is numpy.void

.

for row in x:
    print('%i %.2f   %s'%tuple(row))

      

Printing or writing lines in a loop like this is perfectly normal Python.

Class __str__

methods are often written as:

astr=['a header line']
for row in x:
    astr.append('%i %.2f   %s'%tuple(row))
astr='\n'.join(astr)

      



creating a string of concatenated strings.

The equivalent of understanding could be:

'\n'.join('%i %.2f   %s'%tuple(row) for row in x)

      

Since you are using Python3 you can also use the approach .format

, but I suspect the style is %

closer to what you are using in MATLAB.

+1


source


First:  Regarding your implicit question with generators; you can "tweak" the generator, for example, with str.join

:

>>> gen = (i.upper() for i in "teststring")
>>> print(''.join(gen))
TESTSTRING

      

Second:  To the real question: It's a bit more general than your approach, but it's still not very satisfying.



formats = [
    ("{}", 1),      # format and number of spaces for row[0]
    ("{.2f}", 4),   # the same for row[1]
    ("{}", 0)       # and row[2]
]
for row in x:
    lst = [f.format(d) + (" "*s) for (f, s, d) in zip(formats, row)]
    print(*lst, sep='')

      

It simply provides a better overview for each format.

+1


source







All Articles