Python;例外認識マップ()
-
14-11-2019 - |
質問
汎用データのピプルティングをやり、それを電力値からDB値に変換しています。システムのために、これらの値はから来て、0は「便利なデータの終了」として使用されます(ここでは、数学の性質、定義された値ではありません)。
私の通常の対処方法は、TRY /以外の変換をラッピングし、デフォルトの「低」値を返します。例えば
.
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を使用しています 「エンドポイント」は実行依存です。 「悪い」値がないので、時には上記はatallではありません。これはすべて怠惰であり、ydataの最分に基づいて動的なYlimをリセットする代わりにMatploTlibsグラフスケーリングを使用することがすべて魅力的で使用されています(この場合はATMをしていません(-140)。)
漠然と答えに重要なアップデート: Unutbuの答えは、この定期的に使用されている関数の停止除去のための停止除去のために、私の実際に実際に使用していることです。試してみた他のインスタンスの。時々 - infはあなたが考えるよりも意味があります。
皆さんが素早く早くてくれておかげで、疑問範囲のUnutbuにお詫び申し上げます。
解決
Perhaps there's some trick in the plotting library, but a much better options seems not generating such data to begin with. It's not that map
saves you thirty lines of code...
Use itertools.takewhile(lambda y: y != NO_VALUE, (f(y) for y in yvals))
(and wrap it in a call to list
if the plotting library requires a list instead of an iterable).
Edit: I had an even better idea: In the wrapper, add
except ValueError:
raise StopIteration
That's the exception signaling "end of iterale", and map
respects it.
他のヒント
If you are using matplotlib
, then it implies you have numpy
installed.
Since you are converting to dB
, it sounds like you might be taking a log. In that case, np.log(0) = -inf
.
You can mask nans and infs with the numpy function np.ma.masked_invalid, and matplotlib
can plot masked arrays. For example,
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()
yields
Notice that the graph ends with xval
equal to 89, since the last 10 values of yval
are masked.
You're needlessly limiting yourself by refusing to use a looping construct.
In your situation you want to stop iterating over data when a certain value is reached, that is exactly the purpose of forloops
and breaks
yvals_ = []
for y in yvals:
y_ = f(y)
if y_ == -140:
break
else:
yvals_.append(y_)
p1.plot(xvals[:len(yvals_)],yvals_)
It seems like you have data, and you don't want to plot the last point. So what about not plotting it?
pl.plot(xvals[:-1], map(f, yvals)[:-1])