numpy.piecewise中的多个部分 [英] Multiple Pieces in a numpy.piecewise

查看:102
本文介绍了numpy.piecewise中的多个部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在上模糊系统课程,并且上我的笔记在我的计算机上.这意味着我不得不不时在计算机上绘制图形.由于这些图的定义非常好,我觉得用numpy绘制它们是一个好主意(我在LaTeX上做笔记,而且我在python shell上非常快,所以我认为可以摆脱这种情况)

模糊隶属函数的图形是高度分段的,例如:

为了对此进行绘制,我尝试了以下代码用于numpy.piecewise(这给了我一个神秘的错误):

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

在这一点上,我对如何绘制此函数感到很困惑.我不太了解错误消息,这进一步阻碍了我调试此消息的努力.

最终,我希望将此函数绘制并导出到EPS文件中,因此,我也很感谢您提供的帮助.

解决方案

通常,当您仅将代码编写为数字时,numpy数组非常擅长做明智的事情.链接比较是罕见的例外之一.您所看到的错误本质上是这样的(piecewise内部和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)
>>> 

您也可以使用np.logical_and,但是按位and在这里可以正常工作.

就绘图而言,numpy本身不执行任何操作.这是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')

请注意,piecewise是反复无常的野兽.特别是,它需要将其x参数设置为数组,如果不是,则甚至不会尝试对其进行转换(用numpy说法:x必须是ndarray,而不是):

>>> 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])

I am taking a course on Fuzzy Systems and I take my notes on my computer. This means that I have to draw graphs on my computer from time to time. Since these graphs are quite well defined, I feel that plotting them with numpy would be a good idea (I take notes with LaTeX, and I'm pretty quick on the python shell, so I figure I can get away with this).

The graphs for fuzzy membership functions are highly piecewise, for example:

In order to plot this, I tried the following code for a numpy.piecewise (which gives me a cryptic error):

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

At this point, I'm fairly confused as to how to plot this function. I don't really understand the error message, which is further impeding my efforts to debug this.

Ultimately, I am looking to plot and export this function into an EPS file, so I'd appreciate any help along those lines as well.

解决方案

In general, numpy arrays are very good at doing sensible things when you just write the code as if they were just numbers. Chaining comparisons is one of the rare exceptions. The error you're seeing is essentially this (obfuscated a bit by piecewise internals and ipython error formatting):

>>> 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)
>>> 

You can alternatively use np.logical_and, but bitwise and works just fine here.

As far as plotting is concerned, numpy itself doesn't do any. Here's an example with 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')

Notice that piecewise is a capricious beast. In particular, it needs its x argument to be an array, and won't even try converting it if it isn't (in numpy parlance: x needs to be an ndarray, not an 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])

这篇关于numpy.piecewise中的多个部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