9

我正在做一些通用数据的pyplotting,并将其从功率值转换为dB值。由于这些值来自于系统,所以0被用作'有用的数据在此结束'指示符(数学的性质,而不是定义的值)。Python;异常感知地图()

我通常与这些交易被包裹在一个try转换/ except和返回默认的“低”值的方式,如

def f(value): 
    try: 
     return convert(value) 
    except ValueError: 
     return -140 #implementation specific, don't worry 

这是非常愉快的90%使用我的框架内,除了绘图之外。

我很懒所以我在一分钟做的是:

pl.plot(xvals,map(f,yvals)) 

这正确绘制数据,当数据结束,掉价掉下悬崖,这是预期的行为。但是我想要发生的情况是,当它遇到一个ValueError异常,并且完全抛弃f()时,该图只能到结束

除了把地图变成循环,任何人都有什么好的想法?

更新:

我使用Pylab/MatplotLib “端点” 是执行相关的;有时以上并不重要,因为没有“坏”价值。这一切都是为了让我懒惰,并使用matplotlibs图形缩放,而不是基于ydata的最小值重新设置动态ylim(在这种情况下,我不做atm,只是ylim(-140)。)

浮夸的重要更新在回答: unutbu的答案是我实际将用于我的实现,由于(在问题依赖项中没有提及),因为在这个经常使用的函数中提高StopIteration会造成无关 - 这个问题控制逻辑将所有这些其他实例放在try-except中;有时-inf比你想象的更有意义。

感谢大家的快速,我非常抱歉unutbu为QuestionFail。

+0

问题是有点不清楚。如果你把地图分解成一个循环,你能展示它的样子吗? – Claudiu 2011-03-30 17:06:48

回答

10

也许在绘图库中有一些窍门,但是更好的选择似乎不会产生这样的数据开始。这并不是说map节省你们三十行代码...

使用itertools.takewhile(lambda y: y != NO_VALUE, (f(y) for y in yvals))(如果绘图库需要一个列表,而不是一个可迭代它包装在一个呼叫list)。

编辑:我有一个更好的主意:在包装,加

except ValueError: 
    raise StopIteration 

是例外信号“iterale结束”,并map方面它。

+0

关于旧解决方案的注释,imap()是map()的迭代器版本,所以可以使用时间而不必运行所有数据。但是需要最新的Python版本。 – 2011-03-30 18:59:06

+0

@Gustav Larsson:'map'是列出解析,因为'imap'是生成器表达式。我可以随时使用生成器表达式,包括这里。 – delnan 2011-03-30 19:00:43

0

看起来好像你有数据,你不想绘制最后一点。那么不要密谋呢?

pl.plot(xvals[:-1], map(f, yvals)[:-1]) 
+0

这只会切断最后一项。 OP是否说过它始终是包含伪造数据的最后一项? – delnan 2011-03-30 17:03:41

+0

@delnan:这就是我所理解的:“这样可以正确绘制数据,当数据结束时,就会陷入悬崖峭壁。”如果它并不总是最后一项,那么你的方法将是合适的 – Claudiu 2011-03-30 17:05:15

2

如果您使用matplotlib,则表示您已安装numpy

由于您正在转换为dB,这听起来像您可能正在记录日志。在这种情况下,np.log(0) = -inf

您可以用numpy函数np.ma.masked_invalidmatplotlib屏蔽nans和infs,并且matplotlib可以绘制遮罩阵列。例如,

import matplotlib.pyplot as plt 
import numpy as np 

xvals=np.arange(100) 
yvals=np.cumsum(np.random.random(100)) 
yvals[-10:]=0 
yvals=np.log(yvals) 

print(yvals[-10:]) 
# [-Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf] 

yvals=np.ma.masked_invalid(yvals) 
plt.plot(xvals,yvals) 
plt.show() 

产生 enter image description here

注意,曲线图与xval等于89结束时,由于yval最后10个值被屏蔽。

+0

在这种情况下,它的log10,但我喜欢这里要去的地方。将调查和更新(除非你或任何其他人击败了我!) – Bolster 2011-03-30 17:10:16

+0

我实际上使用你的答案,但严格来说,我的剥夺其他依赖关系的问题是用StopIteration响应回答的。 – Bolster 2011-03-30 17:25:36

+0

不用担心;很高兴你找到了你的答案。 – unutbu 2011-03-30 18:02:35

1

你不必要地限制自己,拒绝使用循环构造。

在你的情况,你想达到一定值时,对数据停止迭代,这也正是forloops目的和breaks

yvals_ = [] 
for y in yvals: 
    y_ = f(y) 
    if y_ == -140: 
     break 
    else: 
     yvals_.append(y_) 

p1.plot(xvals[:len(yvals_)],yvals_)