2013-01-18 18 views
8

od dawna czytnik, pierwszy pisarz.nieobsługiwane typy argumentów dla *: 'numpy.ndarray' i 'numpy.float64'

Szukałem w serwisie Google i przepełnienia stosu, ale nie byłem w stanie znaleźć ogólnej odpowiedzi na to pytanie.

Otrzymuję "nieobsługiwane typy argumentów dla *:" numpy.ndarray "i" numpy.float64 "" błąd w Pythonie 2.7.3 za pomocą numpy 1.6.2.

Błąd pochodzi z pomnożenia tablicy numpy i zmiennej numpy, ale nie dzieje się za każdym razem.

Na przykład:

x = np.tan(1) # numpy.float64 
y = np.array([0,1,2,3]) # numpy.ndarray 
np.multiply(x,y) # works no problem 

Albo

x = np.tan(np.abs(np.multiply(-31,41))) # numpy.float64 
y = np.square(np.add(np.divide(np.zeros(100),42),(-27)**40)) # numpy.ndarray 
np.multiply(x,y) # works no problem 

zarówno do pracy

Teraz dla dzieci problem:

np.multiply(np.square(np.add(np.divide(np.zeros(100),42),-27)**40)), 
np.tan(np.abs(np.multiply(-31,41)))) 

lub zx zdefiniowane jak wyżej:

np.multiply(np.square(np.add(np.divide(np.zeros(100),42),(-27)**40)),x) 

zarówno produkować błąd: NotImplemented

wiem losowe funkcje i numery wydawać dziwne, ale koncepcyjnie to nadal powinno działać, jak to działa, gdy obie zmienne były ustawione indywidualnie.

Dlaczego tak się dzieje? Jak mogę to naprawić w sensie ogólnym?

Dziękuję bardzo! Jason

+0

Chyba połów błąd w kodzie, może chcesz zgłosić go do numpy ludzie. Dla zapisu, jeśli 'a' to' np.ndarray', a 'x' to' np.float64', wtedy działają zarówno 'x * a' i' a * x [...] ', ale żaden z' a * x', 'a + x',' a/x' lub 'a - x' do. Trudno jest zrozumieć, dlaczego, jeśli metoda '__mul__' z' a' nie może sobie z tym poradzić, '__rmul__' z' x' nie jest wywoływane, ponieważ wydaje się, że wie jak sobie z tym poradzić ... – Jaime

+0

Dziękuję bardzo za sprawdzam to dla mnie. Postaram się zgłosić to jako problem w numpy. Czy sądzisz, że może istnieć sposób obejścia tego problemu? – Jason

+0

Jeśli zastąpisz 'x' z' x [...] 'to działa, ale to jest paskudny hack ... – Jaime

Odpowiedz

7

Podejrzewam, że problem polega na tym, że NumPy nie może przechowywać wartości Pythona long w swoich tablicach. Gdy spróbujesz to zrobić, przełącza typ danych tablicy na object. Operacje arytmetyczne na macierzy stają się trudniejsze, ponieważ NumPy nie może już wykonywać samej arytmetyki.

>>> np.array(27**40) 
array(1797010299914431210413179829509605039731475627537851106401L, dtype=object) 
>>> np.array(27**40) * np.tan(1) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unsupported operand type(s) for *: 'numpy.ndarray' and 'numpy.float64' 

Co dziwne, zamieniając kolejność argumentów może czasem działać:

>>> np.tan(1) * np.array(27**40) 
2.7986777223711575e+57 

W tym drugim przypadku, typ wyniku jest Python float, a nie tablica NumPy.

Rozwiązaniem jest unikanie tworzenia long wartości w tablicach numpy i użyć float S zamiast:

