Вы можете использовать duplicated
с подмножеством идентификатора, имени и года, а затем инвертировать результат для определения первого вхождения ..., например:
df['status'] = (~df.duplicated(subset=['id', 'name', 'year'])).astype(int)
Дает вам:
id name year quater value status
0 1 bn 2017 2 NaN 1
1 2 an 2018 1 2.3 1
2 2 an 2018 2 3.3 0
3 2 an 2018 3 4.5 0
Обратите внимание, что, хотя это будет работать с вашими данными, упорядоченными в том виде, в котором они представлены, вы можете отсортировать их по годам (и, возможно, кварталу), чтобы убедиться, что ваши флаги состояния перемещаются в течение того же года и в первый квартал, видимый соответствующим образом.