2014-05-22 10 views
10

Dostaję ten wyjątek z powodu, którego nie rozumiem. Jest to dość skomplikowane, gdzie mój np.array v pochodzi, ale tutaj jest kod, gdy wystąpi wyjątek:Nieoczekiwany wyjątek w numpy.isfinite()

print v, type(v) 

for val in v: 
    print val, type(val) 

print "use isfinte() with astype(float64): " 
np.isfinite(v.astype("float64")) 

print "use isfinite() as usual: " 
try: 
    np.isfinite(v) 
except Exception,e: 
    print e 

To daje następujący wynik:

[6.4441947744288255 7.2246449651781788 4.1028442021807656 
4.8832943929301189] <type 'numpy.ndarray'> 

6.44419477443 <type 'numpy.float64'> 
7.22464496518 <type 'numpy.float64'> 
4.10284420218 <type 'numpy.float64'> 
4.88329439293 <type 'numpy.float64'> 

np.isfinte() with astype(float64): 
[ True True True True] 

np.isfinte() as usual: 
ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe'' 

ja nie rozumiem TypeError . Wszystkie elementy to np.float64 i powinny być w porządku. Może błąd? Ten błąd pojawia się tylko czasami, ale nie mogę znaleźć różnic między tablicami. Zawsze mają ten sam typ.

Z góry dziękuję.

EDIT: Przykład roboczy:

Struktury danych są tak małe, jak pokazano powyżej.

import pandas as pd 
import numpy as np 


def forward_estim(H,end): 

    old_idx = H.index 
    new_idx = pd.period_range(old_idx[-1],end,freq=old_idx.freq) 

    H_estim = pd.DataFrame(columns=["A","B","C","D"],index=new_idx) 

    H_chg = H.values[1:]-H.values[:-1] 
    mean_ = H_chg.mean() 
    std_ = H_chg.std() 

    H_estim.ix[0] = H.ix[-1] 

    for i in range(1,len(H_estim)): 
     H_estim.A[i] = H_estim.A[i-1] + mean_ + std_/2 
     H_estim.B[i] = H_estim.B[i-1] + mean_ + std_ 
     H_estim.C[i] = H_estim.C[i-1] + mean_ - std_ 
     H_estim.D[i] = H_estim.D[i-1] + mean_ - std_/2 

    return H_estim.ix[1:] 


H_idx = pd.period_range("2010-01-01","2012-01-01",freq="A") 
print H_idx 

H = pd.Series(np.array([2.3,3.0,2.9]),index=H_idx) 
print H 

H_estim = forward_estim(H,"2014-01-01") 
print H_estim 

np.isfinite(H_estim.values.astype("float64")) 
print "This works!" 

np.isfinite(H_estim.values) 
print "This does not work!" 

ten prowadzony jest tutaj używając:

MacOSX Mavericks, Python 2.7.6, 1.8.1, numpy pandy 0.13.1

+0

Powinieneś zdecydowanie stwierdzić, z którymi wersjami Pythona i numpy pracujesz w jakim systemie. Byłoby bardzo korzystne, gdybyś mógł wymyślić minimalny przykład odtwarzający problem. –

+0

Edytował oryginalny post z przykładem. Spowoduje to zgłoszenie wyjątku wymienionego powyżej w mojej konfiguracji komputera/pythona. – user2532323

Odpowiedz

10

H_estim.values jest numpy tablicy z typem danych object (Spójrz na H_estim.values.dtype):

In [62]: H_estim.values 
Out[62]: 
array([[3.4000000000000004, 3.6000000000000005, 2.7999999999999998, 3.0], 
     [3.9000000000000004, 4.3000000000000007, 2.6999999999999993, 
     3.0999999999999996]], dtype=object) 

In [63]: H_estim.values.dtype 
Out[63]: dtype('O') 

W object tablicy, dane przechowywane w pamięci tablicy są wskaźniki do obiektów Pythona, nie same obiekty. W tym przypadku obiekty są np.float64 przypadki:

In [65]: H_estim.values[0,0] 
Out[65]: 3.4000000000000004 

In [66]: type(H_estim.values[0,0]) 
Out[66]: numpy.float64 

więc pod wieloma względami, w tym tablica wygląda i zachowuje się jak tablica np.float64 wartości, ale to nie jest to samo. W szczególności numpy ufuncs (w tym np.isfinite) nie obsługuje tablic obiektów.

H_estim.values.astype(np.float64) konwertuje tablicę na taką z typem danych np.float64 (tj. Tablicą, w której elementy tablicy są rzeczywistymi wartościami zmiennoprzecinkowymi, a nie wskaźnikami do obiektów). Porównaj poniższe dane z wynikami pokazanymi powyżej dla H_estim.values.

In [70]: a = H_estim.values.astype(np.float64) 

In [71]: a 
Out[71]: 
array([[ 3.4, 3.6, 2.8, 3. ], 
     [ 3.9, 4.3, 2.7, 3.1]]) 

In [72]: a.dtype 
Out[72]: dtype('float64') 
+0

Dzięki, Warren. To odpowiada na moje pytanie bardzo szczegółowo. Aby dodać moje pytanie: Po raz drugi "nieoczekiwane" zachowanie można obejść, używając metody .astype(). – user2532323

+0

... Czy w funkcji forward_estim() robię coś, co jest pojęciowo niewłaściwe, czy też jest to jedna z wad w językach dynamicznie pisanych, które zazwyczaj ignorujesz/zapominasz o typach (i "strukturach typu wewnętrznego" pakietów) a tego typu "wymuszające" polecenia, takie jak .astype(), są po prostu rzeczami, które musisz czasem zrobić. Ta funkcja należy do około 10.000 linii kodu i do tej pory wszystko działało sprawnie. – user2532323

+1

Tablica obiektów jest tworzona przez Pandy. Pandy używają tablic obiektów jako wygodnego sposobu obsługi macierzy przechowujących heterogeniczne typy danych i zwykle działa dobrze, ale czasami, tak, musisz zdawać sobie sprawę z jego ograniczeń. Nawiasem mówiąc, jeśli używasz 'isfinite' do sprawdzenia NaN, możesz użyć funkcji Pandas' isnull' ('pd.isnull' lub metody DataFrame). Ale 'isnull' nie pomaga, jeśli sprawdzasz' np.inf'. –

1

przyjąć, że "Wszystkie elementy są np.float64 i powinno być w porządku: ". Tak jednak nie jest. Jak duża jest struktura danych? Czy możesz spojrzeć na wszystkie wartości i znaleźć coś podejrzanego? Od http://matplotlib.1069221.n5.nabble.com/type-error-with-python-3-2-and-version-1-1-1-of-matplotlib-numpy-error-td38784.html widzimy, że ten problem może pojawić się w przypadku typów danych Decimal. Czy istnieje sposób, aby stworzyć minimalny przykład roboczy, który odtwarza problem? Powinno być możliwe, a kiedy utworzysz ten przykład, najprawdopodobniej już dokładnie wskażesz problem.

+0

Dzięki za link. Znalazłem to również przed pytaniem. Dlatego napisałem pętlę for drukującą typ() danych, aby potwierdzić, że są np.float64. To właśnie mnie dezorientuje, jak używanie.astype ("float64") pomoże, chociaż dane już są tego typu. – user2532323

Powiązane problemy