0

I have a numpy arrary:

import numpy as np

pval=np.array([[0., 0.,0., 0., 0.,0., 0., 0.],
              [0., 0., 0., 0., 0.,0., 0., 0.]])

And a vectorized function:

def getnpx(age):
    return pval[0]+age
    
vgetnpx = np.frompyfunc(getnpx, 1, 1)

vgetnpx(1)

The output:

array([1., 1., 1., 1., 1., 1., 1., 1.])

However if I want to set a variable for pval:

def getnpx(mt,age):
    return mt[0]+age

vgetnpx = np.frompyfunc(getnpx, 2, 1)

vgetnpx(pval,1)

I received an error:

TypeError: 'float' object is not subscriptable

What is the correct way to set a variable for pval ?Any friend can help?

7
  • You should inspect the value of mt being used in the function. When you pass the ufunc an array, it will call evaluate the function for each value in the array. For what you are doing, it's not clear why you are using frompyfunc rather than just making a regular function (i.e calling getnpx(pval,1)) Commented Oct 7, 2021 at 18:09
  • Thank you for your reply ,because I have very complicated logic on it,such as np.cumprod I have work this for 1 month I have to use frompyfunc Commented Oct 7, 2021 at 18:16
  • If you have to use frompyfunc then you should get to know ufuncs since that what it returns. The first sentence tells you they "operate...in an element-by-element fashion", which means they don't work for what you are trying to do unless you can pass in something that will be broadcast the way you want (like: vgetnpx(pval,[[1], [0]])) where the return value of the main func is just mt+age. Commented Oct 7, 2021 at 18:22
  • what did you expect frompyfunc to do with the pval array? Commented Oct 7, 2021 at 18:26
  • Thank you so much for asking @hpaulj please check this question and you will know stackoverflow.com/questions/68955129/… Commented Oct 7, 2021 at 18:36

1 Answer 1

1

I don't see why you are trying to use frompyfunc. That's for passing array arguments to a function that only takes scalar inputs.

In [97]: pval=np.array([[0., 0.,0., 0., 0.,0., 0., 0.],
    ...:               [0., 0., 0., 0., 0.,0., 0., 0.]])

In the first case you use global pval, and use just 1 age value. No need to frompyfunc:

In [98]: pval[0]+1
Out[98]: array([1., 1., 1., 1., 1., 1., 1., 1.])

And if you want to pass pval as argument, just do:

In [99]: def foo(mt,age):
    ...:     return mt[0]+age
    ...: 
In [100]: foo(pval,1)
Out[100]: array([1., 1., 1., 1., 1., 1., 1., 1.])

You gave a link to an earlier question that I answered. The sticky point in that case was that your function returned an array that could vary in size. I showed how to use it with a list comprehension. I also showed how to tweak vectorize so it would happy returning an object dtype result. Alternatively use frompyfunc to return that object. In all those cases the function argument was a scalar, a single number.

If your goal is to add a different age to each row of pval, just do:

In [102]: pval + np.array([[1],[2]])
Out[102]: 
array([[1., 1., 1., 1., 1., 1., 1., 1.],
       [2., 2., 2., 2., 2., 2., 2., 2.]])
Sign up to request clarification or add additional context in comments.

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.