I added one row (for June) to your test DataFrame:
Name State Job Code Month
0 Bob CA A APR
1 Joe CA B APR
2 Mary AZ C MAY
3 Bob CA D MAY
4 Bob NV C MAY
5 Bob CA D MAY
6 Bob CA D JUN
The reason is to show that the way I provided "calendar" sort
on Month (instead of alphabetical) works OK.
To provide the mentioned "calendar" sort, start with:
df.Month = pd.Categorical(df.Month, ['JAN', 'FEB', 'MAR', 'APR',
'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'])
Then, almost all processing can be performed in the following instruction:
res = df.query('Name == "Bob"').drop(columns=['Name'])\
.set_index('Month').stack().reset_index(name='val')\
.groupby(['Month', 'level_1', 'val']).size()\
.sort_index(ascending=[True, False, True]).droplevel(1)
This instruction is quite long (involves multiple steps), so to understand
it run each step separately and see the intermediate results.
I wrote "almost all" before, because for now the MultiIndex has unnecessary
column names. To clear them, run:
res.index.names = ['', '']
And the final result is:
APR CA 1
A 1
MAY CA 2
NV 1
C 1
D 2
JUN CA 1
D 1
dtype: int64
Note that data for JUN is after MAY, just as it should be.