Подход № 1
Вот один подход -
def find_longest_island_indices(a, values):
b = np.pad(a, ((1,1),(0,0)), 'constant')
shp = np.array(b.shape)[::-1] - [0,1]
maxlens = []
final_out = []
for v in values:
m = b==v
idx = np.flatnonzero((m[:-1] != m[1:]).T)
s0,s1 = idx[::2], idx[1::2]
l = s1-s0
maxidx = l.argmax()
longest_island_flatidx = np.r_[s0[maxidx]:s1[maxidx]]
r,c = np.unravel_index(longest_island_flatidx, shp)
final_out.append(np.c_[c,r])
maxlens.append(l[maxidx])
return maxlens, final_out
Пробный прогон -
In [169]: a
Out[169]:
array([[5, 4, 5, 4],
[2, 3, 5, 5],
[2, 1, 5, 1],
[1, 3, 1, 3]])
In [173]: maxlens
Out[173]: [1, 2, 1, 1, 3]
In [174]: out
Out[174]:
[array([[3, 0]]), array([[1, 0],
[2, 0]]), array([[1, 1]]), array([[0, 1]]), array([[0, 2],
[1, 2],
[2, 2]])]
# With "pretty" printing
In [171]: maxlens, out = find_longest_island_indices(a, [1,2,3,4,5])
...: for l,o,i in zip(maxlens,out,[1,2,3,4,5]):
...: print "For "+str(i)+" : L= "+str(l)+", Idx = "+str(o.tolist())
For 1 : L= 1, Idx = [[3, 0]]
For 2 : L= 2, Idx = [[1, 0], [2, 0]]
For 3 : L= 1, Idx = [[1, 1]]
For 4 : L= 1, Idx = [[0, 1]]
For 5 : L= 3, Idx = [[0, 2], [1, 2], [2, 2]]
Подход № 2
С небольшим изменением и выводом индексов начала и конца для острова максимальной длины, вот один -
def find_longest_island_indices_v2(a, values):
b = np.pad(a.T, ((0,0),(1,1)), 'constant')
shp = b.shape
out = []
for v in values:
m = b==v
idx = np.flatnonzero(m.flat[:-1] != m.flat[1:])
s0,s1 = idx[::2], idx[1::2]
l = s1-s0
maxidx = l.argmax()
start_index = np.unravel_index(s0[maxidx], shp)[::-1]
end_index = np.unravel_index(s1[maxidx]-1, shp)[::-1]
maxlen = l[maxidx]
out.append([v,maxlen, start_index, end_index])
return out
Пример выполнения -
In [251]: a
Out[251]:
array([[5, 4, 5, 4],
[2, 3, 5, 5],
[2, 1, 5, 1],
[1, 3, 1, 3]])
In [252]: out = find_longest_island_indices_v2(a, [1,2,3,4,5])
In [255]: out
Out[255]:
[[1, 1, (3, 0), (3, 0)],
[2, 2, (1, 0), (2, 0)],
[3, 1, (1, 1), (1, 1)],
[4, 1, (0, 1), (0, 1)],
[5, 3, (0, 2), (2, 2)]]
# With some pandas styled printing
In [253]: import pandas as pd
In [254]: pd.DataFrame(out, columns=['Val','MaxLen','StartIdx','EndIdx'])
Out[254]:
Val MaxLen StartIdx EndIdx
0 1 1 (3, 0) (3, 0)
1 2 2 (1, 0) (2, 0)
2 3 1 (1, 1) (1, 1)
3 4 1 (0, 1) (0, 1)
4 5 3 (0, 2) (2, 2)