Reputation: 131
I am new to using pandas dataframe, I would appreciate any help. I have a set of dates and cashflows for different loans, loan set with 120 period is followed by another loan set with 120 periods in csv file. in total there are 10 loans with 120 periods and 120 cash flows for each loan. I am trying to apply xnpv function to calculate npv for each loan's cashflows. But Python shows an error
ValueError: too many values to unpack (expected 2).
I can't understand what I am doing wrong.
Here is my code:
import pandas as pd
from scipy import optimize
def secant_method(tol, f, x0):
x1 = x0*1.1
while (abs(x1-x0)/abs(x1) > tol):
x0, x1 = x1, x1-f(x1)*(x1-x0)/(f(x1)-f(x0))
return x1
def xnpv(rate,cashflows):
chron_order = sorted(cashflows, key = lambda x: x[0])
t0 = chron_order[0][0]
return sum([cf/(1+rate)**((t-t0).days/365.0) for (t,cf) in chron_order])
s=pd.Series(list(zip(df['date'], df['Total CF'])), index =df.index)
df1=s.groupby(df['loan_number']).apply(list).reset_index(name='cashflows')
cashflows=df1['cashflows']
cashflows
0 [(7/15/2021, 0.152497472), (8/15/2021, 0.23157...
1 [(7/15/2021, -1.731640118), (8/15/2021, -1.272...
2 [(7/15/2021, 0.016080295), (8/15/2021, 0.02423...
3 [(7/15/2021, 0.0), (8/15/2021, 0.0), (9/15/202...
4 [(7/15/2021, -3.481797138), (8/15/2021, -2.792...
5 [(7/15/2021, 0.033370756), (8/15/2021, 0.04979...
6 [(7/15/2021, -2.439990626), (8/15/2021, -2.090...
7 [(7/15/2021, -2.661802291), (8/15/2021, -2.280...
8 [(7/15/2021, 0.0), (8/15/2021, 0.0), (9/15/202...
9 [(7/15/2021, 0.0), (8/15/2021, 0.0), (9/15/202...
10 [(7/15/2021, -1.555758792), (8/15/2021, -1.321...
Name: cashflows, dtype: object
xnpv(0.03, cashflows)
ValueError Traceback (most recent call last)
<ipython-input-81-e191dc20193f> in <module>
----> 1 xnpv(0.03, cashflows)
<ipython-input-35-8666e85828f1> in xnpv(rate, cashflows)
23 chron_order = sorted(cashflows, key = lambda x: x[0])
24 t0 = chron_order[0][0] #t0 is the date of the first cash flow
---> 25 return sum([cf/(1+rate)**((t-t0).days/365.0) for (t,cf) in
chron_order])
26
27 def xirr(cashflows,guess=0.1):
<ipython-input-35-8666e85828f1> in <listcomp>(.0)
23 chron_order = sorted(cashflows, key = lambda x: x[0])
24 t0 = chron_order[0][0] #t0 is the date of the first cash flow
---> 25 return sum([cf/(1+rate)**((t-t0).days/365.0) for (t,cf) in
chron_order])
26
27 def xirr(cashflows,guess=0.1):
ValueError: too many values to unpack (expected 2)
Upvotes: 1
Views: 141
Reputation: 3927
As suggested in one of the comments, the error points at the line containing the sum:
return sum([cf/(1+rate)**((t-t0).days/365.0) for (t,cf) in chron_order])
In that line, you are iterating chron_order
in a way that every element of chron_order
is expected to contain a data structure that can be unpacked into two variables: for (t,cf) in chron_order
.
In other words, for this to work, each element in chron_order
must be a list
, a tuple
(or something else that Python can automatically unpack) and each of these must contain exactly two items.
Looking at the output that you posted, it seems that cashflows
is a column, where each row in that column is a list of 2-tuples and (at least in some cases) there are more than two of those 2-tuples in a row.
That means, if you iterate chron_order
(which is derived from cashflows
) the way you are trying to do it now, you are actually iterating a list of lists of 2-tuples which is the reason why the interpreter is complaining.
As to the solution what you need to do in order for this to work is change xnpv()
to something like this (as I can only guess what the code is supposed to be doing):
def xnpv(rate, cashflows):
# chron_orders (plural) is a list of lists of 2-tuples
chron_orders = sorted(cashflows, key=lambda x: x[0])lists
sums = []
for chron_order in chron_orders:
# chron_oder (singular) is a list of 2-tuples now
t0 = chron_order[0][0]
sums.append(sum([cf/(1+rate)**((t-t0).days/365.0) for (t,cf) in chron_order])
return sum(sums) # Just guessing here
Upvotes: 1