Kaila - 7 months ago 115
Python Question

# Numpy log10 function: AttributeError: 'float' object has no attribute 'log10'

``````import numpy as np
import astropy as ap

def mass(FWHM, lumi):
abs_lumi = bhm.L_1450(lumi)
s1 = (FWHM/1000)
s2 = ((abs_lumi)/(10**44))
s = [(s1**2)*(s2**0.53)]
#mass = np.log10((s1**2)*(s2**0.53)) + 6.66 #old way, didn't work
mass = np.log10(s) + 6.66
return mass
``````

I'm trying to use the numpy log10 function, but I keep getting an error that reads:

``````AttributeError: 'float' object has no attribute 'log10'
``````

I tried putting my argument into a list (s variable), but I got the same error message. FWHM and lumi are both numbers with decimal points (I think they're called floating point numbers).

The answer to this is a bit tricky and requires a bit of knowledge how Python handles integers and how numpy coerces types. Thanks @ali_m for your comment!

Assuming 64 bit integer the biggest representable integer is `9,223,372,036,854,775,807` (see for example Wikipedia) which is roughly `10**19`. But Python falls back to unlimited integer representations as soon as this value is exceeded (like in your case `10**44`). But this unlimited precision type is not nativly supported by NumPy, so results will fall back to `object`s and these `object` arrays don't support all (any?) ufuncs, like `np.log10`.

The solution is simple: Convert this large number to a floating point number:

``````>>> # Negative powers will result in floats: 44 -> -44, * instead of /
>>> np.array([10, 20]) * 10**-44
array([  1.00000000e-43,   2.00000000e-43])

>>> # you could also make the base a float: 10 -> 10.
>>> np.array([10, 20]) / 10.**44
array([  1.00000000e-43,   2.00000000e-43])

>>> # or make the exponent a float: 44 -> 44.
>>> np.array([10, 20]) / 10**44.
array([  1.00000000e-43,   2.00000000e-43])

>>> # manually cast the result to a float
>>> np.array([10, 20]) / float(10**44)
array([  1.00000000e-43,   2.00000000e-43])

>>> # not working, result is an object array which cannot be used for np.log10
>>> np.array([10, 20]) / (10**(44))
array([1e-43, 2e-43], dtype=object)
>>> #                       ^---------that's the problem!
``````

All you need is to change the third line in your function:

``````import numpy as np

def mass(FWHM, lumi):
s1 = FWHM / 1000
s2 = lumi * 10**-44   # changed line, using the first option.
s = s1**2 * s2**0.53
mass = np.log10(s) + 6.66
return mass
``````

This works at least with all my test inputs, for example:

``````>>> mass(np.array([10., 20]), np.array([10., 20]))
array([-20.13      , -19.36839411])
``````