वैज्ञानिक संकेतन के साथ और दिए गए परिशुद्धता के साथ एक numpy.array को सुंदर कैसे प्रिंट करें?


331

मैं उत्सुक हूं, क्या स्वरूपित मुद्रित करने का कोई तरीका है numpy.arrays, उदाहरण के लिए, इस तरह से एक तरह से:

x = 1.23456
print '%.3f' % x

अगर मैं numpy.arrayफ़्लोट्स को प्रिंट करना चाहता हूं , तो यह कई दशमलवों को प्रिंट करता है, अक्सर 'वैज्ञानिक' प्रारूप में, जो कम-आयामी सरणियों के लिए भी पढ़ना मुश्किल है। हालांकि, numpy.arrayजाहिरा तौर पर एक स्ट्रिंग के रूप में मुद्रित किया जाना है, यानी, के साथ %s। क्या इसका कोई समाधान है?


यह चर्चा उन लोगों के लिए भी रुचि ले सकती है जो Google खोज के माध्यम से यहां समाप्त होते हैं।
Foad

जवाबों:


557

आप set_printoptionsआउटपुट की शुद्धता निर्धारित करने के लिए उपयोग कर सकते हैं :

import numpy as np
x=np.random.random(10)
print(x)
# [ 0.07837821  0.48002108  0.41274116  0.82993414  0.77610352  0.1023732
#   0.51303098  0.4617183   0.33487207  0.71162095]

np.set_printoptions(precision=3)
print(x)
# [ 0.078  0.48   0.413  0.83   0.776  0.102  0.513  0.462  0.335  0.712]

और suppressछोटी संख्या के लिए वैज्ञानिक संकेतन के उपयोग को दबाता है:

y=np.array([1.5e-10,1.5,1500])
print(y)
# [  1.500e-10   1.500e+00   1.500e+03]
np.set_printoptions(suppress=True)
print(y)
# [    0.      1.5  1500. ]

अन्य विकल्पों के लिए set_printoptions के लिए डॉक्स देखें ।


स्थानीय रूप से मुद्रण विकल्प लागू करने के लिए , NumPy 1.15.0 या बाद के संस्करण का उपयोग करके, आप numpy.printoptions संदर्भ प्रबंधक का उपयोग कर सकते हैं । उदाहरण के लिए, अंदर with-suite precision=3और suppress=Trueसेट हैं:

x = np.random.random(10)
with np.printoptions(precision=3, suppress=True):
    print(x)
    # [ 0.073  0.461  0.689  0.754  0.624  0.901  0.049  0.582  0.557  0.348]

लेकिन with-suiteप्रिंट विकल्पों के बाहर डिफ़ॉल्ट सेटिंग्स पर वापस आ जाते हैं:

print(x)    
# [ 0.07334334  0.46132615  0.68935231  0.75379645  0.62424021  0.90115836
#   0.04879837  0.58207504  0.55694118  0.34768638]

यदि आप NumPy के पुराने संस्करण का उपयोग कर रहे हैं, तो आप स्वयं संदर्भ प्रबंधक बना सकते हैं। उदाहरण के लिए,

import numpy as np
import contextlib

@contextlib.contextmanager
def printoptions(*args, **kwargs):
    original = np.get_printoptions()
    np.set_printoptions(*args, **kwargs)
    try:
        yield
    finally: 
        np.set_printoptions(**original)

x = np.random.random(10)
with printoptions(precision=3, suppress=True):
    print(x)
    # [ 0.073  0.461  0.689  0.754  0.624  0.901  0.049  0.582  0.557  0.348]

शून्य को तैरने के अंत से छीनने से रोकने के लिए:

np.set_printoptionsअब एक formatterपैरामीटर है जो आपको प्रत्येक प्रकार के लिए एक प्रारूप फ़ंक्शन निर्दिष्ट करने की अनुमति देता है।

np.set_printoptions(formatter={'float': '{: 0.3f}'.format})
print(x)

जो प्रिंट करता है

[ 0.078  0.480  0.413  0.830  0.776  0.102  0.513  0.462  0.335  0.712]

के बजाय

[ 0.078  0.48   0.413  0.83   0.776  0.102  0.513  0.462  0.335  0.712]

क्या केवल विशिष्ट प्रिंट स्टेटमेंट को लागू करने का एक माध्यम है (जैसा कि सभी प्रिंट स्टेटमेंट द्वारा उपयोग किए जाने वाले सामान्य आउटपुट प्रारूप को सेट करने के लिए विरोध किया जाता है )?
bph

