I try to determine neighbors in a two-dimensional array using Python 3.7.
The array is like this:
array([[ 1., 2., nan, nan, 5.],
[nan, 2., nan, 5., nan],
[nan, 2., 4., nan, 6.],
[nan, nan, nan, 5., 5.],
[nan, nan, nan, nan, nan],
[ 1., 2., 4., nan, nan],
[ 1., 2., nan, nan, 4.],
[nan, 4., nan, nan, 5.]])
Firstly, the maximum value needs to be determined and the position is (2,4), then I want to get its neighbors with not nan
values. The code is as follows:
test_arr = np.array([[1,2,np.nan,np.nan,5],
[np.nan,2,np.nan,5,np.nan],
[np.nan,2,4,np.nan,6],
[np.nan,np.nan,np.nan,5,5],
[np.nan,np.nan,np.nan,np.nan,np.nan],
[1,2,4,np.nan,np.nan],
[1,2,np.nan,np.nan,5],
[np.nan,4,np.nan,np.nan,6]])
row = test_arr.shape[0]
col = test_arr.shape[1]
temp_amatrix = np.matrix(test_arr)
p = np.argwhere(test_arr == np.nanmax(temp_amatrix)).flatten()[0]
q = np.argwhere(test_arr == np.nanmax(temp_amatrix)).flatten()[1]
def neighbours(test_arr_in,countnotnan_in):
for r in range(len(np.where(countnotnan_in==1)[0])):
x = np.where(countnotnan_in == 1)[0][r]
y = np.where(countnotnan_in == 1)[1][r]
indexlist = [[x-1,y-1],[x-1,y],[x-1,y 1],[x,y-1],[x,y 1],[x 1,y-1],[x 1,y],[x 1,y 1]]
for c in indexlist:
if 0 <= c[0] < row and 0 <= c[1] < col:
if np.isnan(test_arr_in[c[0],c[1]]) == False:
countnotnan_in[c[0],c[1]] = 1
return countnotnan_in
countnotnan = np.zeros_like(test_arr)
countnotnan[p][q] = 1
notnan_arr = neighbours(test_arr,countnotnan)
The result is:
notnan_arr = array([[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 1, 0],
[ 0, 0, 0, 0, 1],
[ 0, 0, 0, 1, 1],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0]])
Yes, it is OK. Actually, I want to use the new '1' values to determine thier neighbors, i.e. determining the neighbors of (1,3), (3,3) and (3,4) positions. Repeat this process until all positions with values starting from the position of (2,4) are identified. The result will be this:
notnan_arr = array([[ 1, 1, 0, 0, 1],
[ 0, 1, 0, 1, 0],
[ 0, 1, 1, 0, 1],
[ 0, 0, 0, 1, 1],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0]])
Next, I want to determine the maximum value of the rest unidentified value to repeat the process until all neighbors' position with values of this two-dimensional array are identified. And the final result should be like this:
notnan_arr = array([[ 1, 1, 0, 0, 1],
[ 0, 1, 0, 1, 0],
[ 0, 1, 1, 0, 1],
[ 0, 0, 0, 1, 1],
[ 0, 0, 0, 0, 0],
[ 1, 1, 1, 0, 0],
[ 1, 1, 0, 0, 1],
[ 0, 1, 0, 0, 1]])
My mother tongue is not English, if anyone has any question about the description. Please tell me, I will try my best to state it. And if anyone can help me, I would be very grateful.
CodePudding user response:
def neighbours(test_arr_in,fstnotnan_in,count_in,countused_in):
for r in range(len(np.where(fstnotnan_in==1)[0])):
x = np.where(count_in == 1)[0][r]
y = np.where(count_in == 1)[1][r]
if np.isnan(countused_in[x][y]) == True:
continue
else:
countused_in[x,y] = np.nan
indexlist = [[x-1,y-1],[x-1,y],[x-1,y 1],[x,y-1],[x,y 1],[x 1,y-1],[x 1,y],[x 1,y 1]]
for c in indexlist:
if 0 <= c[0] < row and 0 <= c[1] < col:
if np.isnan(test_arr_in[c[0],c[1]]) == False:
fstnotnan_in[c[0],c[1]] = 1
count_in = np.where(fstnotnan_in == 1,1.,0)
return fstnotnan_in,count_in,countused_in
test_arr = np.array([[1,2,np.nan,np.nan,5],
[np.nan,2,np.nan,5,np.nan],
[np.nan,2,4,np.nan,6],
[np.nan,np.nan,np.nan,5,5],
[np.nan,np.nan,np.nan,np.nan,np.nan],
[1,2,4,np.nan,np.nan],
[1,2,np.nan,np.nan,5],
[np.nan,4,np.nan,np.nan,6]])
row = test_arr.shape[0]
col = test_arr.shape[1]
temp_amatrix = np.matrix(test_arr)
p = np.argwhere(test_arr == np.nanmax(temp_amatrix)).flatten()[0]
q = np.argwhere(test_arr == np.nanmax(temp_amatrix)).flatten()[1]
countused = np.zeros_like(test_arr)
fstnotnan = np.zeros_like(test_arr)
count = np.full((row,col),np.nan)
fstnotnan[p,q] = 1
count[p,q] = 1
Step by step, the second result was completed.
fstnotnan_out,count_out,countused_out = neighbours(test_arr,fstnotnan,count,countused)
fstnotnan_out1,count_out1,countused_out1 = neighbours(test_arr,fstnotnan_out,count_out,countused_out)
fstnotnan_out2,count_out2,countused_out2 = neighbours(test_arr,fstnotnan_out1,count_out1,countused_out1)
fstnotnan_out3,count_out3,countused_out3 = neighbours(test_arr,fstnotnan_out2,count_out2,countused_out2)
fstnotnan_out4,count_out4,countused_out4 = neighbours(test_arr,fstnotnan_out3,count_out3,countused_out3)
However, this is just an example. My dataset has more than ten thousand rows and cols. So I want to recursively accomplish the goal. And I try the code as below:
def neighbours(test_arr_in,fstnotnan_in,count_in,countused_in):
if (np.where(fstnotnan_in== 1)[0].shape[0] == np.where(np.isnan(countused_in))[0].shape[0]) == True:
return fstnotnan_in,count_in,countused_in
else:
for r in range(len(np.where(fstnotnan_in==1)[0])):
x = np.where(count_in == 1)[0][r]
y = np.where(count_in == 1)[1][r]
if np.isnan(countused_in[x][y]) == True:
continue
else:
countused_in[x,y] = np.nan
indexlist = [[x-1,y-1],[x-1,y],[x-1,y 1],[x,y-1],[x,y 1],[x 1,y-1],[x 1,y],[x 1,y 1]]
for c in indexlist:
if 0 <= c[0] < row and 0 <= c[1] < col:
if np.isnan(test_arr_in[c[0],c[1]]) == False:
fstnotnan_in[c[0],c[1]] = 1
count_in = np.where(fstnotnan_in == 1,1.,0)
return neighbours(test_arr_in,fstnotnan_in,count_in,countused_in)
It's OK. I got it!
CodePudding user response:
I finished it. The code is as follows:
def sechmax(arr_in):
temp_amatrix = np.matrix(arr_in)
r_max = np.argwhere(arr_in == np.nanmax(temp_amatrix)).flatten()[0]
c_max = np.argwhere(arr_in == np.nanmax(temp_amatrix)).flatten()[1]
return r_max,c_max
def neighbours(arr_in,fstnotnan_in,countused_in):
if (np.where(fstnotnan_in == 1)[0].shape[0] == np.where(np.isnan(countused_in))[0].shape[0]):
n_arr_in = np.where(countused_in == 0,arr_in,np.nan)
if np.isnan(n_arr_in).all():
return fstnotnan_in,countused_in
else:
r_max,c_max = sechmax(n_arr_in)
fstnotnan_in[r_max,c_max] = 1
return neighbours(n_arr_in,fstnotnan_in,countused_in)
else:
count = fstnotnan_in.copy()
for r in range(len(np.where(fstnotnan_in==1)[0])):
x = np.where(count == 1)[0][r]
y = np.where(count == 1)[1][r]
if np.isnan(countused_in[x][y]):
continue
else:
countused_in[x,y] = np.nan
indexlist = [[x-1,y-1],[x-1,y],[x-1,y 1],[x,y-1],[x,y 1],[x 1,y-1],[x 1,y],[x 1,y 1]]
for c in indexlist:
if 0 <= c[0] < row and 0 <= c[1] < col:
if np.isnan(arr_in[c[0],c[1]]) == False:
fstnotnan_in[c[0],c[1]] = 1
return neighbours(arr_in,fstnotnan_in,countused_in)
test_arr = np.array([[1,2,np.nan,np.nan,5],
[np.nan,2,np.nan,5,np.nan],
[np.nan,2,4,np.nan,6],
[np.nan,np.nan,np.nan,5,5],
[np.nan,np.nan,np.nan,np.nan,np.nan],
[1,2,4,np.nan,np.nan],
[1,2,np.nan,np.nan,5],
[np.nan,4,np.nan,np.nan,6]])
row = test_arr.shape[0]
col = test_arr.shape[1]
r_max,c_max = sechmax(test_arr)
countused = np.zeros_like(test_arr)
fstnotnan = np.zeros_like(test_arr)
fstnotnan[r_max,c_max] = 1
fstnotnan_out,countused_out = neighbours(test_arr,fstnotnan,countused)