과학적 표기법없이 주어진 정밀도로 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=3and 안에 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]

부동 소수점 끝에서 0이 제거되지 않도록하려면 :

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]

모든 print 문에 사용되는 일반 출력 형식을 설정하는 것과 달리 특정 print 문에만 서식을 적용하는 방법이 있습니까?
bph

7
@Hiett : 단 하나의 인쇄 옵션을 설정하는 NumPy 기능은 없지만 print컨텍스트 관리자를 사용하여 비슷한 것을 만들 수 있습니다. 내가 의미하는 바를 표시하기 위해 위의 게시물을 편집했습니다.
unutbu

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]합니까?
Norfeldt

2
@ Norfeldt : 위의 방법을 추가했습니다.
unutbu

1
이것은 잘 작동합니다. 참고로, set_printoptions문자열 표현을 원하지만 반드시을 사용할 필요는없는 경우에도 사용할 수 있습니다 print. __str__()numpy 배열 인스턴스를 호출 하면 설정 한 인쇄 옵션에 따라 형식이 지정된 문자열이 표시됩니다.
Jayesh

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 (출시일 보류 중) 에는 인쇄 옵션을 로컬로 설정하기위한 컨텍스트 관리자포함됩니다 . 즉, 다음은 고유 한 컨텍스트 관리자를 작성하지 않고도 허용 된 답변 (unutbu 및 Neil G) 의 해당 예제와 동일하게 작동합니다 . 예를 들면 다음과 같습니다.

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

문자열로 결과를 얻기가 너무 쉬운 보석 (오늘의 numpy 버전에서)은 거부 된 답변에 숨겨져 있습니다. 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

나는 종종 다른 열이 다른 형식을 갖기를 원합니다. 다음은 NumPy 배열을 튜플로 변환하여 다양한 형식을 사용하여 간단한 2D 배열을 인쇄하는 방법입니다.

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)).


1

round(precision)numpy 배열에는 요소가 반올림 된 새로운 numpy 배열을 반환하는 메소드 가 있습니다.

import numpy as np

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

1
이것은 matplotlib ylabel에 배열을 전달할 때 나를 위해 일했습니다. 감사합니다
Hans

1

루프를 사용하여 목록이나 배열을 표시 할 때 일반적인 float 형식 {: 9.5f}가 올바르게 작동합니다 (작은 값의 전자 표기법 제외). 그러나 포맷터에 단일 print 문에 여러 항목이있는 경우 해당 형식이 전자 표기법을 억제하지 못하는 경우가 있습니다. 예를 들면 다음과 같습니다.

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']
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.