сжатое
[[n, [*d.B.value_counts().items()]] for n, d in df.groupby('A')]
[['a', [('class1', 2), ('class2', 1)]],
['b', [('class13', 1), ('class12', 1)]]]
Если вы хотите списки вместо кортежей
[[n, [*map(list, d.B.value_counts().items())]] for n, d in df.groupby('A')]
[['a', [['class1', 2], ['class2', 1]]],
['b', [['class13', 1], ['class12', 1]]]]
dict
d = {}
for a, b in df.itertuples(index=False):
d.setdefault(a, {}).setdefault(b, 0)
d[a][b] += 1
[[k, [*map(list, v.items())]] for k, v in d.items()]
[['a', [['class1', 2], ['class2', 1]]],
['b', [['class12', 1], ['class13', 1]]]]