7
@Hiett: केवल एक के लिए प्रिंट विकल्प सेट करने के लिए कोई NumPy फ़ंक्शन नहीं है print, लेकिन आप कुछ समान बनाने के लिए एक संदर्भ प्रबंधक का उपयोग कर सकते हैं। मैंने ऊपर पोस्ट को संपादित करके दिखाया है कि मेरा क्या मतलब है।
अनटु

2
आपका np.set_printoptions(precision=3)अंत शून्य को दबा देता है .. आप उन्हें इस तरह प्रदर्शित करने के लिए कैसे प्राप्त करते हैं [ 0.078 0.480 0.413 0.830 0.776 0.102 0.513 0.462 0.335 0.712]?
नोरफेल्ट

2
@ नोफ़ेल्ड्ट: मैंने ऊपर ऐसा करने का एक तरीका जोड़ा है।
अनटुब

1
यह बहुत अच्छा काम करता है। एक साइड नोट के रूप में, आप भी उपयोग कर सकते हैं set_printoptionsयदि आप एक स्ट्रिंग प्रतिनिधित्व चाहते हैं और जरूरी नहीं कि उपयोग करें print। आप बस __str__()सुन्न सरणी उदाहरण को कॉल कर सकते हैं और आपको आपके द्वारा सेट किए गए प्रिंटपॉइंट्स के अनुसार स्वरूपित स्ट्रिंग मिलेगा।
जयेश

40

आप कमांड np.set_printoptionsसे कार्यक्षमता का एक सबसेट प्राप्त कर सकते हैं np.array_str, जो केवल एक प्रिंट स्टेटमेंट पर लागू होता है।

http://docs.scipy.org/doc/numpy/reference/generated/numpy.array_str.html

उदाहरण के लिए:

In [27]: x = np.array([[1.1, 0.9, 1e-6]]*3)

In [28]: print x
[[  1.10000000e+00   9.00000000e-01   1.00000000e-06]
 [  1.10000000e+00   9.00000000e-01   1.00000000e-06]
 [  1.10000000e+00   9.00000000e-01   1.00000000e-06]]

In [29]: print np.array_str(x, precision=2)
[[  1.10e+00   9.00e-01   1.00e-06]
 [  1.10e+00   9.00e-01   1.00e-06]
 [  1.10e+00   9.00e-01   1.00e-06]]

In [30]: print np.array_str(x, precision=2, suppress_small=True)
[[ 1.1  0.9  0. ]
 [ 1.1  0.9  0. ]
 [ 1.1  0.9  0. ]]

37

Unutbu ने वास्तव में पूर्ण उत्तर दिया (उन्हें मेरे से भी +1 मिला), लेकिन यहाँ एक लो-टेक विकल्प है:

>>> x=np.random.randn(5)
>>> x
array([ 0.25276524,  2.28334499, -1.88221637,  0.69949927,  1.0285625 ])
>>> ['{:.2f}'.format(i) for i in x]
['0.25', '2.28', '-1.88', '0.70', '1.03']

एक फ़ंक्शन के रूप में ( format()स्वरूपण के लिए सिंटैक्स का उपयोग करके ):

def ndprint(a, format_string ='{0:.2f}'):
    print [format_string.format(v,i) for i,v in enumerate(a)]

उपयोग:

>>> ndprint(x)
['0.25', '2.28', '-1.88', '0.70', '1.03']

>>> ndprint(x, '{:10.4e}')
['2.5277e-01', '2.2833e+00', '-1.8822e+00', '6.9950e-01', '1.0286e+00']

>>> ndprint(x, '{:.8g}')
['0.25276524', '2.283345', '-1.8822164', '0.69949927', '1.0285625']

सरणी का सूचकांक प्रारूप स्ट्रिंग में सुलभ है:

>>> ndprint(x, 'Element[{1:d}]={0:.2f}')
['Element[0]=0.25', 'Element[1]=2.28', 'Element[2]=-1.88', 'Element[3]=0.70', 'Element[4]=1.03']

15

FYI Numpy 1.15 (रिलीज की तारीख लंबित) में स्थानीय स्तर पर प्रिंट विकल्प स्थापित करने के लिए एक संदर्भ प्रबंधक शामिल होगा । इसका मतलब यह है कि निम्नलिखित अपने स्वयं के संदर्भ प्रबंधक को लिखने के बिना स्वीकृत उत्तर (अनुत्पाद और नील जी द्वारा) में इसी उदाहरण के रूप में काम करेगा । जैसे, उनके उदाहरण का उपयोग करना:

