Próbuję wykonać mądry podział elementu w Pythonie, ale jeśli napotkano zero, potrzebuję, aby iloraz był równy zero.
Na przykład:
array1 = np.array([0, 1, 2])
array2 = np.array([0, 1, 1])
array1 / array2 # should be np.array([0, 1, 2])
Zawsze mógłbym po prostu użyć pętli for w moich danych, ale aby naprawdę wykorzystać optymalizacje numpy, potrzebuję funkcji dzielenia, która zwraca 0 po dzieleniu przez zero, zamiast ignorować błąd.
O ile czegoś nie brakuje, nie wydaje się, że numpy.seterr () może zwracać wartości w przypadku błędów. Czy ktoś ma jakieś inne sugestie, w jaki sposób mogę uzyskać najlepsze wyniki z numpy, ustawiając własną obsługę błędów dzielenia przez zero?
python
arrays
numpy
error-handling
divide-by-zero
hlin117
źródło
źródło
Odpowiedzi:
W Numpy 1.7 + możesz skorzystać z opcji „where” dla ufuncs . Możesz robić rzeczy w jednej linii i nie musisz zajmować się menedżerem kontekstu errstate.
W tym przypadku oblicza dzielenie wszędzie tam, gdzie „b” nie jest równe zero. Kiedy b jest równe zero, to pozostaje niezmienione w stosunku do wartości, którą pierwotnie podałeś w argumencie „out”.
źródło
a
i / lubb
mogą być tablicami całkowitymi, to jest to ta sama koncepcja, wystarczy jawnie ustawić prawidłowy typ wyjścia:c = np.divide(a, b, out=np.zeros(a.shape, dtype=float), where=b!=0)
out=np.zeros_like(a)
jest krytyczny, jak stwierdzono w komentarzu.np.divide(a, b, out=np.zeros_like(a), where=b!=0)
, pojawia się błądAssigning to function call which doesn't return
. Dziwne jest to, że używam go dwukrotnie i błąd pojawia się tylko raz.Opierając się na odpowiedzi @Franck Dernoncourt, naprawiając -1/0:
źródło
~
odwracaTrue
iFalse
w NumPy tablic:print ~ np.array([ True, False, False ])
.c[ ~ np.isfinite( c )] = 0
oznacza: znajdź pozycje, w którychc
jest skończone, odwróć je na NIE skończone z~
i ustaw niekończone wartości na 0. Zobacz także stackoverflow.com/search?q=[numpy]+"boolean+indexing "Opierając się na innych odpowiedziach i ulepszając:
0/0
obsługa poprzez dodanieinvalid='ignore'
donumpy.errstate()
numpy.nan_to_num()
do konwersjinp.nan
do0
.Kod:
Wynik:
źródło
0/0
jak i1/0
błędach.a
lub drugieb
zawieraNaN
, Twoje rozwiązanie nagle daje0
wynik. Może to łatwo ukryć błędy w kodzie i jest absolutnie nieoczekiwane.numpy.nan_to_num(x, copy=True, nan=0.0, posinf=None, neginf=None)
to podpis.One-linier (rzuca ostrzeżenie)
źródło
Spróbuj zrobić to w dwóch krokach. Najpierw dziel, potem zamień.
Ta
numpy.errstate
linia jest opcjonalna i po prostu zapobiega informowaniu przez numpy o "błędzie" dzielenia przez zero, ponieważ już zamierzasz to zrobić i zająć się tym przypadkiem.źródło
np.errstate(divide='ignore'):
divide='warn'
mogłoby się również przydać, gdyby nadal chciał być powiadamiany.Możesz również zamienić na podstawie
inf
, tylko jeśli dtypy tablicy są zmiennoprzecinkowe, zgodnie z tą odpowiedzią :źródło
Jedną z odpowiedzi, jaką znalazłem podczas wyszukiwania powiązanego pytania, było manipulowanie danymi wyjściowymi w oparciu o to, czy mianownik był zerowy, czy nie.
Załóżmy
arrayA
iarrayB
zostały zainicjowane, alearrayB
ma kilka zer. Możemy wykonać następujące czynności, jeśli chcemyarrayC = arrayA / arrayB
bezpiecznie obliczyć .W takim przypadku ilekroć mam w jednej z komórek dzielenie przez zero, ustawiam komórkę na równą
myOwnValue
, co w tym przypadku będzie równe zeroPrzypis: Z perspektywy czasu ta linia i tak jest niepotrzebna, ponieważ
arrayC[i]
jest tworzona na zero. Ale gdyby tak byłomyOwnValue != 0
, ta operacja by coś zrobiła.źródło
Inne rozwiązanie, o którym warto wspomnieć:
źródło