f string formatting for numpy array
Asked Answered
B

2

8

Here is my code snippets. It prints the means and the standard deviations from the image pixels.

from numpy import asarray
from PIL import Image
import os

os.chdir("../images") 
image = Image.open("dubai_2020.jpg")
pixels = asarray(image) 
pixels = pixels.astype("float32")
means, stds = pixels.mean(axis=(0, 1), dtype="float64"), pixels.std(
    axis=(0, 1), dtype="float64")
print(f"Means: {means:%.2f}, Stds: {stds:%.2f} ")

And the output is

 File "pil_local_standard5.py", line 15, in <module>
    print(f"Means: {means:%.2f, %.2f, %.2f}, Stds: {stds:%.2f, %.2f, %.2f} ")

TypeError: unsupported format string passed to numpy.ndarray.__format__

How do I define the f-strings format of the data in this case?

Breakneck answered 13/2, 2020 at 2:38 Comment(4)
numpy uses its own formatting specifications. The Python ones, whether '%', 'str.format' or 'f' don't work within an array. f{x!s} and f{x!r} work, but not much else. Oh, and '%.2f' isn't right. Use the str.format style, e.g. f'{12.23:.2f}' Mikes
@Mikes Thank you for your comment. But your suggestion like f'{12.23:.2f}' works only for the scalar or the non-array. My case is the f-string for the Numpy array. And your suggestion was tried and found not working. You may try my snippets by yourself then you can find it out.Breakneck
The 'oh and' means I'm bringing up a different point. I'm not saying that will work with arrays.Mikes
@hpaulj, You're right! I misunderstood your comments. Sorry for that.Breakneck
B
11

I think the easiest way to accomplish something similar to what you want, currently would require the use of numpy.array2string.

For example, let's say means = np.random.random((5, 3)). Then you could do this:

import numpy as np
means = np.random.random((5, 3)).astype(np.float32)  # simulate some array
print(f"{np.array2string(means, precision=2, floatmode='fixed')}")

which will print:

[[0.41 0.12 0.84]
 [0.28 0.43 0.29]
 [0.68 0.41 0.14]
 [0.75 1.00 0.16]
 [0.30 0.49 0.37]]

The same can be achieved with:

print(f"{np.array2string(means, formatter={'float': lambda x: f'{x:.2f}'})}")

You can also add separators, if you wish:

print(f"{np.array2string(means, formatter={'float': lambda x: f'{x:.2f}'}, separator=', ')}")

which would print:

[[0.41, 0.12, 0.84],
 [0.28, 0.43, 0.29],
 [0.68, 0.41, 0.14],
 [0.75, 1.00, 0.16],
 [0.30, 0.49, 0.37]]
Borgerhout answered 21/7, 2021 at 22:57 Comment(0)
N
1

Unfortunately, Python's f-string doesn't support formatting of numpy arrays.


A workaround I came up with:

def prettifyStr(numpyArray, fstringText):
  num_rows = numpyArray.ndim
  l = len(str(numpyArray))
  t = (l // num_rows)
  diff_to_center_align = 50 - t
  return f"{str(numpyArray)}{' ': <{diff_to_center_align}}{fstringText}"

Sample use

    print( prettifyStr(a2, "this is some text") )
    print( prettifyStr(a3, "this is some text") )
    print( prettifyStr(a1, "this is some text") )
    print( prettifyStr(a4, "this is some text") )

Output

[[0.  3.  4. ]
 [0.  5.  5.1]]                                   this is some text 

[[0.   3.   4.   4.35]
 [0.   5.   5.1  3.6 ]]                           this is some text 

[[0 3]
 [0 5]]                                           this is some text 

[[0.   3.   4.   4.35 4.25]
 [0.   5.   5.1  3.6  3.1 ]]                      this is some text
Nonappearance answered 5/2, 2021 at 13:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.