중첩 목록에서 배열을 만들 때 Numpy에서 과학적 표기법 억제


160

다음과 같은 중첩 Python 목록이 있습니다.

my_list = [[3.74, 5162, 13683628846.64, 12783387559.86, 1.81],
 [9.55, 116, 189688622.37, 260332262.0, 1.97],
 [2.2, 768, 6004865.13, 5759960.98, 1.21],
 [3.74, 4062, 3263822121.39, 3066869087.9, 1.93],
 [1.91, 474, 44555062.72, 44555062.72, 0.41],
 [5.8, 5006, 8254968918.1, 7446788272.74, 3.25],
 [4.5, 7887, 30078971595.46, 27814989471.31, 2.18],
 [7.03, 116, 66252511.46, 81109291.0, 1.56],
 [6.52, 116, 47674230.76, 57686991.0, 1.43],
 [1.85, 623, 3002631.96, 2899484.08, 0.64],
 [13.76, 1227, 1737874137.5, 1446511574.32, 4.32],
 [13.76, 1227, 1737874137.5, 1446511574.32, 4.32]]

그런 다음 Numpy를 가져 와서 인쇄 옵션을로 설정합니다 (suppress=True). 배열을 만들 때 :

my_array = numpy.array(my_list)

나는 내 인생에서 과학적 표기법을 억제 할 수 없다.

[[  3.74000000e+00   5.16200000e+03   1.36836288e+10   1.27833876e+10
    1.81000000e+00]
 [  9.55000000e+00   1.16000000e+02   1.89688622e+08   2.60332262e+08
    1.97000000e+00]
 [  2.20000000e+00   7.68000000e+02   6.00486513e+06   5.75996098e+06
    1.21000000e+00]
 [  3.74000000e+00   4.06200000e+03   3.26382212e+09   3.06686909e+09
    1.93000000e+00]
 [  1.91000000e+00   4.74000000e+02   4.45550627e+07   4.45550627e+07
    4.10000000e-01]
 [  5.80000000e+00   5.00600000e+03   8.25496892e+09   7.44678827e+09
    3.25000000e+00]
 [  4.50000000e+00   7.88700000e+03   3.00789716e+10   2.78149895e+10
    2.18000000e+00]
 [  7.03000000e+00   1.16000000e+02   6.62525115e+07   8.11092910e+07
    1.56000000e+00]
 [  6.52000000e+00   1.16000000e+02   4.76742308e+07   5.76869910e+07
    1.43000000e+00]
 [  1.85000000e+00   6.23000000e+02   3.00263196e+06   2.89948408e+06
    6.40000000e-01]
 [  1.37600000e+01   1.22700000e+03   1.73787414e+09   1.44651157e+09
    4.32000000e+00]
 [  1.37600000e+01   1.22700000e+03   1.73787414e+09   1.44651157e+09
    4.32000000e+00]]

간단한 numpy 배열을 직접 만들면 :

new_array = numpy.array([1.5, 4.65, 7.845])

문제가 없으며 다음과 같이 인쇄됩니다.

[ 1.5    4.65   7.845]

내 문제가 무엇인지 아는 사람이 있습니까?


2
numpy.set_printoptionsnumpy 배열을 인쇄하는 방법을 제어합니다. 그러나 과학적 표기법을 완전히 억제 할 수는 없습니다. 1e-2에서 1e9 사이의 값을 가지기 때문에 전환됩니다. 범위가 더 작 으면 과학적 표기법을 사용하여 표시하지 않습니다. print하지만로 표시되는 방식이 왜 중요 합니까? 저장하려고하면 savetxt등을 사용하십시오 .
Joe Kington

2
실제로 당신이 요구하는 것은 아니지만 numpy.round (높은 정밀도로도 사용)를 사용하여 SVD 재구성 행렬에서 7.00000000e +00처럼 보이는 과학적 표기법을 제거 할 수있었습니다. 과학적 표기법 (?) 때문에 평등을 주장하지는 않습니다. np.set_printoptions (suppress = True)가이 문제를 해결하지 못했기 때문에 언급하고 있습니다.
BrechtDeMan

