Here is an unsupervised approach that takes into account the significant local variance changes, which tend to coincide with the boundaries of intervals.
Core components
signal = df[‘y’].ffill().bfill()
window_size = 300
variance = signal.rolling(window_size).var().valuesvariance_th = 500
jump_indices_raw = np.where(variance > variance_th)[0]