Ошибка типа 'numpy .float64' не имеет len (), с которым я не могу разобраться, убедить Python, что он имеет дело с массивом? - PullRequest
1 голос
/ 03 марта 2020

В настоящее время я пишу сценарий, который преобразует измеренные величины галактики внутри апертуры в светимости. Я использую ноутбуки Jupyter с Python 3 и numpy. Я также распространяю неопределенность в измерениях через вторую функцию ниже.

Когда я пытаюсь вызвать функцию luminositieserror, возвращается ошибка:

TypeError: object of type 'numpy.float64' has no len().

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

#converts an array of magnitudes, a_mag, into an array of luminosities
def m_to_L(a_mag, g_dist, abs_s_mag):

      list1 =[]

      for i in range(len(a_mag)):
        ans = 10**(-0.4*(a_mag[i] -5*np.log(g_dist) -5 -abs_s_mag))
        list1.append(ans)

       return np.array(list1)

#converts an array of magnitude uncertainties, a_mag_err
#into an array of luminosity uncertainties, by calculating 
#uncertainty due to each variable in m_to_L and then adding
#them in quadrature, for every index in the array a_mag
def Luminosity_errors(a_mag, a_mag_err, g_dist, g_dist_err, abs_s_mag, abs_s_mag_err):


    list1 =[]

    for i in range(len(a_mag)):

        alpha_mag = abs(m_to_L((a_mag[i] + a_mag_err[i]), g_dist, abs_s_mag) - m_to_L(a_mag[i], g_dist, abs_s_mag))

        alpha_dist = abs(m_to_L(a_mag[i], (g_dist + g_dist_err), abs_s_mag) - m_to_L(a_mag[i], g_dist, abs_s_mag))

        alpha_solar = abs(m_to_L(a_mag[i], g_dist, (abs_s_mag + abs_s_mag_err)) - m_to_L(a_mag[i], g_dist, abs_s_mag))

        ans = (alpha_mag**2 + alpha_dist**2 + alpha_solar**2)**0.5

        list1.append(ans)

    return np.array(list1)

Затем я вызываю функцию для четко определенных переменных:

luminositieserror = Luminosity_errors(appmagnitudes, appmagerror, g_dist, g_dist_err, abs_s_mag, abs_s_mag_err)

С ошибкой:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-35-7a37ab3a0861> in <module>
----> 1 luminositieserror = Luminosity_errors(appmagnitudes, appmagerror, g_dist, g_dist_err, abs_s_mag, abs_s_mag_err)

<ipython-input-32-96474bd06045> in Luminosity_errors(a_mag, a_mag_err, g_dist, g_dist_err, abs_s_mag, abs_s_mag_err)
     14     for i in range(len(a_mag)):
     15 
---> 16         alpha_mag = abs(m_to_L((a_mag[i] + a_mag_err[i]), g_dist, abs_s_mag) - m_to_L(a_mag[i], g_dist, abs_s_mag))
     17 
     18         alpha_dist = abs(m_to_L(a_mag[i], (g_dist + g_dist_err), abs_s_mag) - m_to_L(a_mag[i], g_dist, abs_s_mag))

<ipython-input-32-96474bd06045> in m_to_L(a_mag, g_dist, abs_s_mag)
      3     list1 =[]
      4 
----> 5     for i in range(len(a_mag)):
      6         ans = 10**(-0.4*(a_mag[i]-5*np.log(g_dist)-5-abs_s_mag))
      7         list1.append(ans)

TypeError: object of type 'numpy.float64' has no len()

Насколько я понимаю, мне нужно убедить Python, что фиктивная переменная a_mag на самом деле является массивом. Любой совет о том, как это сделать, будет принята с благодарностью!

Ответы [ 2 ]

0 голосов
/ 03 марта 2020

A float64 объект является numpy скаляром. Хотя он имеет много свойств ndarray, он не является массивом и не имеет len:

In [69]: x = np.float64(12)                                                                                                
In [70]: x                                                                                                                 
Out[70]: 12.0
In [71]: x.shape                                                                                                           
Out[71]: ()                # 0d shape
In [72]: len(x)                                                                                                            
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-72-a7f4a5366567> in <module>
----> 1 len(x)

TypeError: object of type 'numpy.float64' has no len()
In [73]: x[()]              # it can be indexed with an empty tuple                                                                                      
Out[73]: 12.0

Другой способ создания массива 0d:

In [74]: y = np.array(12,float)                                                                                            
In [75]: y                                                                                                                 
Out[75]: array(12.)
In [76]: y.shape                                                                                                           
Out[76]: ()
In [77]: len(y)                                                                                                            
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-77-24c1855bc88d> in <module>
----> 1 len(y)

TypeError: len() of unsized object

Но у него тоже нет len.

Прямая итерация тоже не работает:

In [78]: for i in x: print(i)                                                                                              
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-78-c1c708d34f18> in <module>
----> 1 for i in x: print(i)

TypeError: 'numpy.float64' object is not iterable
In [79]: for i in y: print(i)                                                                                              
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-79-b6e658ea7a00> in <module>
----> 1 for i in y: print(i)

TypeError: iteration over a 0-d array

===

Есть способы убедиться объект массива является итеративным, например, убедитесь, что он равен 1d:

In [83]: z=np.atleast_1d(12.)                                                                                              
In [84]: z                                                                                                                 
Out[84]: array([12.])
In [85]: z.shape                                                                                                           
Out[85]: (1,)
In [86]: len(z)                                                                                                            
Out[86]: 1
In [87]: for i in z:print(i)                                                                                               
12.0

====

НО, ваш код пытается выполнить итерацию дважды на amag. Предполагается, что amag не менее 2d.

def Luminosity_errors(a_mag, ....:
    for i in range(len(a_mag)):
        alpha_mag = abs(m_to_L((a_mag[i] ....

def m_to_L(a_mag, g_dist, abs_s_mag):
      for i in range(len(a_mag)):
        ans = 10**(-0.4*(a_mag[i] ...

Другими словами, последняя строка пытается использовать appmagnitudes[i][j] для appmagnitudes, отправленного на Luminosity.

In [92]: mags = np.array([1.,2.,3.,4.])                                                                                    
In [93]: mags[0]                                                                                                           
Out[93]: 1.0
In [94]: len(mags[0])                                                                                                      
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-94-d70c4034220e> in <module>
----> 1 len(mags[0])

TypeError: object of type 'numpy.float64' has no len()

для 2d mags:

In [95]: mags = np.array([[1.],[2.],[3.],[4.]])                                                                            
In [96]: mags.shape                                                                                                        
Out[96]: (4, 1)
In [97]: len(mags[0])                                                                                                      
Out[97]: 1
0 голосов
/ 03 марта 2020

Переписать вашу функцию так, чтобы она работала как с NumPy массивами, так и (скалярными) числами с плавающей точкой (в частности, она не будет работать со списками: вам придется сначала преобразовать их в массив):

def m_to_L(a_mag, g_dist, abs_s_mag):
    lum = 10. ** (-0.4 * a_mag - 5 * np.log(g_dist) - 5 - abs_s_mag)
    return lum

Как видите, это также намного короче, и вы можете существенно заменить вызов функции средней строкой в ​​основном коде.

Аналогично для Luminosity_errors.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...