это работа для замаскированных массивов, numpy.ma имеет множество функций для работы с подмножествами.
a = np.zeros((10), dtype=str)
a[2] = 'A'
a[4] = 'X'
a[8] = 'B'
давайте замаскируем непустые элементы:
am=np.ma.masked_where(a!='', a)
np.ma.notmasked_contiguous
проходит через массив (очень эффективно) и находит все фрагменты смежных элементов, где массив не маскируется:
slices = np.ma.notmasked_contiguous(am)
[slice(0, 1, None), slice(3, 3, None), slice(5, 7, None), slice(9, 9, None)]
Итак, массив постоянно пуст, например, между элементами 5 и 7.
Теперь вам нужно только объединить интересующие вас срезы, сначала вы получите начальный индекс каждого среза:
slices_start = np.array([s.start for s in slices])
тогда вы получите местоположение искомого индекса:
slices_start.searchsorted(4) #4
Out: 2
Итак, вы хотите срез 1 и 2:
а [ломтиков [1] .start: ломтики [2] .stop + 1]
массив (['', 'X', '', '', ''],
DTYPE = '| S1')
или давайте попробуем 8:
i = slices_start.searchsorted(8)
a[slices[i-1].start:slices[i].stop+1]
Out: array(['', '', '', 'B', ''],
dtype='|S1')
Если, возможно, стоит немного поиграть с этим в ipython для лучшего понимания.