Я создал простую библиотеку, которая выводит необходимые кодеры для сложных типов продуктов на основе параметров входного типа.
https://github.com/lesbroot/typedudf
import typedudf.TypedUdf
import typedudf.ParamEncoder._
case class Foo(x: Int, y: String)
val fooUdf = TypedUdf((foo: Foo) => foo.x + foo.y.length)
df.withColumn("sum", fooUdf($"foo"))
Вам необходимо сложить отдельные денежные потоки в рамках вашей функции и вернуть их. В данный момент вы возвращаете значение pv первого денежного потока, поскольку у вас есть отчет о возврате в цикле for.
Кроме того, я думаю, что то, как вы проверите свой цикл while по i
, будет означать, что вы пропустите последний платеж. Обычно вам не нужно создавать экземпляры встречных переменных самостоятельно (см. Мои примеры ниже):
def npv(cfList, r):
f = 0
i = 1
pv = cfList[f] / ((1 + r) ** i) # <-- this needs to be in the loop
while i < len(cfList): # <-- i will break loop before last payment is calculated.
f += 1
i += 1
return pv # <-- this return here is the issue
print(npv(cfList, r))
NPV - это сумма PV всех будущих денежных потоков, это то, что вам нужно рассчитать. Например :
def npv(cfList, r):
sum_pv = 0 # <-- variable used to sum result
for i, pmt in enumerate(cfList, start=1): # <-- use of enumerate allows you to do away with the counter variables.
sum_pv += pmt / ((1 + r) ** i) # <-- add pv of one of the cash flows to the sum variable
return sum_pv # <-- only return the sum after your loop has completed.
Всегда помните, что оператор return
в цикле for выйдет из цикла при первом обнаружении return
.
Альтернативной реализацией будет получение отдельных PV от генератора PV и суммирование результатов:
def pv_gen(cfList, r):
for i, pmt in enumerate(cfList, start=1):
yield pmt / ((1 + r) ** i)
print(sum(pv_gen(cfList, r)))
Если вы выполняете итерацию по списку с помощью цикла while, то вы должны иметь действие, выполняющее строку кода внутри цикла while.
Также похоже, что ваш цикл будет обрезаться раньше, когда i = 2 = len (cflist) на второй итерации (не забывайте, что python использует индексирование на основе 0 ) и потому что обратный вызов находится внутри цикла while.
Это должно работать:
def npv(cfList, r):
f = 0
i = 1
pv = 0
while f <= len(cfList):
pv += (cfList[f] / ((1 + r) ** i))
f += 1
i += 1
return pv
Возвращение NPV из списка денежных потоков будет выглядеть так:
def npv(cfList, r):
return sum(f / ((1 + r) ** i) for i, f in enumerate(cfList, 1))
In []:
cfList = [20, 50, 90]
r = 0.05
npv(cfList, r)
Out[]:
142.14447683835436