ValueError: f (a) и f (b) должны иметь разные знаки - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть датафрейм с колонками Date, cash, rate, name.Когда я пытаюсь сгруппировать по имени, тогда я могу найти значение XIRR, но когда я пытаюсь сгруппировать по скорости, ошибка появляется как

Файл "C: \ ProgramData \ Anaconda3 \ lib \site-packages \ scipy \ optimize \ zeros.py ", строка 519, в brentq r = _zeros._brentq (f, a, b, xtol, rtol, maxiter, args, full_output, disp)

ValueError: f(a) and f(b) must have different signs"
def xnpv(rate, values, dates):    
    if rate <= -1.0:
        return float('inf')
    d0 = dates.min()   # or min(dates)
    return sum([ vi / (1.0 + rate)**((di - d0).days / 365.0) for vi, di in zip(values, dates)])
def xirr(values, dates):  
    try:
        return scipy.optimize.newton(lambda r: xnpv(r, values, dates), 0.0)
    except RuntimeError:    # Failed to converge?
        return scipy.optimize.brentq(lambda r: xnpv(r, values, dates), -1.0, 1e10) 

def f(x):

    x["XNPV"] = xnpv(0.1, x["Cash"], x['Date'])
    x["XIRR"] = xirr( x["Cash"], x['Date'])
    return x

f2 = f1.groupby('RATE').apply(f)

1 Ответ

0 голосов
/ 05 декабря 2018

Сообщение об ошибке довольно ясно.From docs

Возврат с плавающей точкой, ноль f между a и b.f должна быть непрерывной функцией, а [a, b] должна быть интервалом смены знака.

Ситуация происходит из-за того, что brentq работает над модификацией методов поиска корней "пополам", в то время как метод Ньютона делаетне.Учитывая уверенность в том, что существует корень между интервалами (что означает, что знак должен меняться между интервалами), brentq всегда будет сходиться.
Это в отличие от метода Ньютона, который не страдает теми же требованиями, но можетне удается сойтись, так как он работает от первоначального корневого предположения.

Нижняя строка scipy.optimize.brentq(lambda r: xnpv(r, values, dates), -1.0, 1e10) Здесь интервал обрабатывается как [-1.0, 1e10], и функция должна бытьоценивая один и тот же знак для обоих этих значений.Вам нужно будет указать интервал, который имеет разные значения для f(a) и f(b), чтобы гарантировать, что корень находится между ними.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...