Elegant grid search in python/numpy
Question: I have a function that has a bunch of parameters. Rather than setting all of
the parameters manually, I want to perform a grid search. I have a list of
possible values for each parameter. For every possible combination of
parameters, I want to run my function which reports the performance of my
algorithm on those parameters. I want to store the results of this in a many-
dimensional matrix, so that afterwords I can just find the index of the
maximum performance, which would in turn give me the best parameters. Here is
how the code is written now:

    
    
    param1_list = [p11, p12, p13,...]
    param2_list = [p21, p22, p23,...] # not necessarily the same number of values
    ...
    
    results_size = (len(param1_list), len(param2_list),...)
    results = np.zeros(results_size, dtype = np.float)
    
    for param1_idx in range(len(param1_list)):
      for param2_idx in range(len(param2_list)):
        ...
        param1 = param1_list[param1_idx]
        param2 = param2_list[param2_idx]
        ...
        results[param1_idx, param2_idx, ...] = my_func(param1, param2, ...)
    
    max_index = np.argmax(results) # indices of best parameters!
    

I want to keep the first part, where I define the lists as-is, since I want to
easily be able to manipulate the values over which I search.

I also want to end up with the results matrix as is, since I will be
visualizing how changing different parameters affects the performance of the
algorithm.

The bit in the middle, though, is quite repetitive and bulky (especially
because I have lots of parameters, and I might want to add or remove
parameters), and I feel like there should be a more succinct/elegant way to
initialize the results matrix, iterate over all of the indices, and set the
appropriate parameters.

So, is there?


Answer: I think
[`scipy.optimize.brute`](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.brute.html#scipy.optimize.brute)
is what you're after.

    
    
    >>> from scipy.optimize import brute
    >>> a,f,g,j = brute(my_func,[param1_list,param2_list,...],full_output = True)
    

Note that if the `full_output` argument is `True`, the evaluation grid will be
returned.

