0

I have a vector A and I want to find all the "i" values of the array which are bigger than the neighboring values, i.e. right before (i-1) and right after (i+1). I wrote a simple code (surely with mistakes) that should print the array (y_maxtab) containing the "i" values. I try to run and It gets stacked. Could you help me on that?

import numpy as np

y_maxtab = []


A=np.array([2.0,2.5,1.7,5,7,8,9,3,5,3,7,8])

i=1

while i <= len(A):
   if A[i] > A[i-1] and a[i] > A[i+1]:
         y_maxtab.append(A[i])
         i=i+1
print y_maxtab

2 Answers 2

1

Well, your code as is has some problems.

  1. If the first if statement fails, you will never increment i, and will be stuck in an infinite loop.
  2. The second clause of the if statement has an undefined reference (a).
  3. The while statement will allow values of i which will cause IndexErrors with A[i] and A[i+1].

If you are committed to keeping the code in the same form, you could change it so that it looks like

i = 1
while i < len(A)-1:
    if A[i] > A[i-1] and a[i] > A[i+1]:
        y_maxtab.append(A[i])
    i=i+1
print y_maxtab
# [2.5, 9.0, 5.0]

However, a more pythonic way would be something like

for first, middle, last in zip(A[:], A[1:], A[2:]):
    if first < middle > last:
        y_maxtab.append(middle)
print y_maxtab
# [2.5, 9.0, 5.0]
Sign up to request clarification or add additional context in comments.

5 Comments

+1 for pointing out and fixing the errors. But the indexing in the zip() is a bit inconsistent.
Since zip stops once the shortest iterable is exhausted, I wasn't careful. To me, it makes the most sense as I've edited it, although the way it's written in @Eelco's answer may be preferable to some.
I agree, this behavior of zip is well known and it looks nicer
Perhaps the downvote is due to not utilizing the power of numpy, but it doesn't seem that OP grasps when one should use numpy.array over list.
My corrected code works fine and also the more pythonic version, thanks a lot!!
1

Here is a solution that uses numpy directly. Far faster and cleaner than a python loop, and moreover, it does what you intend it to.

local_maximum = (A[:-2]<A[1:-1]) & (A[2:]<A[1:-1])
print A[1:-1][local_maximum]

Or slightly more verbose, but perhaps more readable:

left, mid, right = A[:-2], A[1:-1], A[2:]
local_maximum = (left<mid) & (right<mid)
print mid[local_maximum]

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.