2013-10-24 22 views
6

Biorę kurs na Fuzzy Systems i biorę my notes na moim komputerze. Oznacza to, że od czasu do czasu muszę rysować wykresy na moim komputerze. Ponieważ te wykresy są dość dobrze zdefiniowane, uważam, że dobrym pomysłem byłoby spisekowanie ich za pomocą numpy (robię notatki z LaTeXem i jestem dość szybki w powłoce Pythona, więc wyobrażam sobie, że mogę tego uniknąć).Wiele elementów w numpy.piecewise

Wykresy dla fuzzy membership functions są bardzo odcinkowo, na przykład:

Fuzzy Membership Function

Aby wykreślić to, próbowałem następujący kod dla numpy.piecewise (co daje mi tajemniczy błąd):

In [295]: a = np.arange(0,5,1) 

In [296]: condlist = [[b<=a<b+0.25, b+0.25<=a<b+0.75, b+0.75<=a<b+1] for b in range(3)] 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-296-a951e2682357> in <module>() 
----> 1 condlist = [[b<=a<b+0.25, b+0.25<=a<b+0.75, b+0.75<=a<b+1] for b in range(3)] 

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

In [297]: funclist = list(itertools.chain([lambda x:-4*x+1, lambda x: 0, lambda x:4*x+1]*3)) 

In [298]: np.piecewise(a, condlist, funclist) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-298-41168765ae55> in <module>() 
----> 1 np.piecewise(a, condlist, funclist) 

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/lib/function_base.pyc in piecewise(x, condlist, funclist, *args, **kw) 
    688  if (n != n2): 
    689   raise ValueError(
--> 690     "function list and condition list must be the same") 
    691  zerod = False 
    692  # This is a hack to work around problems with NumPy's 

ValueError: function list and condition list must be the same 

W tym momencie jestem dość zdezorientowany, jak wykreślić tę funkcję. Naprawdę nie rozumiem komunikatu o błędzie, który dodatkowo utrudnia moje próby debugowania tego.

Docelowo planuję wyeksportować tę funkcję do pliku EPS, więc doceniam każdą pomoc również w tym zakresie.

+1

Try łamanie połączonych warunkowych,

+0

Co @Zhenya powiedział . Na przykład. 'b <= a

Odpowiedz

4

Ogólnie rzecz biorąc, niezliczone tablice są bardzo dobre w robieniu sensownych rzeczy, kiedy po prostu piszesz kod tak, jakby były tylko liczbami. Porównywanie łańcuchów jest jednym z nielicznych wyjątków. Błąd widzisz jest zasadniczo ten (ukrywane trochę przez piecewise wewnętrznych i formatowania błędu ipython):

>>> a = np.array([1, 2, 3]) 
>>> 1.5 < a 
array([False, True, True], dtype=bool) 
>>> 
>>> 1.5 < a < 2.5 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 
>>> 
>>> (1.5 < a) & (a < 2.5) 
array([False, True, False], dtype=bool) 
>>> 

Można alternatywnie użyć np.logical_and, ale bitowe and działa dobrze tutaj.

Jeśli chodzi o kreślenie, numpy się nie wykonuje. Oto przykład z matplotlib:

>>> import numpy as np 
>>> def piecew(x): 
... conds = [x < 0, (x > 0) & (x < 1), (x > 1) & (x < 2), x > 2] 
... funcs = [lambda x: x+1, lambda x: 1, 
...   lambda x: -x + 2., lambda x: (x-2)**2] 
... return np.piecewise(x, conds, funcs) 
>>> 
>>> import matplotlib.pyplot as plt 
>>> xx = np.linspace(-0.5, 3.1, 100) 
>>> plt.plot(xx, piecew(xx)) 
>>> plt.show() # or plt.savefig('foo.eps') 

Uwaga, piecewise to kapryśna bestia. W szczególności potrzebuje x argumentu za tablicę, a nawet nie próbować przekształcenie go, jeśli to nie jest (w numpy żargonie: x musi być ndarray, a nie array_like):

>>> piecew(2.1) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 4, in piecew 
    File "/home/br/.local/lib/python2.7/site-packages/numpy/lib/function_base.py", line 690, in piecewise 
    "function list and condition list must be the same") 
ValueError: function list and condition list must be the same 
>>> 
>>> piecew(np.asarray([2.1])) 
array([ 0.01])