답변:


260

나는 당신이 필요로하는 것 같다 np.set_printoptions(suppress=True): 자세한 내용은 여기를 참조하십시오, http://pythonquirks.blogspot.fr/2009/10/controlling-printing-in-numpy.html

모든 기능 매개 변수를 포함하는 SciPy.org numpy 설명서 (서류는 위 링크에 자세히 나와 있지 않음)는 다음을 참조하십시오. https://docs.scipy.org/doc/numpy/reference/generated/numpy.set_printoptions.html


7
최소한 그 기능에 대한 요약을 제공 할 수 있습니까?
찰리 파커

4
제 경우에는 여전히 과학적 표기법을 사용합니다
lesolorzanov

2
@ ZloySmiertniy, 아래 Eric의 답변과 같이 포맷터를 사용하십시오. 내가 사용 np.set_printoptions(formatter={'all':lambda x: str(x)})
nurp

37

파이썬은 numpy ndarray, wrangle text justification, rounding 및 print 옵션을 인쇄 할 때 모든 지수 표기법을 강제 억제합니다.

다음은 진행중인 작업에 대한 설명입니다. 코드 데모를 보려면 맨 아래로 스크롤하십시오.

매개 변수 suppress=True를 함수에 전달 set_printoptions하면 다음과 같이 할당 된 기본 8 자 공간에 맞는 숫자에 대해서만 작동합니다.

import numpy as np
np.set_printoptions(suppress=True) #prevent numpy exponential 
                                   #notation on print, default False

#            tiny     med  large
a = np.array([1.01e-5, 22, 1.2345678e7])  #notice how index 2 is 8 
                                          #digits wide

print(a)    #prints [ 0.0000101   22.     12345678. ]

그러나 너비가 8자를 초과하는 숫자를 전달하면 다음과 같이 지수 표기법이 다시 적용됩니다.

np.set_printoptions(suppress=True)

a = np.array([1.01e-5, 22, 1.2345678e10])    #notice how index 2 is 10
                                             #digits wide, too wide!

#exponential notation where we've told it not to!
print(a)    #prints [1.01000000e-005   2.20000000e+001   1.23456780e+10]

numpy는 숫자를 반으로 자르기 때문에 잘못 표시하거나 지수 표기법을 적용하여 후자를 선택합니다.

다음은 set_printoptions(formatter=...)인쇄 및 반올림 옵션을 지정하는 방법입니다. 에게 set_printoptions단지 베어 플로트를 베어 인쇄 :

np.set_printoptions(suppress=True,
   formatter={'float_kind':'{:f}'.format})

a = np.array([1.01e-5, 22, 1.2345678e30])  #notice how index 2 is 30
                                           #digits wide.  

#Ok good, no exponential notation in the large numbers:
print(a)  #prints [0.000010 22.000000 1234567799999999979944197226496.000000] 

우리는 지수 표기법을 강제 억제했지만 반올림하거나 정당화되지 않았으므로 추가 형식 지정 옵션을 지정하십시오.

np.set_printoptions(suppress=True,
   formatter={'float_kind':'{:0.2f}'.format})  #float, 2 units 
                                               #precision right, 0 on left

a = np.array([1.01e-5, 22, 1.2345678e30])   #notice how index 2 is 30
                                            #digits wide

print(a)  #prints [0.00 22.00 1234567799999999979944197226496.00]

ndarrays의 모든 지수 개념을 강제 억제하는 단점은 ndarray가 무한대 근처에서 거대한 float 값을 가져 와서 인쇄하면 페이지가 가득 찬 얼굴로 폭발 할 것입니다.

전체 예제 데모 1 :

