Вариант 1: Чтобы получить только первые индексы:
df[df.Amount.notna()].groupby('Id').Date.idxmin()
# 1.42 ms ± 14.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
вывод:
Id
1 2
2 7
Name: Date, dtype: int64
Вариант 2: , чтобы получитьдругие строки, используйте cumsum
на notna()
df[df['Amount'].notna().groupby(df['Id']).cumsum().gt(0)]
# 2.09 ms ± 220 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Вариант 3: вы можете ffill()
в группе и выбрать те, которые не заполнены:
df[df.groupby('Id').Amount.ffill().notna()]
# 831 µs ± 14.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Вывод:
Date Id Amount
2 201303 1 100.0
3 201304 1 120.0
4 201305 1 NaN
5 201306 1 120.0
7 201303 2 150.0
8 201304 2 180.0
Вывод : вариант 3 самый быстрый!
Обновление: для фильтрации обоих концов с использованиемВариант 3:
amt_group = df.groupby('Id').Amount
df[amt_group.bfill().notna() & amt_group.ffill().notna()]