0

I have a serie of lines and want to extract some of them. This is the number of lines:

line_no= np.arange (17, 34)

These lines are arranged in two perependicular direction. I have shown them with bluw and red lines in the fig. I know where the direction is changing, it is called sep:

sep=25 # lines from 17 to 25 are blue and from 26 to end are red

Then, I have the number of the points that create the lines. I call them chunks, because each number can be chunk:

chunk_val=np.array([1,2,3,3,4])

This chunk_val says how lines are created. I need to extract specific line numbers which are highlighted by a blue circle in the fig. For the red lines the algorithm is simpler. chunk_val[0] is 1, it means I have no red line there. chunk_val[1] is 2, so I have one line and I want that line (26) because the previous chunk gave me no line. chunk_val[2] is 3, so I have two lines here and I want the one last line (28 out of 27 and 28), because previous chunk gave me one line. chunk_val[3] is 3, there are again two line but I want none of them because the number of created red lines in this chunk is equal to previous chunk. chunk_val[3] is 4, it creates three line and I want to export the number of last one (33 out of 31, 32 and 33) because it is creating one line more than previous chunk. If chunk_val[3] was 5, then I wanted to save the last two line.

For blue lines, that connect the chunks it is a little bit more complicated. chunk_val[0] is 1and chunk_val[1] is 2, it means there is one connecting line because first chunk_value defines how many lines can be there. Meanwhile, I want that line (17), because there is only one line. If there were more lines, I wanted to pick the last one. From chunk_val[1] to chunk_val[2] I have two lines and I want the last one (19 out of 18 and 19). Then, chunk_val[2] to chunk_val[3] there are three line and I want the last one (22 out of 20, 21 and 22). From chunk_value[3] to chunk_value[4] again there are three line and I want the last one (25 out of 23, 24 and 25). There is one very important note on how to pick these connecting (blue) lines: I want to start picking them from the first chunk_val untill where values of chunk_val change. In my example until the last number of chunk_val I see a change (chunk_val[-2] is 3 while chunk_val[-1] is 4). If chunk_val[-1] was also 3, then I wanted to stop picking the blue lines after going from chunk_val[1] to chunk_val[2] (I mean I only wanted to have 17 and 19). These are the idea of my algorithm but I have no idea to code it in python. In summary I want to have the following list of numbers:

[17, 26, 19, 28, 22, 25, 33]

In advance, I do appreciate any contribution.

enter image description here

6
  • 1
    kudos for the verbose explanation! Commented Dec 30, 2020 at 16:00
  • Dear @anurag, I really do not know how to code my idea. That's why I explained. I thought mybe an unrelated code from my side mislead the reader. Commented Dec 30, 2020 at 16:04
  • 1
    I am not complaining, it is just that verbosity is dis-orienting, may be the steps in pictorial form would be more helpful! Commented Dec 30, 2020 at 16:07
  • Dear @anurag, I do appreciate your hint. I tried to visualize it on the fig but it is not completely possible. Meanwhile thanks again for our feedback. Commented Dec 30, 2020 at 16:11
  • 1
    Hello Ali, I see that you still have some more problems in the same context as before. I suggest coming up with an appropriate data-structure to represent the cell details like the numbers and it's neighbours (preserving the geometrical ordering) will help you solve many problems/requirements as you progress further with your task. Otherwise, you will be just tackling every task from scratch. Commented Dec 30, 2020 at 16:52

2 Answers 2

1

Upon reflection, there is a simpler solution to this problem (which can also be easily adapted for its twin problem):

import numpy as np
from scipy.ndimage.interpolation import shift

# Input data
line_no = np.arange (17, 34)
sep = 25  # lines from 17 to 25 are blue and from 26 to end are red
chunk_val = np.array([1,2,3,3,4])

# Blue candidates
blue_A = line_no[:np.where(line_no == sep)[0][0]+1]

# Red candidates
red_A = line_no[np.where(line_no == sep)[0][0]+1:]

# Select blue lines
blue_index = (chunk_val[:-1]).cumsum() - 1
blues = blue_A[blue_index]
blue_shift = (chunk_val[-1] - chunk_val)[:-1]
blues[blue_shift == 0] = 0  # set value of zero if no further jagged lines