from pprint import pprint
import numpy as np
#chaotic python list of lists with very different numeric magnitudes
my_list = [[3.74, 5162, 13683628846.64, 12783387559.86, 1.81],
           [9.55, 116, 189688622.37, 260332262.0, 1.97],
           [2.2, 768, 6004865.13, 5759960.98, 1.21],
           [3.74, 4062, 3263822121.39, 3066869087.9, 1.93],
           [1.91, 474, 44555062.72, 44555062.72, 0.41],
           [5.8, 5006, 8254968918.1, 7446788272.74, 3.25],
           [4.5, 7887, 30078971595.46, 27814989471.31, 2.18],
           [7.03, 116, 66252511.46, 81109291.0, 1.56],
           [6.52, 116, 47674230.76, 57686991.0, 1.43],
           [1.85, 623, 3002631.96, 2899484.08, 0.64],
           [13.76, 1227, 1737874137.5, 1446511574.32, 4.32],
           [13.76, 1227, 1737874137.5, 1446511574.32, 4.32]]

#convert python list of lists to numpy ndarray called my_array
my_array = np.array(my_list)

#This is a little recursive helper function converts all nested 
#ndarrays to python list of lists so that pretty printer knows what to do.
def arrayToList(arr):
    if type(arr) == type(np.array):
        #If the passed type is an ndarray then convert it to a list and
        #recursively convert all nested types
        return arrayToList(arr.tolist())
    else:
        #if item isn't an ndarray leave it as is.
        return arr

#suppress exponential notation, define an appropriate float formatter
#specify stdout line width and let pretty print do the work
np.set_printoptions(suppress=True,
   formatter={'float_kind':'{:16.3f}'.format}, linewidth=130)
pprint(arrayToList(my_array))

인쇄물:

array([[           3.740,         5162.000,  13683628846.640,  12783387559.860,            1.810],
       [           9.550,          116.000,    189688622.370,    260332262.000,            1.970],
       [           2.200,          768.000,      6004865.130,      5759960.980,            1.210],
       [           3.740,         4062.000,   3263822121.390,   3066869087.900,            1.930],
       [           1.910,          474.000,     44555062.720,     44555062.720,            0.410],
       [           5.800,         5006.000,   8254968918.100,   7446788272.740,            3.250],
       [           4.500,         7887.000,  30078971595.460,  27814989471.310,            2.180],
       [           7.030,          116.000,     66252511.460,     81109291.000,            1.560],
       [           6.520,          116.000,     47674230.760,     57686991.000,            1.430],
       [           1.850,          623.000,      3002631.960,      2899484.080,            0.640],
       [          13.760,         1227.000,   1737874137.500,   1446511574.320,            4.320],
       [          13.760,         1227.000,   1737874137.500,   1446511574.320,            4.320]])

전체 예제 데모 2 :

import numpy as np  
#chaotic python list of lists with very different numeric magnitudes 

#            very tiny      medium size            large sized
#            numbers        numbers                numbers

my_list = [[0.000000000074, 5162, 13683628846.64, 1.01e10, 1.81], 
           [1.000000000055,  116, 189688622.37, 260332262.0, 1.97], 
           [0.010000000022,  768, 6004865.13,   -99e13, 1.21], 
           [1.000000000074, 4062, 3263822121.39, 3066869087.9, 1.93], 
           [2.91,            474, 44555062.72, 44555062.72, 0.41], 
           [5,              5006, 8254968918.1, 7446788272.74, 3.25], 
           [0.01,           7887, 30078971595.46, 27814989471.31, 2.18], 
           [7.03,            116, 66252511.46, 81109291.0, 1.56], 
           [6.52,            116, 47674230.76, 57686991.0, 1.43], 
           [1.85,            623, 3002631.96, 2899484.08, 0.64], 
           [13.76,          1227, 1737874137.5, 1446511574.32, 4.32], 
           [13.76,          1337, 1737874137.5, 1446511574.32, 4.32]] 
