Попробуйте это:
df.T.reset_index()\
.set_axis(range(len(df)+1), axis=1, inplace=False)\
.to_json(orient='records')
Примечание. Проблема заключается в переименовании столбцов после транспонирования. Длина должна быть равна числу строк в исходном кадре данных плюс 1 для индекса.
Выход:
'[{"0":"beef","1":0,"2":4,"3":8,"4":12,"5":16},{"0":"veal","1":1,"2":5,"3":9,"4":13,"5":17},{"0":"pork","1":2,"2":6,"3":10,"4":14,"5":18},{"0":"lamb","1":3,"2":7,"3":11,"4":15,"5":29}]'