>>> np.array(27.0**40) 
array(1.797010299914431e+57) 
>>> np.array(27.0**40) * np.tan(1) 
2.7986777223711575e+57 
>>> np.multiply(np.square(np.add(np.divide(np.zeros(10),42),(-27.0)**40)),np.tan(1)) 
array([ 5.02925269e+114, 5.02925269e+114, 5.02925269e+114, 
     5.02925269e+114, 5.02925269e+114, 5.02925269e+114, 
     5.02925269e+114, 5.02925269e+114, 5.02925269e+114, 
     5.02925269e+114]) 

Jeśli nie pojawia się błąd jak to jest przyszłość, pierwszą rzeczą do zrobienia jest, aby sprawdzić dtype tablicy mnożonej. Czy zawiera wartości NumPy lub obiekty Python?

+0

Dobra rozmowa! Moja zmienna tablicy (y = np.square (np.add (np.divide (np.zeros (100), 42), (- 27) ** 40)), jak zdefiniowano powyżej w moim pytaniu) ma typ 'object' (y.dtype) Niestety nie jestem pewien, czy mogę go wymusić, ponieważ zaczyna się jako pływak, a gdzieś po drodze rzuca się na długi. – Jason

+0

To jest problem z '(-27) ** 40'. NumPy nie radzi sobie bezpośrednio z Pythonem 'long's. Można jednak użyć polecenia 'np.array' w celu przekonwertowania tablicy NumPy na inną tablicę innego typu. Na przykład 'np.array (np.array (27 ** 40), dtype = np.float64)' zwróci tablicę typu 'float64'. –

+0

Tak, udało mi się znaleźć, gdzie w moim kodzie zostały wygenerowane numery wewnętrzne 27 i 40 i rzutować je jako zmienne. Dla rekordu np.arange generuje int32. Większość funkcji numpy działa w trybach pływających, w tym np.ones i np.zeros. – Jason

-1

Czy to jest quiz? Nie rozumiem, dlaczego pytanie jest tak zafascynowane ... Wszystko sprowadza się do tego prostego faktu.

Biorąc

>>> x = 10**100 
>>> type(x) 
<type 'long'> 
>>> y = np.float64(1) 

mamy

>>> y.__mul__(x) 
1e+100 
>>> y.__rmul__(x) 
NotImplemented 

Jest to bug (lub funkcja, nie wiem) ponieważ powinien on być y.__mul__(x) == y.__rmul__(x) (przynajmniej dla tych szczególnych wartościach x i y).

Python long nie wie, jak radzić sobie z numpy.float64 mnożenia (ale to jest poprawna.)

>>> x.__mul__(y) 
NotImplemented 
>>> x.__rmul__(y) 
NotImplemented 

Więc y*x ocenia się y.__mul__(x) i daje oczekiwanego rezultatu. Wręcz przeciwnie, x*y jest najpierw testowany jako x.__mul__(y) (nie zaimplementowany, OK) niż jako y.__rmul__(x) (nie zaimplementowany, ale błąd).

Jak już wspomniano, możemy mieć nd.arrays dowolnych obiektów i wszystko staje się jasne.

Edit

Ten błąd został skorygowany (prawdopodobnie w numpy ver 1.7.):

>>> np.version.version 
'1.13.1' 
>>> x = 10**100 
>>> y = np.float64(1) 
>>> x.__mul__(y) 
NotImplemented 
>>> x.__rmul__(y) 
NotImplemented 
>>> y.__mul__(x) 
1e+100 
>>> y.__rmul__(x) 
1e+100 
>>> x*y 
1e+100 
>>> y*x 
1e+100 
+0

. Dlaczego jest to odrzucane? – Worthy7

+0

@ Worthy7 Nie mam pojęcia, dlaczego moja odpowiedź została odrzucona: IMHO wskazuje na numpy błąd odpowiedzialny za nieoczekiwane zachowanie, potwierdzone przez https://github.com/numpy/numpy/issues/2930#issuecomment-12445232 (i nie, I nie napisałem odpowiedzi po przeczytaniu tego numpy.) –

Powiązane problemy