Следующий код производит ожидаемый результат точно, но не является производительным;он будет сильно тормозить с увеличением размера входных данных (из-за понимания списка).
# Assume all repeated API values are contiguous;
# if not, first sort df by API
grouped = (df.groupby('API', sort=False)['Index']
.agg(['first', 'last'])
.itertuples(index=False, name=None))
pd.Series([x if x[0] != x[1] else x[0] for x in grouped],
index=df.API.unique(), name='Index_RANGE')
5 (0, 2)
10 3
12 4
1 (5, 6)
100 7
23 (8, 9)
Name: Index_RANGE, dtype: object