Search code examples
numpystring-formattingrecord

floats in NumPy structured array and native string formatting with .format()


Can anyone tell me why this NumPy record is having trouble with Python's new-style string formatting? All floats in the record choke on "{:f}".format(record).

Thanks for your help!

In [334]: type(tmp)
Out[334]: numpy.core.records.record

In [335]: tmp
Out[335]: ('XYZZ', 2001123, -23.823917388916016)

In [336]: tmp.dtype
Out[336]: dtype([('sta', '|S6'), ('ondate', '<i8'), ('lat', '<f4')])

# Some formatting works fine
In [337]: '{0.sta:6.6s} {0.ondate:8d}'.format(tmp)
Out[337]: 'XYZZ    2001123'

# Any float has trouble
In [338]: '{0.sta:6.6s} {0.ondate:8d} {0.lat:11.6f}'.format(tmp)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/Users/jkmacc/python/pisces/<ipython-input-338-e5f6bcc4f60f> in <module>()
----> 1 '{0.sta:6.6s} {0.ondate:8d} {0.lat:11.6f}'.format(tmp)

ValueError: Unknown format code 'f' for object of type 'str'

Solution

  • This question was answered on the NumPy user mailing list under "floats coerced to string with "{:f}".format() ?":

    It seems that np.int64/32 and np.str inherit their respective native Python __format__(), but np.float32/64 doesn't get __builtin__.float.__format__(). That's not intuitive, but I see now why this works:

    In [8]: '{:6.6s} {:8d} {:11.6f}'.format(tmp.sta, tmp.ondate, float(tmp.lat))
    Out[8]: 'XYZZ    2001123  -23.820000'
    

    Thanks!

    -Jon

    EDIT: np.float32/int32 inherits from native Python types if your system is 32-bit. Same for 64-bit. A mismatch will generate the same problem as the original post.