Я бы рекомендовал использовать цифры c для индекса, а не названия месяцев. Таким образом, сводную таблицу будет легче сортировать по индексу.
df = pd.DataFrame(
[
('1/1/2014', 1, -950, -5954, 0, 0, -64430),
('1/1/2015', 1, 0, -5084, 0, 0, -29896),
('2/1/1995', 2, -5160, -1403, 0, 0, -16281),
('2/1/1996', 2, 0, -1573, 0, -14, -30772),
],
columns=['Date', 'Month', 'ID_1', 'ID_2', 'ID_3', 'ID_4', 'ID_5']
)
# Date Month ID_1 ID_2 ID_3 ID_4 ID_5
# 0 1/1/2014 1 -950 -5954 0 0 -64430
# 1 1/1/2015 1 0 -5084 0 0 -29896
# 2 2/1/1995 2 -5160 -1403 0 0 -16281
# 3 2/1/1996 2 0 -1573 0 -14 -30772
Конвертировать данные в длинный формат, используя pd.melt
df = df.melt(id_vars=['Date', 'Month'], var_name='ID')
# Date Month ID value
# 0 1/1/2014 1 ID_1 -950
# 1 1/1/2015 1 ID_1 0
# 2 2/1/1995 2 ID_1 -5160
# 3 2/1/1996 2 ID_1 0
# 4 1/1/2014 1 ID_2 -5954
Удалить все нулевые значения
df = df[df.value != 0]
# Date Month ID value
# 0 1/1/2014 1 ID_1 -950
# 2 2/1/1995 2 ID_1 -5160
# 4 1/1/2014 1 ID_2 -5954
# 5 1/1/2015 1 ID_2 -5084
# 6 2/1/1995 2 ID_2 -1403
Сгруппировать по месяцам и идентификаторам и взять первую строку
df = df.groupby(['Month', 'ID']).first().reset_index()
# Month ID Date value
# 0 1 ID_1 1/1/2014 -950
# 1 1 ID_2 1/1/2014 -5954
# 2 1 ID_5 1/1/2014 -64430
# 3 2 ID_1 2/1/1995 -5160
# 4 2 ID_2 2/1/1995 -1403
# 5 2 ID_4 2/1/1996 -14
# 6 2 ID_5 2/1/1995 -16281
Повернуть таблицу обратно в широкий формат, где каждый столбец представляет собой месяц, используя df.pivot_table
df = df.pivot_table(index='Month', columns='ID', values='value')
# ID ID_1 ID_2 ID_4 ID_5
# Month
# 1 -950.0 -5954.0 NaN -64430.0
# 2 -5160.0 -1403.0 -14.0 -16281.0
Преобразование кадра данных в формат, используя df.to_dict
df.to_dict('list')
# {'ID_1': [-950.0, -5160.0], 'ID_2': [-5954.0, -1403.0], 'ID_4': [nan, -14.0], 'ID_5': [-64430.0, -16281.0]}