Poniższy kod generuje błąd:
Traceback (most recent call last):
File "", line 25, in <module>
sol = anna.main()
File "", line 17, in main
sol = list(map(self.eat, self.mice))
File "", line 12, in eat
calc = np.sqrt((food ** 5))
AttributeError: "int" object has no attribute "sqrt"
Kod:
import numpy as np
#import time
class anaconda():
def __init__(self):
self.mice = range(10000)
def eat(self, food):
calc = np.sqrt((food ** 5))
return calc
def main(self):
sol = list(map(self.eat, self.mice))
return sol
if __name__ == "__main__":
#start = time.time()
anna = anaconda()
sol = anna.main()
print(len(sol))
#print(time.time() - start)
Wydaje mi się, że popełniłem poważny błąd, ponieważ wygląda na to, że Python interpretuje „np” z NumPy jako liczbę całkowitą, ale nie mam pojęcia, dlaczego tak jest.
Odpowiedzi:
11 dla odpowiedzi nr 1Spróbuję dodać dokładną odpowiedź do tych, które już zostały podane. numpy.sqrt
ma pewne ograniczenia, które math.sqrt
nie ma.
import math
import numpy # version 1.13.3
print(math.sqrt(2 ** 64 - 1))
print(numpy.sqrt(2 ** 64 - 1))
print(math.sqrt(2 ** 64))
print(numpy.sqrt(2 ** 64))
zwraca (z Python 3.5):
4294967296.0
4294967296.0
4294967296.0
Traceback (most recent call last):
File "main.py", line 8, in <module>
print(numpy.sqrt(2 ** 64))
AttributeError: "int" object has no attribute "sqrt"
W rzeczywistości, 2 ** 64
jest równe 18,446,744,073,709,551,616
i zgodnie ze standardem typów danych C (wersja C99), long long unsigned integer
typ zawiera przynajmniej zakres pomiędzy 0
i 18,446,744,073,709,551,615
w zestawie.
The AttributeError
występuje, ponieważ numpy
, widząc typ, którego nie umie obsługiwać (po konwersji na typ danych C), domyślnie wywołuje funkcję sqrt
metoda na obiekcie (ale to nie istnieje). Jeśli użyjemy liczb zmiennoprzecinkowych zamiast liczb całkowitych, wszystko będzie działać przy użyciu numpy
:
import numpy # version 1.13.3
print(numpy.sqrt(float(2 ** 64)))
zwraca:
4294967296.0
Więc zamiast zastępować numpy.sqrt
przez math.sqrt
, możesz alternatywnie wymienić calc = np.sqrt(food ** 5)
przez calc = np.sqrt(float(food ** 5))
w twoim kodzie.
Mam nadzieję, że ten błąd będzie dla ciebie bardziej sensowny.
3 dla odpowiedzi № 2
Jak zauważyli inni, sprowadza się to do tego np.sqrt(7131 ** 5)
działa ale np.sqrt(7132 ** 5)
zwraca błąd:
import numpy as np
print(np.sqrt(7131 ** 5))
print(np.sqrt(7132 ** 5))
# 4294138928.9
Traceback (most recent call last):
File "main.py", line 4, in <module>
print(np.sqrt(7132 ** 5))
AttributeError: "int" object has no attribute "sqrt"
Od np.sqrt
docs nie wspominając o żadnych ograniczeniach argumentu, uważam to za dziwaczny błąd.
2 dla odpowiedzi nr 3
Możesz zastąpić numpy wbudowaną funkcją math.sqrt w następujący sposób:
import math
class anaconda():
def __init__(self):
self.mice = range(10000)
def eat(self, food):
calc = math.sqrt(food ** 5)
return calc
def main(self):
sol = list(map(self.eat, self.mice))
return sol
if __name__ == "__main__":
anna = anaconda()
sol = anna.main()
print(len(sol))
Myślę, że problemem twojego kodu jest to, że typrawdopodobnie osiągają limit (nie jestem jeszcze pewien, dlaczego podnosi ten mylący błąd), ponieważ 10000 ** 5 to naprawdę duża liczba. Możesz to sprawdzić, zmniejszając swój zasięg (10000) do zasięgu (1000). Zauważysz, że Twój kod działa idealnie dobrze:
import numpy as np
class anaconda():
def __init__(self):
self.mice = range(1000)
def eat(self, food):
calc = np.sqrt((food ** 5))
return calc
def main(self):
sol = list(map(self.eat, self.mice))
print sol
return sol
if __name__ == "__main__":
anna = anaconda()
sol = anna.main()
print(len(sol))
Działa to idealnie dobrze, po prostu zmniejszając zasięg (10000) do zasięgu (1000)
1 dla odpowiedzi nr 4
Tak naprawdę nie potrzebujesz numpy
ani math
bo sqrt(x)
jest x**0.5
. Więc:
sqrt(x**5) = x ** (5/2) = x ** 2.5
Oznacza to, że możesz zastąpić swój kod:
class anaconda():
def __init__(self):
self.mice = range(10000)
def eat(self, food):
calc = food ** 2.5
return calc
def main(self):
sol = list(map(self.eat, self.mice))
return sol
if __name__ == "__main__":
anna = anaconda()
sol = anna.main()
print(len(sol))
NumPy
Jeśli chcesz korzystać z NumPy, możesz cieszyć się faktem, że możesz pracować z tablicami tak, jakby były skalarami:
import numpy as np
class anaconda():
def __init__(self):
self.mice = np.arange(10000)
def eat(self, food):
return food ** 2.5
def main(self):
return self.eat(self.mice)
if __name__ == "__main__":
anna = anaconda()
sol = anna.main()
print(len(sol))
Krótki refaktor
Usuwając wszystkie niepotrzebne nazwy obiektowe z dziwnymi nazwami, kod staje się:
import numpy as np
print(np.arange(10000) ** 2.5)