2

I wonder if you can define a function to act on all elements of a 1-D numpy array simultaneously, so that you don't have to loop over the array. Similar to the way you can, for example, square all elements of an array without looping. An example of what I'm after is to replace this code:

A = np.array([ [1,4,2], [5,1,8], [2,9,5], [3,6,6] ])
B = []

for i in A:
    B.append( i[0] + i[1] - i[2] )

B = array(B)
print B

Output:

>>> array([3, -2, 6, 3])

With something like:

A = np.array([ [1,4,2], [5,1,8], [2,9,5], [3,6,6] ])

def F(Z):
    return Z[0] + Z[1] - Z[2]

print F(A)

So that the output is something like:

>>> array( [ [3] , [-2], [6], [3] ] )

I know the 2nd code won't produce what I'm after, but I'm just trying to give an idea of what I'm talking about. Thanks!

EDIT:

I used the function above just as a simple example. The real function I'd like to use is something like this:

 from numpy import linalg as LA

 def F(Z):
     #Z is an array of matrices
     return LA.eigh(Z)[0]

So I have an array of 3x3 matrices, and I'd like an output array of their eigenvalues. And I'm wondering if it's possible to do this in some numpythonic way, so as not to have to loop over the array.

5
  • Slicing might help : docs.scipy.org/doc/numpy/reference/… Commented Jul 23, 2016 at 20:06
  • 3
    B = A[:, 0] + A[:, 1] - A[:, 2]? (Assuming that you meant i[2] rather than [2].) Or you could use np.dot: you're essentially doing a matrix-by-vector multiplication here. Commented Jul 23, 2016 at 20:11
  • 1
    numpy has already defined a basic set of functions that operate on all the elements of one or more arrays. Efficient numpy code combines these functions. Think of it as have a bunch of 'parallel' building blocks. Try to use those before falling back on 'serial' thinking (looping over a 'scalar' function). Commented Jul 24, 2016 at 3:54
  • @MarkDickinson Slicing works well for this simple function. What if it were something more complicated. Say I had a large array of 3x3 matrices, and I wanted to define a function where I input this large array and the output is an array of the eigenvalues (using something like linalg from numpy). Do you think this would be possible without looping? Commented Jul 24, 2016 at 7:26
  • @cracka31 Regarding your recent questions on avoiding loops/proper-vectorization, it works on a case by case basis. Whether you would be able to vectorize some function, depends on the function implementation itself, as there's no magical thing which would do proper-vectorization on any generic function. So, post your specific function and post how you are using that function, if you can of course. Commented Jul 24, 2016 at 9:26

1 Answer 1

3

Try:

np.apply_along_axis(F, 1, A)
Sign up to request clarification or add additional context in comments.

2 Comments

In this particular case, this is needlessly inefficient, though, since there's a Python-level for-loop involved in the implementation of apply_along_axis. (Well, actually, it's a while loop, but it comes to the same thing.) A simple slicing solution might be better.
Yes that’s true. I just ran some tests and this solution doesn’t work faster than a for loop. It’s definitely a more efficient way to write code, but it doesn’t cut down on computational efficiency which is my goal here. I think slicing may be the way to go. Thanks for responses everyone.

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.