82

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.

misterbear
  • 803
  • 2
  • 13
  • 33
Kaly
  • 3,289
  • 4
  • 24
  • 25

4 Answers4

104

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.

flying sheep
  • 8,475
  • 5
  • 56
  • 73
ali_m
  • 71,714
  • 23
  • 223
  • 298
  • 2
    How to make it also apply to scalars? – nn0p Mar 25 '20 at 13:25
  • 1
    @nn0p If you're using IPython you can use the [`%precision` magic](https://ipython.readthedocs.io/en/stable/interactive/magics.html#magic-precision), 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 Mar 25 '20 at 14:50
  • @Ali_m Sometimes you have variables that can be both scalars and arrays, and it would be convenient to apply to all. – N. Osil Jun 19 '22 at 08:49
50

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']
Guillaume Jacquenot
  • 11,217
  • 6
  • 43
  • 49
rth
  • 2,946
  • 1
  • 22
  • 27
  • 1
    It should be noted as it is above that this changes the representation and not just the display value as most user may intend. – Heberto Mayorquin Feb 04 '16 at 11:04
  • 1
    @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. – rth Feb 05 '16 at 13:25
42

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])
U2EF1
  • 12,907
  • 3
  • 35
  • 37
  • 1
    This solved my problem partly, I still get the e+01 (like in 2.15e+01 instead of 21.5). – Kaly Jan 08 '14 at 23:44
  • 4
    @kaly Hm, you may want to just write your own formatter (`np.set_printoptions(formatter={float: float_formatting_function})`). – U2EF1 Jan 08 '14 at 23:50
2
[ round(x,2) for x in [2.15295647e+01, 8.12531501e+00, 3.97113829e+00, 1.00777250e+01]]
Roland
  • 69
  • 1
  • 5