Pergunta

Estou fazendo algumas pyplotting de dados genéricos e convertê-lo a partir de um valor de energia para um valor de base de dados.Devido ao sistema de estes valores são a partir de, 0 é usado como um 'os dados úteis termina aqui' (indicador da natureza da matemática, não um valor definido).

A minha forma habitual de lidar com essas envolve a conversão em um try/except e retornando um padrão "baixo" valor, por exemplo,

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

Este é fino e elegante, para 90% de utilização dentro do meu quadro, exceto quando se trata de gráficos.

Eu sou preguiçosa então o que eu faço no momento é:

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

Isso atrai os dados corretamente, e quando os dados termina, e precipita-se fora de um penhasco, que é o comportamento esperado.Mas o que eu gostaria de acontecer é para o gráfico, basta fim quando ele encontra uma exceção ValueError e acabar com f() completamente.

Outros que quebrar o mapa em um loop, alguém tem quaisquer idéias brilhantes?

ATUALIZAÇÕES:

Eu estou usando o Pylab / MatplotLib "Ponto final" é a execução dependentes;às vezes, o que não importa atall como não há 'ruim' valores.Isso é tudo em um esforço para eu ser preguiçoso e usar matplotlibs gráfico de escala, em vez de redefinição da dinâmica ylim baseado no min da ydata (que eu não faço atm, apenas ylim(-140), neste caso).

Vagamente Atualização Importante Na Resposta:unutbu, a resposta é que eu vou estar usando para minha implementação, devido a (não mencionado na pergunta dependências), como levantar um StopIteration neste usados regularmente a função de causa estragos alheios-para-o-questão de lógica de controle, sem colocar em todos os outros casos em tentar-excetua;às vezes -inf faz mais sentido do que você imagina.

Obrigado a todos por ser incrivelmente rápido, e eu pedir desculpas para unutbu para o QuestionFail.

Foi útil?

Solução

Talvez haja algum truque na biblioteca de plotagem, mas muito melhores opções parece não gerar tais dados para começar.Não é que map você economiza trinta linhas de código...

Utilização itertools.takewhile(lambda y: y != NO_VALUE, (f(y) for y in yvals)) (e enrole-o em uma chamada para list se o desenho da biblioteca requer uma lista em vez de um iterable).

Editar:Eu tinha uma idéia ainda melhor:Na embalagem, adicione

except ValueError:
    raise StopIteration

Essa é a exceção de sinalização de "fim de iterale", e map respeita-o.

Outras dicas

Se você estiver usando o matplotlib, e , em seguida, isso implica que você tem numpy instalado.

Desde que você está convertendo para dB, parece que você pode estar tendo um registo.Nesse caso, np.log(0) = -inf.

Você pode máscara nans e infs com o numpy função np.ma.masked_invalid, e matplotlib pode enredo mascarado matrizes.Por exemplo,

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

rendimentos enter image description here

Observe que o gráfico termina com xval igual a 89, desde os últimos 10 valores de yval são mascarados.

Você está desnecessariamente a limitar-se ao recusar-se a usar uma construção de loop.

No seu caso você quer parar de iteração através de dados quando um determinado valor é atingido, que é exatamente o propósito de forloops e breaks

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

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

Parece que você tem dados, e você não quer desenhar o último ponto.Por que não plotagem-lo?

pl.plot(xvals[:-1], map(f, yvals)[:-1])
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top