x = np.random.random(10)
with np.printoptions(precision=3, suppress=True):
    print(x)
    # [ 0.073  0.461  0.689  0.754  0.624  0.901  0.049  0.582  0.557  0.348]

12

वह रत्न जो परिणाम को स्ट्रिंग के रूप में प्राप्त करना बहुत आसान बनाता है (आज के सुन्न संस्करणों में) डेनिस उत्तर में छिपा है: np.array2string

>>> import numpy as np
>>> x=np.random.random(10)
>>> np.array2string(x, formatter={'float_kind':'{0:.3f}'.format})
'[0.599 0.847 0.513 0.155 0.844 0.753 0.920 0.797 0.427 0.420]'

8

वर्षों बाद, एक और नीचे है। लेकिन हर रोज इस्तेमाल के लिए मैं सिर्फ

np.set_printoptions( threshold=20, edgeitems=10, linewidth=140,
    formatter = dict( float = lambda x: "%.3g" % x ))  # float arrays %.3g

''' printf( "... %.3g ... %.1f  ...", arg, arg ... ) for numpy arrays too

Example:
    printf( """ x: %.3g   A: %.1f   s: %s   B: %s """,
                   x,        A,        "str",  B )

If `x` and `A` are numbers, this is like `"format" % (x, A, "str", B)` in python.
If they're numpy arrays, each element is printed in its own format:
    `x`: e.g. [ 1.23 1.23e-6 ... ]  3 digits
    `A`: [ [ 1 digit after the decimal point ... ] ... ]
with the current `np.set_printoptions()`. For example, with
    np.set_printoptions( threshold=100, edgeitems=3, suppress=True )
only the edges of big `x` and `A` are printed.
`B` is printed as `str(B)`, for any `B` -- a number, a list, a numpy object ...

`printf()` tries to handle too few or too many arguments sensibly,
but this is iffy and subject to change.

How it works:
numpy has a function `np.array2string( A, "%.3g" )` (simplifying a bit).
`printf()` splits the format string, and for format / arg pairs
    format: % d e f g
    arg: try `np.asanyarray()`
-->  %s  np.array2string( arg, format )
Other formats and non-ndarray args are left alone, formatted as usual.

Notes:

`printf( ... end= file= )` are passed on to the python `print()` function.

Only formats `% [optional width . precision] d e f g` are implemented,
not `%(varname)format` .

%d truncates floats, e.g. 0.9 and -0.9 to 0; %.0f rounds, 0.9 to 1 .
%g is the same as %.6g, 6 digits.
%% is a single "%" character.

The function `sprintf()` returns a long string. For example,
    title = sprintf( "%s  m %g  n %g  X %.3g",
                    __file__, m, n, X )
    print( title )
    ...
    pl.title( title )

Module globals:
_fmt = "%.3g"  # default for extra args
_squeeze = np.squeeze  # (n,1) (1,n) -> (n,) print in 1 line not n

See also:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.set_printoptions.html
http://docs.python.org/2.7/library/stdtypes.html#string-formatting

'''
# http://stackoverflow.com/questions/2891790/pretty-printing-of-numpy-array


#...............................................................................
from __future__ import division, print_function
import re
import numpy as np

__version__ = "2014-02-03 feb denis"

_splitformat = re.compile( r'''(
    %
    (?<! %% )  # not %%
    -? [ \d . ]*  # optional width.precision
    \w
    )''', re.X )
    # ... %3.0f  ... %g  ... %-10s ...
    # -> ['...' '%3.0f' '...' '%g' '...' '%-10s' '...']
    # odd len, first or last may be ""

_fmt = "%.3g"  # default for extra args
_squeeze = np.squeeze  # (n,1) (1,n) -> (n,) print in 1 line not n

#...............................................................................
def printf( format, *args, **kwargs ):
    print( sprintf( format, *args ), **kwargs )  # end= file=

printf.__doc__ = __doc__


