0

I have an numpy array of functions and I'd like to apply to an array of floats using numpy's brodcasting rules. Aside from using a for loop, is there any standard way of achive this?

funcs = np.array([f1, f2, f3]) # each f is of type f(x: float) -> float
data = np.array([[1,2,3],
                 [4,5,6]])

# Expected result
np.array([[f1(1),f2(2),f3(3)],
          [f1(4),f2(5),f3(6)]])

Edit

Below there is a better example of the expected behaviour. It is important to be able to broadcast, as like summing two arrays:

>>> np.array([0,1]) + 1
np.array([0+1, 1+1])

>>> np.array([0,1]) + np.array([1,2])
np.array([0+1, 1+2])

>>> np.array([0,1]) + np.array([[1,2], [3,4]])
np.array([[0+1, 1+2], [0+3, 1+4]])

## Expected behaviour (Imagine % means function application operator)
>>> np.array([0,1]) % f
np.array([f(0), f(1)])

>>> np.array([0,1]) % np.array([f1,f2])
np.array([f1(0), f2(1)])

>>> np.array([0,1]) % np.array([[f1,f2], [f3,f4]])
np.array([[f1(0), f2(1)], [f3(0), f4(1)]])
3
  • Tried a list comprehension yet? Commented Feb 28, 2020 at 9:31
  • Can the functions accept NumPy arrays? Commented Feb 28, 2020 at 9:37
  • @NilsWerner Yes. Those functions can accept the whole axis for example Commented Feb 28, 2020 at 9:39

3 Answers 3

1

Use frompyfunc

f = np.frompyfunc(lambda fx,arg: fx(arg), 2, 1)
res = f(fns, arg)

Result should be object dtype, with full broadcasting.

In [416]: f = np.frompyfunc(lambda fn,x:fn(x),2,1)                                             
In [420]: f1=lambda x:x+1 
     ...: f2=lambda x: x*3                                                                     
In [421]: f([[f1],[f2]], np.arange(4))                                                         
Out[421]: 
array([[1, 2, 3, 4],
       [0, 3, 6, 9]], dtype=object)
Sign up to request clarification or add additional context in comments.

Comments

0

Using a comprehension you could go for:

import numpy as np

def f1(input):
    return input + 1

def f2(input):
    return input + 2

def f3(input):
    return input + 3

funcs = np.array([f1, f2, f3])
data = np.array([[1,2,3],
                 [4,5,6]])

result = np.array(
    [[fun(item) for fun, item in zip(funcs, lst)]
    for lst in data])

print(result)

Which yields

[[2 4 6]
 [5 7 9]]

1 Comment

I've tried this, but it doesn't broadcast. Let me edit the question so it is a little more clear
0

If the functions can accept a numpy array, I would use 2 transpositions:

resul = np.transpose(np.array([f[i](x[i]) for i, x in enumerate(np.transpose(data)]))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.