问题
I have a bunch of lines created by connecting some points. I have the number number of lines as a numpy array:
line_no_A= np.arange (17, 31)
sep_A=23
These lines are arranged in two perpendicular direction, shown as blue and red lines. From the sep
, direction of lines changes.
I have also the number of points createing these lines:
point_rep_A=np.array([4, 3, 3, 1])
Now, I want to extract some specific lines. I uploaded a fig and shown the specifics line with blue circles. To find the red lines with circle in scenario_A, I can firstly check the point_rep_A
: first value is 4 and second is 3, makes 1 difference: so, from the first point_rep_A[0] - 1
red lines, keep the first one (line number 24
out of 24
, 25
and 26
). Then, the diff between point_rep_A[1] - point_rep_A[2]
is zero, so from the point_rep_A[1] - 1
red lines, keep none of them. Then, point_rep_A[2] - point_rep_A[3]
equals 2, so keep the first two lines (29
and 30
). For the point_rep_A[4]
, if it is 1, it means ther is only one point and can not make any red line. But, if it is bigger than one, I want to keep all lines out of point_rep_A[4] - 1
red lines.
for specific böue lines, point_rep_A[1] - point_rep_A[2]
is not zero, so I want to keep the first lines of the next follwong chunkcs of blue line. I mean first line of point_rep_A[1] - 1
blue lines (which is 17
out of 17
, 18
and 19
). First line of point_rep_A[2] - 1
blue lines (which is 20
out of 20
, 21
and 22
). And finally First line of point_rep_A[3] - 1
blue lines (which is 23
out of 23
). In fact, I want to start picking these lines just after the first change in point_rep_A
happens. I think my fig can show the idea better. Finally I want to have such result:
[24, 17, 20, 29, 30, 23]
For scenario B, my specific lines are the last ones of each chunk. Here I want all blue lines of each chunk but in previous one I wanted to start picking them after the first change in point_rep_A
. My input for scenario B is:
line_no_B= np.arange (17, 34)
sep_B=25
point_rep_B=np.array([1, 2, 3, 3, 4])
I want to have such result for scenarion B:
[17, 26, 19, 28, 22, 25, 33]
I do appreciate if any one help me to an algorithm for my idea in python. Thanks in Advance.
回答1:
This is the first part:
# SCENARIO A
import numpy as np
from scipy.ndimage.interpolation import shift
# Input data
line_no_A = np.arange(17, 31)
sep_A = 23
point_rep_A = np.array([4, 3, 3, 1])
# RED LINES
# Red candidates
point_rep_red = point_rep_A - 1
red_A = line_no_A[np.where(line_no_A == sep_A)[0][0]+1:]
# Build red array
red_array = np.zeros(shape=(3, 4))
red_lines_index = np.cumsum(point_rep_red)
red_lines_index = np.insert(red_lines_index, 0, 0)
for i in range(len(red_lines_index)-1):
red_array[:,i][:point_rep_red[i]] = red_A[red_lines_index[i]:red_lines_index[i + 1]][::-1]
# Select red lines
shift_rep_A = point_rep_red - shift(point_rep_red, -1, cval=0)
red_specific = [red_array[:, i][:point_rep_red[i]][red_array[:, i][:point_rep_red[i]].size-ind:][::-1] for i, ind in enumerate(shift_rep_A)]
red_specific = np.array(red_specific, dtype=object)
# BLUE LINES
# Blue candidates
blue_A = line_no_A[:np.where(line_no_A == sep_A)[0][0]+1]
# Build blue array
blue_array = np.zeros(shape=(3, 3))
blue_lines_index = np.cumsum(point_rep_A[1:])
blue_lines_index = np.insert(blue_lines_index, 0, 0)
for i in range(len(blue_lines_index)-1):
blue_array[:,i][:point_rep_A[i+1]] = blue_A[blue_lines_index[i]:blue_lines_index[i + 1]][::-1]
# Select blue lines
first_change_index = np.argmax(shift_rep_A > 0) # index of first change in point_rep_A
blue_specific = np.array([blue_array[point_rep_A[i+1]-1, i] for i in range(blue_array.shape[1])])
blue_specific[:first_change_index] = np.nan # skip values before the first change in point_rep_A
blue_specific = np.append(blue_specific, np.nan) # make it the same length as red_specific
blue_specific = np.array(blue_specific, dtype=object)
# Merge red lines and blue lines
result_A = np.hstack(np.ravel(np.column_stack((red_specific, blue_specific))))
result_A = result_A[~np.isnan(result_A)] # remove NaNs
print(result_A)
And the output is:
[24. 17. 20. 29. 30. 23.]
来源:https://stackoverflow.com/questions/65393533/how-to-extract-specific-numbers-based-on-the-conditions-in-python