0

Let's assume I have this array:

prova = np.array([[[0, 8],
    [8, 8],
    [7, 7]],

   [[6, 5],
    [6, 6],
    [0, 3]],

   [[0, 1],
    [5, 6],
    [0, 2]],

   [[6, 2],
    [2, 8],
    [4, 4]]])

Let's also assume I have a random function that take in input 2 numpy array (not important of what the function does, it is just a random example) and always returns a scalar (int in this case):

def random_function(a1, a2):
    a1 = a1[np.argsort(a1)]
    a2 = a2[np.argsort(a2)]
    if a1[0]>a2[0]:
        print("1")
        return np.diff(a2-a1).max()
    elif a2[0]>a1[0]:
        print("2")
        return np.diff(a2-a1).min()
    else:
        print("3")
        return (np.cumsum(a1)+np.cumsum(a2))[-1]

What I want to do is to apply this function on the first axis of prova in this way:

np.array([random_function(*p.T) for p in prova])

out:

array([-6, -4, -1, 26])

How can I obtain the same result without using a for loop? Can I use np.apply_along_axis or np.apply_over_axes to achieve this goal?

Thank you in advance.

  • 1
    Does this help [Easy parallelization of numpy.apply_along_axis()?](https://stackoverflow.com/questions/45526700/easy-parallelization-of-numpy-apply-along-axis)? – Michael Szczesny Jun 16 '22 at 09:31
  • I already know how to apply functions in parallel with `multiprocessing`, `joblib` and `numba`. I would like to solve the task using only `numpy` – Salvatore Daniele Bianco Jun 16 '22 at 09:41
  • 1
    OK, I see. Multiprocessing a custom python function even without the standard module `multiprocessing` ('external' is typically used for a library that needs to be installed, like `numpy`). The referenced question should give you a hint whether this is possible with `numpy` functions. – Michael Szczesny Jun 16 '22 at 09:50
  • Yes you are right. I'll edit the title of my question replacing "external libraries" with "other libraries". Anyway thanks for the referenced question, it is very useful and I think that i will use that strategy in case there are no other ways. – Salvatore Daniele Bianco Jun 16 '22 at 10:02
  • `apply_along_axis` is slower than an equivalent explicit iteration, and as should be clear from the docs, only takes ONE array, and a function that expects as 1d array. IF given a 3d array, it iterates over 2 of the axes, and passing the third to the function, one at a time. `apply_over_axes` is an entirely different operation - with the word `apply` being the only thing in common. – hpaulj Jun 16 '22 at 15:42
  • Ideally you want to write `random_function` so it works with `random_function(prova[:,:,0],prova[:,:,1])`. But expressions like `if a1[0]>a2[0]:` only work with scalar values. So the inputs arrays have to be 1d, not 2d. – hpaulj Jun 16 '22 at 15:52

0 Answers0