def sprintf( format, *args ):
    """ sprintf( "text %.3g text %4.1f ... %s ... ", numpy arrays or ... )
        %[defg] array -> np.array2string( formatter= )
    """
    args = list(args)
    if not isinstance( format, basestring ):
        args = [format] + args
        format = ""

    tf = _splitformat.split( format )  # [ text %e text %f ... ]
    nfmt = len(tf) // 2
    nargs = len(args)
    if nargs < nfmt:
        args += (nfmt - nargs) * ["?arg?"]
    elif nargs > nfmt:
        tf += (nargs - nfmt) * [_fmt, " "]  # default _fmt

    for j, arg in enumerate( args ):
        fmt = tf[ 2*j + 1 ]
        if arg is None \
        or isinstance( arg, basestring ) \
        or (hasattr( arg, "__iter__" ) and len(arg) == 0):
            tf[ 2*j + 1 ] = "%s"  # %f -> %s, not error
            continue
        args[j], isarray = _tonumpyarray(arg)
        if isarray  and fmt[-1] in "defgEFG":
            tf[ 2*j + 1 ] = "%s"
            fmtfunc = (lambda x: fmt % x)
            formatter = dict( float_kind=fmtfunc, int=fmtfunc )
            args[j] = np.array2string( args[j], formatter=formatter )
    try:
        return "".join(tf) % tuple(args)
    except TypeError:  # shouldn't happen
        print( "error: tf %s  types %s" % (tf, map( type, args )))
        raise


def _tonumpyarray( a ):
    """ a, isarray = _tonumpyarray( a )
        ->  scalar, False
            np.asanyarray(a), float or int
            a, False
    """
    a = getattr( a, "value", a )  # cvxpy
    if np.isscalar(a):
        return a, False
    if hasattr( a, "__iter__" )  and len(a) == 0:
        return a, False
    try:
        # map .value ?
        a = np.asanyarray( a )
    except ValueError:
        return a, False
    if hasattr( a, "dtype" )  and a.dtype.kind in "fi":  # complex ?
        if callable( _squeeze ):
            a = _squeeze( a )  # np.squeeze
        return a, True
    else:
        return a, False


#...............................................................................
if __name__ == "__main__":
    import sys

    n = 5
    seed = 0
        # run this.py n= ...  in sh or ipython
    for arg in sys.argv[1:]:
        exec( arg )
    np.set_printoptions( 1, threshold=4, edgeitems=2, linewidth=80, suppress=True )
    np.random.seed(seed)

    A = np.random.exponential( size=(n,n) ) ** 10
    x = A[0]

    printf( "x: %.3g  \nA: %.1f  \ns: %s  \nB: %s ",
                x,         A,         "str",   A )
    printf( "x %%d: %d", x )
    printf( "x %%.0f: %.0f", x )
    printf( "x %%.1e: %.1e", x )
    printf( "x %%g: %g", x )
    printf( "x %%s uses np printoptions: %s", x )

    printf( "x with default _fmt: ", x )
    printf( "no args" )
    printf( "too few args: %g %g", x )
    printf( x )
    printf( x, x )
    printf( None )
    printf( "[]:", [] )
    printf( "[3]:", [3] )
    printf( np.array( [] ))
    printf( [[]] )  # squeeze

6

और यहाँ है कि मैं क्या उपयोग करें, और यह बहुत सरल है:

print(np.vectorize("%.2f".__mod__)(sparse))

3

aroundउल्लिखित विधि को न देखकर आश्चर्य हुआ - इसका मतलब है कि प्रिंट विकल्पों में कोई गड़बड़ नहीं है।

import numpy as np

x = np.random.random([5,5])
print(np.around(x,decimals=3))

Output:
[[0.475 0.239 0.183 0.991 0.171]
 [0.231 0.188 0.235 0.335 0.049]
 [0.87  0.212 0.219 0.9   0.3  ]
 [0.628 0.791 0.409 0.5   0.319]
 [0.614 0.84  0.812 0.4   0.307]]

2

मैं अक्सर विभिन्न कॉलमों के लिए अलग-अलग प्रारूप चाहता हूं। यहां बताया गया है कि कैसे मैं एक सरल 2 डी सरणी को ट्यूप में मेरी न्यूमरी सरणी को परिवर्तित करके (स्लाइस के) प्रारूप में कुछ विविधता का उपयोग कर प्रिंट करता हूं:

import numpy as np
dat = np.random.random((10,11))*100  # Array of random values between 0 and 100
print(dat)                           # Lines get truncated and are hard to read
for i in range(10):
    print((4*"%6.2f"+7*"%9.4f") % tuple(dat[i,:]))

1