# Select red lines
red_index = (chunk_val[1:] - 1).cumsum() - 1
reds = red_A[red_index]
red_shift = (chunk_val - shift(chunk_val, 1, cval=0))[1:]  # increments between successive series of red lines
reds[red_shift == 0] = 0  # set value of zero if no increment

# Merge blue lines and red lines
result = np.ravel(np.column_stack((blues, reds)))
result = result[result != 0]  # remove zeros
print(result)

Output:

[17 26 19 28 22 25 33]
Sign up to request clarification or add additional context in comments.

7 Comments

Dear @David M, I do appreciate your help. If I change the input, I cannot see the result I want. I remove the last red line (line_no = np.arange (17, 33) and chunk_val = np.array([1,2,3,3,3])). Then, I want to only have the lines numbered 17, 26, 19 and 28. In fact, I have jagged surfaces and want to extract the lines the are in adjacency of the jagged area. If I remove the last line, the last two column are not jagged anymore and I do not need any line from there. Thanks again for being that much supportive.
I have modified the code; it will now work when there are no further jagged lines. For clarity, I have also removed the previous solution.
Dear @David M., thanks for being that much supportive. Is there anyway to solve both the problems with one solution? You previously solved the first problem for me. I do appreciate it. The fact is that I want to export the lines in the adjacency of the jagged area. In all cases the regular grid is cut by a line That removes some points and makes my surfaces jagged. If I had not the cutting line, all points were distributed in a regular grid and I had some regular surfaces.
What do you mean by "export the lines in the adjacency of the jagged area"?
I second @sai’s comment: it would be better to find a way to describe the general problem you are trying to solve, otherwise you will have to endlessly modify partial solutions. Such a description would have to address the following questions: what problem am I trying to solve (in the general case, not a particular case)? What is the general form of the input? What is the expected output?
|
1

I agree with @sai's comment that this is probably best handled with some classes that represent the problem. Possibly a structure that represents the blue line to the right of the point and the red line up from the point. As I don't understand the problem I'm not sure what's best.

The code below works for the specific example in the question. I don't know whether it genuinely solves the question for different control lists or how to test it. Delete or comment out the two print statements when not required.

def specific_values( control, start = 0 ):
    cumulative = start
    blues = []  # List of lists of blues
    reds = []   # List of list of reds
    for i in control[ :-1 ]:  # The last item in control doesn't generate blues.
        temp=[]
        for j in range( cumulative, cumulative + i ):
            temp.append( j )
        blues.append(temp)
        cumulative += i
    print( blues )
    for ix, i in enumerate( control[ 1: ] ):  
        # The first item in the control doesn't generate reds.
        # The index is used to check whether the length of the red is less than 
        # the corresponding blue
        temp = [] 
        for j in range( cumulative, cumulative+i-1 ): 
            temp.append( j )
        while len(temp) < len( blues[ix] ):  
             temp.append( None )   # Pad the red with None to match the corresponding blue. 
        reds.append(temp) 
        cumulative += i-1
    print( reds )
    res = [] 
    for b_arr, r_arr in zip( blues, reds ): 
        res.append( b_arr[ -1 ] ) # Append last item in blues sub array to result
        res.append( r_arr[ -1 ] ) # Append last item in reds sub array to result
    return [ x for x in res if not x is None ]    # Filter out any Nones

control = [ 1, 2, 3, 3, 4 ]
specific_values( control, 17 )

There may be better ways to solve this but this represents the pattern I can see. What happens if a later control point is less than it's predecessor or if a control point is zero?

2 Comments

Dear @Tls Chris, Thanks for being that much helpful. I do appreciate it. I am dealig with a geometrical issue. I have some points from a regular grid. Points are creating sume lines and some lines are creating surfaces, exactly like my fig. Now, I want to extract line numbers that are not involver in creating surfaces (like 17 and 33) and also lines from specific parts of the surfaces. When I try your method for control = [1, 2, 3, 3, 3] and again 17 as start, it gives me the wrong answer: [17, 26, 19, 28, 22, 25].
Just Imagine that in my fig I do not have the last red line, then I only need to extract 17, 26, 19 and 28. In fact, I have a regular grid, then the grid is cut by a surface. Thats why you see a jagged pattern of surfaces. I want to extract the lines that are in adjacency of the jagged area. If I remove the last red line, then the last two chunks are not jagged any more.

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.