1

I am trying to optimize a function of two variables. The problem is that my function has a pandas dataframe 'df_main' with 3 columns as param_1, param_2 and returns such that I would like to maximize the output of below defination,

def func(p1, p2):
    return df_main[(df_main['param_1'] >= p1) & (df_main['param_2'] >= p2)]['returns'].add(1).cumprod().iloc[-1]

The definition returns a cumulative product of returns column after applying the filter on columns param_1 and param_2

enter image description here

I was trying something like following,

import scipy.optimize as spo
spo.brute(func, ((0, 1, 0.1), (0, 1, 0.1)), finish=None)

caused,

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-322-4fb6b5111a14> in <module>
----> 1 spo.brute(func, ((0,1,0.1), (0,1,0.1)), finish=None)

e:\Anaconda3\lib\site-packages\scipy\optimize\optimize.py in brute(func, ranges, args, Ns, full_output, finish, disp)
   2829     if (N == 1):
   2830         grid = (grid,)
-> 2831     Jout = vecfunc(*grid)
   2832     Nshape = shape(Jout)
   2833     indx = argmin(Jout.ravel(), axis=-1)

e:\Anaconda3\lib\site-packages\numpy\lib\function_base.py in __call__(self, *args, **kwargs)
   1970             vargs.extend([kwargs[_n] for _n in names])
   1971 
-> 1972         return self._vectorize_call(func=func, args=vargs)
   1973 
   1974     def _get_ufunc_and_otypes(self, func, args):

e:\Anaconda3\lib\site-packages\numpy\lib\function_base.py in _vectorize_call(self, func, args)
   2040             res = func()
   2041         else:
-> 2042             ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
   2043 
   2044             # Convert args to object arrays first

e:\Anaconda3\lib\site-packages\numpy\lib\function_base.py in _get_ufunc_and_otypes(self, func, args)
   2000 
   2001             inputs = [arg.flat[0] for arg in args]
-> 2002             outputs = func(*inputs)
   2003 
   2004             # Performance note: profiling indicates that -- for simple

e:\Anaconda3\lib\site-packages\scipy\optimize\optimize.py in _scalarfunc(*params)
   2823     def _scalarfunc(*params):
   2824         params = asarray(params).flatten()
-> 2825         return func(params, *args)
   2826 
   2827     vecfunc = vectorize(_scalarfunc)

TypeError: func() missing 1 required positional argument: 'p2'

How do I brute force two parameters while applying them as filters on data frame with a cumprod()? An application on numpy array of 3 columns instead of data frame itself should also suffice.

Milind Dalvi
  • 826
  • 2
  • 11
  • 20

1 Answers1

1

scipy.optimize.brute probably supplies the parameters as an array (of the form np.array([p1,p2])) to your function. So if you change your function to accommodate this, does that work? E.g.

def func(p_arr):
    p1, p2 = p_arr
    return df_main[(df_main['param_1'] >= p1) & (df_main['param_2'] >= p2)]['returns'].add(1).cumprod().iloc[-1]
Ewoud
  • 741
  • 4
  • 6