numpy.char.modआपके एप्लिकेशन के विवरण के आधार पर भी उपयोगी हो सकता है जैसे: numpy.char.mod('Value=%4.2f', numpy.arange(5, 10, 0.1))तत्वों के साथ एक स्ट्रिंग सरणी लौटाएगा "मान = 5.00", "मान = 5.10" आदि (कुछ हद तक विपरीत उदाहरण के रूप में)।


1

सुन्न सरणियों में वह विधि होती है, round(precision)जो उसी के अनुरूप गोल तत्वों के साथ एक नया खसरा सरणी लौटाती है।

import numpy as np

x = np.random.random([5,5])
print(x.round(3))

1
यह मेरे लिए काम किया जब एक matplotlib ylabel करने के लिए सरणी गुजर रहा है, धन्यवाद
हंस 10

1

मुझे लगता है कि सामान्य फ्लोट प्रारूप {: 9.5f} ठीक से काम करता है - छोटे-मूल्य वाले ई-नोटेशन को दबाने - जब एक सूची या एक लूप का उपयोग करके एक सरणी प्रदर्शित करता है। लेकिन यह प्रारूप कभी-कभी अपने ई-नोटेशन को दबाने में विफल रहता है, जब एक फॉर्मेटर में एक ही प्रिंट स्टेटमेंट में कई आइटम होते हैं। उदाहरण के लिए:

import numpy as np
np.set_printoptions(suppress=True)
a3 = 4E-3
a4 = 4E-4
a5 = 4E-5
a6 = 4E-6
a7 = 4E-7
a8 = 4E-8
#--first, display separate numbers-----------
print('Case 3:  a3, a4, a5:             {:9.5f}{:9.5f}{:9.5f}'.format(a3,a4,a5))
print('Case 4:  a3, a4, a5, a6:         {:9.5f}{:9.5f}{:9.5f}{:9.5}'.format(a3,a4,a5,a6))
print('Case 5:  a3, a4, a5, a6, a7:     {:9.5f}{:9.5f}{:9.5f}{:9.5}{:9.5f}'.format(a3,a4,a5,a6,a7))
print('Case 6:  a3, a4, a5, a6, a7, a8: {:9.5f}{:9.5f}{:9.5f}{:9.5f}{:9.5}{:9.5f}'.format(a3,a4,a5,a6,a7,a8))
#---second, display a list using a loop----------
myList = [a3,a4,a5,a6,a7,a8]
print('List 6:  a3, a4, a5, a6, a7, a8: ', end='')
for x in myList: 
    print('{:9.5f}'.format(x), end='')
print()
#---third, display a numpy array using a loop------------
myArray = np.array(myList)
print('Array 6: a3, a4, a5, a6, a7, a8: ', end='')
for x in myArray:
    print('{:9.5f}'.format(x), end='')
print()

मेरे परिणाम 4, 5 और 6 के मामलों में बग दिखाते हैं:

Case 3:  a3, a4, a5:               0.00400  0.00040  0.00004
Case 4:  a3, a4, a5, a6:           0.00400  0.00040  0.00004    4e-06
Case 5:  a3, a4, a5, a6, a7:       0.00400  0.00040  0.00004    4e-06  0.00000
Case 6:  a3, a4, a5, a6, a7, a8:   0.00400  0.00040  0.00004  0.00000    4e-07  0.00000
List 6:  a3, a4, a5, a6, a7, a8:   0.00400  0.00040  0.00004  0.00000  0.00000  0.00000
Array 6: a3, a4, a5, a6, a7, a8:   0.00400  0.00040  0.00004  0.00000  0.00000  0.00000

मेरे पास इसके लिए कोई स्पष्टीकरण नहीं है, और इसलिए मैं हमेशा कई मूल्यों के फ्लोटिंग आउटपुट के लिए एक लूप का उपयोग करता हूं।


1

मैं उपयोग करता हूं

def np_print(array,fmt="10.5f"):
    print (array.size*("{:"+fmt+"}")).format(*array)

बहुआयामी सरणियों के लिए इसे संशोधित करना मुश्किल नहीं है।


0

फिर भी एक अन्य विकल्प decimalमॉड्यूल का उपयोग करना है:

import numpy as np
from decimal import *

arr = np.array([  56.83,  385.3 ,    6.65,  126.63,   85.76,  192.72,  112.81, 10.55])
arr2 = [str(Decimal(i).quantize(Decimal('.01'))) for i in arr]

# ['56.83', '385.30', '6.65', '126.63', '85.76', '192.72', '112.81', '10.55']
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.