Решение
Вот более прискорбный подход, чем тот, который предлагается пользователем 3448203. Это позволяет избежать ненужных итераций, быстрее (для достаточно больших наборов данных) и более идиоматично.
m = {'A':[1,2,3,4,5,6,7],
'B':[12,13,14,15,16,17,18]}
p = {'A':[8,9,10,11,12,13,14],
'B':[18,19,20,21,22,23,24]}
p_df = pd.DataFrame(p).melt(value_name='value')
m_df = pd.DataFrame(m).melt(value_name='value')
p_df['category'] = 'P'
m_df['category'] = 'M'
result = pd.concat([m_df, p_df], ignore_index=True)
Тесты (для больших наборов данных):
m = {'A': list(range(0, 100_000)), 'B': list(range(100_000, 200_000))}
p = {'A': list(range(200_000, 300_000)), 'B': list(range(300_000, 400_000))}
Вот и мы:
%%timeit
p_df = pd.DataFrame(p).melt(value_name='value')
m_df = pd.DataFrame(m).melt(value_name='value')
p_df['category'] = 'P'
m_df['category'] = 'M'
result = pd.concat([m_df, p_df], ignore_index=True)
120 мс ± 3,16 мс на цикл (среднее ± стандартное отклонение из 7 циклов, по 10 циклов в каждом)
%%timeit
categories = ['M', 'P']
dcts = [m, p]
dfs = [
pd.DataFrame([[k, el, cat] for k, v in dct.items() for el in v])
for dct, cat in zip(dcts, categories)
]
cols = {'columns': {0: 'Name', 1: 'Value', 2: 'Category'}}
result = pd.concat(dfs).reset_index(drop=True).rename(**cols)
207 мс ± 8,9 мс на цикл (среднее ± стандартное отклонение из 7 циклов, по 1 циклу каждый)