2010-12-19 9 views
15

Mam tablicę NxM w numpy, którą chciałbym wziąć dziennik i zignorować wpisy, które były ujemne przed zrobieniem logu. Kiedy zajmie dziennik ujemnych wpisów, to zwraca -Inf, więc będę mieć macierz z pewnymi wartościami -Inf jako wynik. Następnie chciałbym podsumować kolumny tej macierzy, ale ignorując wartości -Inf - jak mogę to zrobić?Ignoring -Inf wartości w tablicach używających numpy/scipy w Pythonie

Na przykład

mylogarray = log(myarray) 
# take sum, but ignore -Inf? 
sum(mylogarray, 0) 

Wiem, że nansum i muszę równowartość, coś infsum.

Dzięki.

Odpowiedz

10

Zastosowanie masked arrays:

>>> a = numpy.array([2, 0, 1.5, -3]) 
>>> b = numpy.ma.log(a) 
>>> b 
masked_array(data = [0.69314718056 -- 0.405465108108 --], 
      mask = [False True False True], 
     fill_value = 1e+20) 

>>> b.sum() 
1.0986122886681096 
+1

czy możesz rozwinąć ten temat? Nie rozumiem tego przykładu. Jak zainicjowałeś powyższą tablicę z maskowaniem? – user248237dfsf

+3

@ user248237 - Funkcje "numpy.ma.log" itp. Automatycznie utworzą maskowaną tablicę, w której zamaskowane zostanie wszystko, co powoduje "inf" lub "nan". Jest to nieco mniej jednoznaczne, więc możesz zamiast tego zrobić: 'a = np.ma.masked_where (a == np.inf, a)', a następnie po prostu wykonaj 'b = np.log (a)' (lub dowolna inna funkcja). Alternatywnie można ominąć maskowane tablice i po prostu zrobić 'np.log (a [a! = Np.inf]) .sum()' (Możesz indeksować według tablic logicznych, jest znacznie czystszy i szybszy od opartego na filtrach odpowiedzi.) –

+0

@ user248237 Nie zainicjowałem maskowanej tablicy jawnie. 'a' jest po prostu normalną, niezamaskowaną tablicą. 'ma.log' maskuje wszystkie wartości, w których logarytm (rzeczywisty) jest niezdefiniowany. Następnie wynikowa maskowana tablica 'b' jest traktowana z grubsza, tak jakby nie było tam zamaskowanych wpisów. – Philipp

1

Użyj filter():

>>> array 
array([ 1., 2., 3., -Inf]) 
>>> sum(filter(lambda x: x != float('-inf'), array)) 
6.0 
+0

Czy jest to operacja wektoryzowana? Czy istnieje skuteczniejszy sposób? Muszę to zrobić wiele razy w moim kodzie i chciałem wektoryzacji – user248237dfsf

+0

Czy pytasz, czy odbywa się to w miejscu z iteratorów? Nie. Czy istnieje skuteczniejszy sposób? AFAIK, musisz przechodzić przez tablicę, ponieważ nie ma funkcji filtrującej, która zwraca iterator, chyba że go napiszesz. – marcog

+0

Nie sądzę, że kod filtru działa dla tablic NxM. Wydaje się, że działa on tylko dla wektorów 1xM. – user248237dfsf

1

może można indeksować macierz i zastosowanie:

import numpy as np; 
matrix = np.array([[1.,2.,3.,np.Inf],[4.,5.,6.,np.Inf],[7.,8.,9.,np.Inf]]); 
print matrix[:,1]; 
print sum(filter(lambda x: x != np.Inf,matrix[:,1])); 
print matrix[1,:]; 
print sum(filter(lambda x: x != np.Inf,matrix[1,:])); 
15

Najprostszym sposobem, aby to zrobić jest użycie numpy.ma.masked_invalid():

a = numpy.log(numpy.arange(15)) 
a.sum() 
# -inf 
numpy.ma.masked_invalid(a).sum() 
# 25.19122118273868 
Powiązane problemy