import sys 
#convert python list of lists to numpy ndarray called my_array 
my_array = np.array(my_list) 
#following two lines do the same thing, showing that np.savetxt can 
#correctly handle python lists of lists and numpy 2D ndarrays. 
np.savetxt(sys.stdout, my_list, '%19.2f') 
np.savetxt(sys.stdout, my_array, '%19.2f') 

인쇄물:

 0.00             5162.00      13683628846.64      10100000000.00              1.81
 1.00              116.00        189688622.37        260332262.00              1.97
 0.01              768.00          6004865.13 -990000000000000.00              1.21
 1.00             4062.00       3263822121.39       3066869087.90              1.93
 2.91              474.00         44555062.72         44555062.72              0.41
 5.00             5006.00       8254968918.10       7446788272.74              3.25
 0.01             7887.00      30078971595.46      27814989471.31              2.18
 7.03              116.00         66252511.46         81109291.00              1.56
 6.52              116.00         47674230.76         57686991.00              1.43
 1.85              623.00          3002631.96          2899484.08              0.64
13.76             1227.00       1737874137.50       1446511574.32              4.32
13.76             1337.00       1737874137.50       1446511574.32              4.32
 0.00             5162.00      13683628846.64      10100000000.00              1.81
 1.00              116.00        189688622.37        260332262.00              1.97
 0.01              768.00          6004865.13 -990000000000000.00              1.21
 1.00             4062.00       3263822121.39       3066869087.90              1.93
 2.91              474.00         44555062.72         44555062.72              0.41
 5.00             5006.00       8254968918.10       7446788272.74              3.25
 0.01             7887.00      30078971595.46      27814989471.31              2.18
 7.03              116.00         66252511.46         81109291.00              1.56
 6.52              116.00         47674230.76         57686991.00              1.43
 1.85              623.00          3002631.96          2899484.08              0.64
13.76             1227.00       1737874137.50       1446511574.32              4.32
13.76             1337.00       1737874137.50       1446511574.32              4.32

반올림은 2 단위의 정밀도로 일관성이 있으며, 매우 크고 e+x작은 e-x범위 에서 지수 표기법이 억제됩니다 .


22

1D 및 2D 배열의 경우 np.savetxt를 사용하여 특정 형식 문자열을 사용하여 인쇄 할 수 있습니다.

>>> import sys
>>> x = numpy.arange(20).reshape((4,5))
>>> numpy.savetxt(sys.stdout, x, '%5.2f')
 0.00  1.00  2.00  3.00  4.00
 5.00  6.00  7.00  8.00  9.00
10.00 11.00 12.00 13.00 14.00
15.00 16.00 17.00 18.00 19.00

v1.3에서 numpy.set_printoptions 또는 numpy.array2string을 사용하는 옵션은 상당히 어수선하고 제한적입니다 (예 : 숫자에 대한 과학적 표기법을 억제 할 방법이 없음). numpy.set_printoptions (formatter = ..) 및 numpy.array2string (style = ..)을 사용하여 향후 버전에서 변경 될 것으로 보입니다.


0

과학적 표기법을 규칙적으로 변환하는 함수를 작성할 수 있습니다.

def sc2std(x):
    s = str(x)
    if 'e' in s:
        num,ex = s.split('e')
        if '-' in num:
            negprefix = '-'
        else:
            negprefix = ''
        num = num.replace('-','')
        if '.' in num:
            dotlocation = num.index('.')
        else:
            dotlocation = len(num)
        newdotlocation = dotlocation + int(ex)
        num = num.replace('.','')
        if (newdotlocation < 1):
            return negprefix+'0.'+'0'*(-newdotlocation)+num
        if (newdotlocation > len(num)):
            return negprefix+ num + '0'*(newdotlocation - len(num))+'.0'
        return negprefix + num[:newdotlocation] + '.' + num[newdotlocation:]
    else:
        return s
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.