Antoine Gallix
Antoine Gallix

Reputation: 816

printing numpy timedelta64 with format()

I would like to print a numpy.timedelta64() value in a formatted way. The direct method works well:

>>> import numpy as np
>>> print np.timedelta64(10,'m')
10 minutes

Which I guess comes from the __str__() method

>>> np.timedelta64(10,'m').__str__()
'10 minutes'

But when I try to print it with the format() function I get the following error:

>>> print "my delta is : {delta}".format(delta=np.timedelta64(10,'m'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: don't know how to convert scalar number to long

I would like to understand the underlying mechanism of the "string".format() function, and why it doesn't work in this particular case.

Upvotes: 2

Views: 1740

Answers (3)

Veedrac
Veedrac

Reputation: 60167

falsetru mentions one aspect of the problem. The other is why this errors at all.

Looking at the code for __format__, we see that it is a generic implementation.

The important part is:

    else if (PyArray_IsScalar(self, Integer)) {
#if defined(NPY_PY3K)
        obj = Py_TYPE(self)->tp_as_number->nb_int(self);
#else
        obj = Py_TYPE(self)->tp_as_number->nb_long(self);
#endif
    }

This triggers, and tries to run:

int(numpy.timedelta64(10, "m"))

but Numpy (rightly) says that you can't convert a number with units to a raw number.

This looks like a bug.

Upvotes: 2

falsetru
falsetru

Reputation: 369194

According to the Format String Syntax documentation:

The conversion field causes a type coercion before formatting. Normally, the job of formatting a value is done by the __format__() method of the value itself. However, in some cases it is desirable to force a type to be formatted as a string, overriding its own definition of formatting. By converting the value to a string before calling __format__(), the normal formatting logic is bypassed.

>>> np.timedelta64(10,'m').__format__('')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: don't know how to convert scalar number to long

By appending !s conversion flag, you can force it to use str:

>>> "my delta is : {delta!s}".format(delta=np.timedelta64(10,'m'))
'my delta is : 10 minutes'

Upvotes: 4

ivan_pozdeev
ivan_pozdeev

Reputation: 36046

%s should be fine. It calls str() on the object.

Upvotes: 1

Related Questions