Один из подходов заключается в использовании коллекций. Счетчик :
import pandas as pd
from collections import Counter
data = [[1, 5, 2, 2],
[2, 5, 3, 1],
[3, 3, 2, 1],
[4, 1, 4, 4]]
df = pd.DataFrame(data=data, columns=['A', 'B', 'C', 'D'], index=[1, 4, 5, 8])
total = {k: 0 for k in range(1, 6)}
result = pd.DataFrame([{**total, **Counter(row)} for row in df.values], index=df.index)
result = result.rename(columns={k: f'S_{k}' for k in total}).fillna(0)
print(result)
Выход
S_1 S_2 S_3 S_4 S_5
1 1 2 0 0 1
4 1 1 1 0 1
5 1 1 2 0 0
8 1 0 0 3 0
Использование счетчика для подсчета случаев, выражение:
{**total, **Counter(row)}
создает словарь с 0
счетчиком для пропущенных значений.