86

If I have a numpy array like this:

[2.15295647e+01, 8.12531501e+00, 3.97113829e+00, 1.00777250e+01]

how can I move the decimal point and format the numbers so I end up with a numpy array like this:

[21.53, 8.13, 3.97, 10.08]

np.around(a, decimals=2) only gives me [2.15300000e+01, 8.13000000e+00, 3.97000000e+00, 1.00800000e+01] Which I don't want and I haven't found another way to do it.

0

4 Answers 4

112

In order to make numpy display float arrays in an arbitrary format, you can define a custom function that takes a float value as its input and returns a formatted string:

In [1]: float_formatter = "{:.2f}".format

The f here means fixed-point format (not 'scientific'), and the .2 means two decimal places (you can read more about string formatting here).

Let's test it out with a float value:

In [2]: float_formatter(1.234567E3)
Out[2]: '1234.57'

To make numpy print all float arrays this way, you can pass the formatter= argument to np.set_printoptions:

In [3]: np.set_printoptions(formatter={'float_kind':float_formatter})

Now numpy will print all float arrays this way:

In [4]: np.random.randn(5) * 10
Out[4]: array([5.25, 3.91, 0.04, -1.53, 6.68]

Note that this only affects numpy arrays, not scalars:

In [5]: np.pi
Out[5]: 3.141592653589793

It also won't affect non-floats, complex floats etc - you will need to define separate formatters for other scalar types.

You should also be aware that this only affects how numpy displays float values - the actual values that will be used in computations will retain their original precision.

For example:

In [6]: a = np.array([1E-9])

In [7]: a
Out[7]: array([0.00])

In [8]: a == 0
Out[8]: array([False], dtype=bool)

numpy prints a as if it were equal to 0, but it is not - it still equals 1E-9.

If you actually want to round the values in your array in a way that affects how they will be used in calculations, you should use np.round, as others have already pointed out.

Sign up to request clarification or add additional context in comments.

4 Comments

How to make it also apply to scalars?
@nn0p If you're using IPython you can use the %precision magic, e.g. %precision %.2f That only applies to native Python floats, though (I don't know of a way to set the display precision for numpy float scalars).
@Ali_m Sometimes you have variables that can be both scalars and arrays, and it would be convenient to apply to all.
@nn0p A very late reply, but for others looking for this, use int or int_kind in the formatter as described in the numpy docs.
52

You can use round function. Here some example

numpy.round([2.15295647e+01, 8.12531501e+00, 3.97113829e+00, 1.00777250e+01],2)
array([ 21.53,   8.13,   3.97,  10.08])

IF you want change just display representation, I would not recommended to alter printing format globally, as it suggested above. I would format my output in place.

>>a=np.array([2.15295647e+01, 8.12531501e+00, 3.97113829e+00, 1.00777250e+01])
>>> print([ "{:0.2f}".format(x) for x in a ])
['21.53', '8.13', '3.97', '10.08']

3 Comments

It should be noted as it is above that this changes the representation and not just the display value as most user may intend.
@RamonMartinez you are right. I posted this because I didn't like the idea to change a printing format globally, as it was suggested before. Later in another part of the program, you may get 0.00 and create new topic at stackoverflow why does this happen. So in this case I would simply use ["{:0.2f}".format(x) for x in a], where a is numpy array or any other iteratable object (list, tuple....). In this case you don't alter other printing formats.
Another problem of using round is that the result may be misleading. For example, print(np.around([1234.5,0.00067],4)) produces [1.2345e+03 7.0000e-04]. The zeros in the 7.0000e-4 usually means that this result is precise up to 8th decimal place, while a round was made at the 4th. np.set_printoptions gives more consistent results.
47

You're confusing actual precision and display precision. Decimal rounding cannot be represented exactly in binary. You should try:

> np.set_printoptions(precision=2)
> np.array([5.333333])
array([ 5.33])

2 Comments

This solved my problem partly, I still get the e+01 (like in 2.15e+01 instead of 21.5).
@kaly Hm, you may want to just write your own formatter (np.set_printoptions(formatter={float: float_formatting_function})).
3
[ round(x,2) for x in [2.15295647e+01, 8.12531501e+00, 3.97113829e+00, 1.00777250e+01]]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.