1

I'm trying to re-write some code that looks like it was written by a FORTRAN programmer to make it more Pythonic/readable. Below is the code snippet of interest. The overall behavior of the code is to store the first three elements of Z into Zstart so long as the values are less than 1, and also store the last three values of Z into Zend as long as they are less than 1 as well.

import numpy as np
nbpoints = 3
Z = np.linspace(0,1.0,10)
Zstart = np.ones(nbpoints)
Zend = np.ones(nbpoints)
Zpts = np.size(Z)
for j in range(nbpoints):
    if Z[j] < Zstart[j]:
       Zstart[j] = Z[j]
    if Z[Zpts - 1 - j] < Zend[nbpoints - 1 - j]:
        Zend[nbpoints - 1 - j] = Z[Zpts - 1 - j]

The counter moving access of Zstart and Zend from both ends is tripping me up a bit. My current solution is the following.

import numpy as np
nbpoints = 3
Z = np.linspace(0,1.0,10)
Zstart = np.ones(nbpoints)
Zend = np.ones(nbpoints)
Zpts = np.size(Z)
for j in range(nbpoints):
    if Z[j] < Zstart[j]:
       Zstart[j] = Z[j]
    if Z[-(j+1)] < Zend[-(j+1)]:
        Zend[-(j+1)] = Z[-(j+1)]

Sample output from this code is:

Z = [ 0.0 0.11111111  0.22222222  0.33333333  0.44444444  0.55555556 
0.66666667  0.77777778  0.88888889  1.0 ]

Zstart = [ 0.0 0.11111111  0.22222222]
Zend = [ 0.77777778  0.88888889  1.0 ]

My solution feels like I'm still just re-writing poorly written code e.g. rearranging chairs on the deck of the Titanic. Is there a more Pythonic way to perform this operation?

6
  • can you give an example of input and desired output? Commented Oct 12, 2017 at 15:31
  • @JulienSpronck I added sample output. The input is just the Z array. A one-dimensional numpy array that varies from 0 to 1. In the actual code it is passed in, but for the purposes of this snippet I just used the numpy linspace function to emulate input data. Commented Oct 12, 2017 at 15:46
  • @wandadars What happens if the starting values are > 1? Do you store only those that are <1, or none at all? Commented Oct 12, 2017 at 16:09
  • @BradSolomon In the context of the code that this snippet comes from, the values of Z are bound between 0 and 1. As for the initial values of Zstart and Zend, only the original author knows why they did that. Commented Oct 12, 2017 at 16:12
  • What? If the values in Z are guaranteed to be 0 < value < 1, then why are you testing that they are <1 in the first place? Commented Oct 12, 2017 at 16:14

2 Answers 2

1

You don't need to instantiate Zstart and Zend with np.ones. Just build them directly:

nbpoints = 3
Z = np.linspace(0,1.0,10)
Zstart = Z[:nbpoints][Z[:nbpoints] < 1]
Zend = Z[-nbpoints:][Z[-nbpoints:] < 1]

print(Zstart)
print(Zend)
# [ 0.          0.11111111  0.22222222]    
# [ 0.77777778  0.88888889]

Notice that Zend has only 2 elements here, because the final element in Z is not less than 1.

Sign up to request clarification or add additional context in comments.

Comments

1

This code gives the same results without a moving counter

nbpoints = 3
Z=np.linspace(0,1.,10.)               
Zstart = np.ones(nbpoints)            
Zend = np.ones(nbpoints)              

Zstart[Z[:nbpoints] < 1] = Z[:nbpoints][Z[:nbpoints] < 1]  
Zend[Z[-nbpoints:] < 1] = Z[-nbpoints:][Z[-nbpoints:] < 1] 

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.