title: Calculating Variable Cash-flow IRR in Python (pandas)
body: <p>I have a DataFrame of unpredictable cashflows and unpredictable period lengths, and I need to generate a backward-looking IRR.</p>
  
  <p>Doing it in Excel is pretty straightforward using the solver, wondering if there's a good way to pull it off in Python. (I think I could leverage openpyxl to get solver to work in excel from python, but that feels unnecessarily cumbersome).</p>
  
  <p>The problem is pretty straightforward:</p>
  
  <blockquote>
    <p>NPV of Cash Flow = ((cash_flow)/(1+IRR)^years_ago)</p>
  </blockquote>
  
  <p>GOAL: Find IRR where SUM(NPV) = 0</p>
  
  <p>My dataframe looks something like this:</p>
  
  <pre><code>cash_flow    |years_ago
  -----------------------
  -3.60837e+06 |4.09167    
  31462        |4.09167    
  1.05956e+06  |3.63333    
  -1.32718e+06 |3.28056    
  -4.46554e+06 |3.03889    
  </code></pre>
  
  <p>It seems as though other IRR calculators (such as numpy.irr) assume strict period cutoffs (every 3 months, 1 year, etc), which won't work. The other option seems to be the iterative route, where I continually guess, check, and iterate, but that feels like the wrong way to tackle this. Ideally, I'm looking for something that would do this:</p>
  
  <pre><code>irr = calc_irr((cash_flow1,years_ago1),(cash_flow2,years_ago2),etc)
  </code></pre>
  
  <p>EDIT: Here is the code I'm running the problem from. I have a list of transactions, and I've chosen to create temporary tables by id.</p>
  
  <pre><code>for id in df_tran.id.unique():
     temp_df = df_tran[df_tran.id == id] 
  
     cash_flow = temp_df.cash_flows.values
     years = temp_df.years.values
  
     print(id, cash_flow)
     print(years)
  #irr_calc = irr(cfs=cash_flow, yrs=years,x0=0.100000)
  #print(sid, irr_calc)
  </code></pre>
  
  <p>where df_tran (which temp_df is based on) looks like:</p>
  
  <pre><code>    cash_flow       |years     |id
  0   -3.60837e+06     4.09167    978237
  1   31462            4.09167    978237
  4   1.05956e+06      3.63333    978237
  6   -1.32718e+06     3.28056    978237
  8   -4.46554e+06     3.03889    978237
  10  -3.16163e+06     2.81944    978237
  12  -5.07288e+06     2.58889    978237
  14  268833           2.46667    978237
  17  -4.74703e+06     1.79167    978237
  20  -964987          1.40556    978237
  22  -142920          1.12222    978237
  24  163894           0.947222   978237
  26  -2.2064e+06      0.655556   978237
  27  1.23804e+06      0.566667   978237
  29  180655           0.430556   978237
  30  -85297           0.336111   978237
  34  -2.3529e+07      0.758333   1329483
  36  21935            0.636111   1329483
  38  -3.55067e+06     0.366667   1329483
  41  -4e+06           4.14167    1365051
  </code></pre>
  
  <p>temp_df looks identical to df_tran, except it only holds transactions for a single id.</p>