IIUC, you can extract the month with to_datetime and dt.month, then compute a pivot_table with a custom function (are both months present for a given combination), then sum to count:
(df.assign(month=pd.to_datetime(df['Date'], format='%Y%m%d').dt.month)
.pivot_table(index='id_1', columns='id_2', values='month',
aggfunc=lambda x: set(x)<={1, 12})
.sum(axis=1).reset_index(name='Nb')
)
Or with a crosstab:
pd.crosstab(df['id_1'], df['id_2'],
values=pd.to_datetime(df['Date'], format='%Y%m%d').dt.month,
aggfunc=lambda x: set(x)<={1, 12}
).sum(axis=1).reset_index(name='Nb')
Output:
id_1 Nb
0 12 2.0
1 18 1.0
Intermediate before the sum:
id_2 1 2 5 7
id_1
12 True True NaN NaN
18 NaN NaN True False
Or using a double groupby:
(df.assign(month=pd.to_datetime(df['Date'], format='%Y%m%d').dt.month)
.groupby(['id_1', 'id_2'])['month'].agg(lambda x: set(x)<={1, 12})
.groupby('id_1').sum().reset_index(name='Nb')
)