1

I have a Python function of two arguments, f(x,y), which returns a scalar. I also have two np.arrays of possible arguments, xs and ys. I'd like to compute a two-dimensional numpy array of shape (xs.size, ys.size) which holds values of f evaluated at all combinations of arguments drawn from xs and ys. The result should be equal to

np.array([[f(x,y) for y in ys] for x in xs])

I would like to achieve this as efficiently as possible and take advantage from multiple processor cores. f does not have any side-effect. I tried to use numpy.vectorize but did not manage to use it to the desired effect. E.g. numpy.outer does exactly what I want for the special case of f=operator.__mul__.

As an additional caveat, though potentially not immediately relevant, one of the array, say ys, does not contain numbers but objects as returned by scipy.interpolate.interp1d. The function f calculates a definite integral via scipy.integrate.quad of these interpolations. The resulting matrix still only contains numbers.

Jonas Greitemann
  • 1,011
  • 10
  • 25
  • may be you can improve the performance a bit by removing the nest loops. For instance calculate the Cartesian product of `xs` and `ys` and then calculate `f` going through each one at a time. Here is a code for Cartesian product (see the accepted answer) which is fast: http://stackoverflow.com/questions/1208118/using-numpy-to-build-an-array-of-all-combinations-of-two-arrays – Dataman Feb 24 '16 at 16:35
  • 3
    It seems the object returned by `scipy.interpolate.interp1d` can't be pickled and that poses problems for using the `multiprocessing` module... –  Feb 24 '16 at 16:57
  • You'll probably get better responses if you change the headline of this question. The question is about multiprocessing, not combinations. – tom10 Feb 24 '16 at 17:35
  • 2
    Depending on what `f` does, you may be much better off modifying it to accept vectors of `x` and `y` values – ali_m Feb 24 '16 at 19:45

1 Answers1

1

Assuming f is a python function, use numpy.frompyfunc() with .outer()

np.frompyfunc(f, 2, 1).outer(xs, ys)
RootTwo
  • 4,288
  • 1
  • 11
  • 15