I haven't grokked the key concepts in numpy
yet.
I would like to create a 3-dimensional array and populate each cell with the result of a function call - i.e. the function would be called many times with different indices and return different values.
Note: Since writing this question, the documentation has been updated to be clearer.
I could create it with zeros (or empty), and then overwrite every value with a for loop, but it seems cleaner to populate it directly from the function.
fromfunction
sounds perfect. Reading the documentation it sounds like the function gets called once per cell.
But when I actually try it...
from numpy import * def sum_of_indices(x, y, z): # What type are X, Y and Z ? Expect int or duck-type equivalent. # Getting 3 individual arrays print "Value of X is:" print x print "Type of X is:", type(x) return x + y + z a = fromfunction(sum_of_indices, (2, 2, 2))
I expect to get something like:
Value of X is: 0 Type of X is: int Value of X is: 1 Type of X is: int
repeated 4 times.
I get:
Value of X is: [[[ 0. 0.] [ 0. 0.]] [[ 1. 1.] [ 1. 1.]]] [[[ 0. 0.] [ 1. 1.]] [[ 0. 0.] [ 1. 1.]]] [[[ 0. 1.] [ 0. 1.]] [[ 0. 1.] [ 0. 1.]]] Type of X is: <type 'numpy.ndarray'>
The function is only called once, and seems to return the entire array as result.
What is the correct way to populate an array based on multiple calls to a function of the indices?
fromfunction() function construct an array by executing a function over each coordinate and the resulting array, therefore, has a value fn(x, y, z) at coordinate (x, y, z). Parameters : function : [callable] The function is called with N parameters, where N is the rank of shape.
The fromfunction() function is used to construct an array by executing a function over each coordinate. The resulting array therefore has a value fn(x, y, z) at coordinate (x, y, z). Shape of the output array, which also determines the shape of the coordinate arrays passed to function.
The documentation is very misleading in that respect. It's just as you note: instead of performing f(0,0), f(0,1), f(1,0), f(1,1)
, numpy performs
f([[0., 0.], [0., 1.]], [[1., 0.], [1., 1.]])
Using ndarrays rather than the promised integer coordinates is quite frustrating when you try and use something likelambda i: l[i]
, where l
is another array or list (though really, there are probably better ways to do this in numpy).
The numpy vectorize
function fixes this. Where you have
m = fromfunction(f, shape)
Try using
g = vectorize(f) m = fromfunction(g, shape)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With