Подавление научной нотации в Numpy при создании массива из вложенного списка

У меня есть вложенный список, который выглядит следующим образом:

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]]

Если я создаю простой массив напрямую:

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

У меня нет проблем, и он печатается следующим образом:

[ 1.5    4.65   7.845]

Кто-нибудь знает, что моя проблема?

Ответ 1

Я предполагаю, что вам нужно 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

Ответ 2

для 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

Ваши параметры с numpy.set_printoptions или numpy.array2string в версии 1.3 довольно неуклюжи и ограничены (например, нет способа подавить научную нотацию для больших чисел). Похоже, что это изменится с будущими версиями, с numpy.set_printoptions (formatter =..) и numpy.array2string (style =..).

Ответ 3

Я не совсем понимаю вашу цель, но если вы хотите, чтобы результат отображался в ненаучных поплавках, вы могли бы сделать

map(list, my_array)

Если это проблема рутинга ваших значений, вы можете указать тип данных при создании

my_array = numpy.array(my_list, dtype=numpy.float64)

Я предполагаю, что модуль numpy угадывает, что ваши номера лучше всего отображаются в научной нотации, так как у вас есть такие большие числа.

Ответ 4

Демо-версия Python 2.7 Принудительное подавление всех экспоненциальных обозначений при печати ndarrays numpy, no if's и/или прикладов.

Передача suppress=True в set_printoptions работает сначала..., она подавляет экспоненциальную нотацию в небольших количествах, например:

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 символов, то numpy заставляет экспоненциальную нотацию снова! Что за черт:

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 =...) для спасения. Скажите setform_printoptions formatter, чтобы просто напечатать голый плавающий файл:

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 вблизи бесконечности в нем, и вы его распечатываете, вы будете взорваны в лицо со страницей, полной чисел,

Ответ 5

Вы можете написать функцию, которая преобразует научную нотацию в обычный, что-то вроде

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