1

I can't understand why this formatter doesn't format a complex128:

import numpy as np
import scipy.sparse as sp

A = sp.diags([1, -2, 1], [1, 0, -1], shape=[3, 3], format='csc')
evals, evecs = sp.linalg.eigs(A, k=1, which='LM')

with np.printoptions(formatter={'complex_kind': '{:.2f}'.format}):
    print (evals, evals[0])

This code displays a one-element numpy.ndarray, then the element. The formatter is used for the array, not for the element alone:

[-3.41+0.00j] (-3.4142135623730954+0j)

Types involved:

type(evals): numpy.ndarray
evals.dtype: dtype('complex128')
type(evals[0]): numpy.complex128

Any clue appreciated.

mins
  • 6,478
  • 12
  • 56
  • 75
  • https://stackoverflow.com/questions/7746143/formatting-complex-numbers does this help you – ombk Nov 27 '20 at 11:51
  • `evals[0]` is a python complex, not a `numpy` array. – hpaulj Nov 27 '20 at 12:14
  • `evals[0]` is a python complex, not a `numpy` array. – hpaulj Nov 27 '20 at 12:14
  • @hpaulj: `evals` being an array of complexes, indeed `evals[0]` is a complex. The question is why this complex isn't formatted by `formatter={'complex_kind': '{:.2f}'.format}` – mins Nov 27 '20 at 12:29
  • 1
    It is not a **numpy** complex. You have to use python formatting directly. – hpaulj Nov 27 '20 at 12:51
  • @hpaulj: "*evals[0] is a python complex [...] not a numpy complex*": Are you sure, as `type(evals[0]` returns `numpy.complex128`. Even if that was true I wouldn't understand why `print (evals, evals[0])` would process the two arguments differently. – mins Nov 27 '20 at 12:59
  • 1
    It is a `numpy.complex128`, but the settings of `printoptions` only apply when printing an array, not a numpy scalar. – Warren Weckesser Nov 27 '20 at 16:19
  • 1
    @WarrenWeckesser: Thanks. If you are right (which would explain), then there is a problem with the description of [set_printoptions](https://numpy.org/doc/stable/reference/generated/numpy.set_printoptions.html#numpy.set_printoptions): "*These options determine the way **floating point numbers, arrays and other NumPy objects** are displayed.*" which lists arrays as one of the possible objects to format. Do you have another reference stating the scope of the options? Found [this post](https://www.mail-archive.com/numpy-discussion%40scipy.org/msg49594.html) about this confusion. – mins Nov 27 '20 at 16:46
  • 2
    There is another discussion of the issue here: https://github.com/numpy/numpy/issues/11048 – Warren Weckesser Nov 27 '20 at 17:01
  • 1
    @WarrenWeckesser: Yes, that's definitely the explanation, in this page, there is also [this strange behavior, by stefanv](https://github.com/numpy/numpy/issues/11048) (cannot link to comment directly). It's ok for me, but I'd be happy to select your answer if you have time to post one. It could be useful for others. – mins Nov 27 '20 at 17:05

1 Answers1

1

The settings of numpy.printoptions and numpy.set_printoptions control how NumPy prints arrays. They do not affect how NumPy scalars (such as numpy.complex128, numpy.float32, etc) are printed.

For example,

In [14]: np.set_printoptions(precision=3)                                       

In [15]: np.array([np.pi])  # A 1-d array.                                                                                          
Out[15]: array([3.142])

In [16]: np.array(np.pi)    # A 0-d array (aka a scalar array)                                                                        
Out[16]: array(3.142)

In [17]: np.float64(np.pi)  # A scalar float64. Output is not controlled by the print options                                       
Out[17]: 3.141592653589793

See github issue 11048 (and the links given there) on the NumPy github site for discussions of this topic.

Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
  • 1
    And yet https://stackoverflow.com/questions/65036864/printoptions-formatter-not-working-for-a-single-element-of-an-array-of-complex-n says: "These options determine the way floating point numbers, arrays and other NumPy objects are displayed." So I guess the docs are wrong. It appears that `reprlib` also cannot affect numpy floats, so basically there's no way to print them with a smaller precision when they are in a nested container? – max Apr 23 '22 at 05:07