Пропадает возможность делать слайс по периоду после объединения двух DataFrame Pandas

Имею два DataFrame (res, descr) со следующим набором колонок:

MultiIndex([(          'bucket', '2020-01'),
            (          'bucket', '2020-02'),])

Момент, на который здесь необходимо обратить внимание, это тип данных второго элемента MultiIndex, а именно pandas._libs.tslibs.period.Period:

type(descr.columns[0][1]) # pandas._libs.tslibs.period.Period
type(res.columns[0][1])   # pandas._libs.tslibs.period.Period

В нужный момент объединяю массивы:

total_df = res.merge(descr, how='left', left_on='calculationID', right_on='calculationID', suffixes=('_res', '_descr'), sort=True)

Полученный сводный массив имеет такой набор колонок:

MultiIndex([(                'bucket', 2020-01),
            (                'bucket', 2020-02),])

То есть, визуально, второй элемент MultiIndex уже не заключен в кавычки. При этом, тип этого элемента по-прежнему pandas._libs.tslibs.period.Period:

type(total_df.columns[0][1]) # pandas._libs.tslibs.period.Period

Проблема заключается в том, что в объединенном DataFrame пропадает возможность делать слайс по периоду во втором элементе.

До объединения датафреймов следующая конструкция позволяет отфильтровать только нужные месяцы:

descr.head(1).loc[:, idx[:, idx['2020-01': '2020-02']]]

Результат:

              confiscation_cost    days_for_confiscation
period        2020-01   2020-02    2020-01   2020-02
calculationID
ID 1          10        20         1         2

Если же пытаюсь тем же способом отобрать в объединенном DataFrame столбцы, ловлю ошибку KeyError: '2020-01':

In: total_df.head(1).loc[:, idx[:, idx['2020-01': '2020-02']]]
Out: ...KeyError: '2020-01'

UPD1 код для генерации тестовых массивов:

res = {
    ('bucket', pd.Period('2020-01', 'M')): {'ID1': '1.0', 'ID2': '1.0', 'ID3': '1.0', 'ID4': '1.0', 'ID5': '1.0'},
    ('bucket', pd.Period('2020-02', 'M')): {'ID1': '1.0', 'ID2': '1.0', 'ID3': '1.0', 'ID4': '1.0', 'ID5': '1.0'},
    ('bucket', pd.Period('2020-03', 'M')): {'ID1': '1.0', 'ID2': '1.0', 'ID3': '1.0', 'ID4': '1.0', 'ID5': '1.0'},
    ('bucket', pd.Period('2020-04', 'M')): {'ID1': '1.0', 'ID2': '1.0', 'ID3': '1.0', 'ID4': '1.0', 'ID5': '1.0'},
      }
res = pd.DataFrame(res)
res.index.rename('calculationID', inplace=True)

descr = {
    ('mark', pd.Period('2020-01', 'M')): {'ID1': 'm1', 'ID2': 'm1', 'ID3': 'm2', 'ID4': 'm2', 'ID5': 'm1'},
    ('mark', pd.Period('2020-02', 'M')): {'ID1': 'm1', 'ID2': 'm2', 'ID3': 'm3', 'ID4': 'm4', 'ID5': 'm2'},
    ('mark', pd.Period('2020-03', 'M')): {'ID1': 'm1', 'ID2': 'm2', 'ID3': 'm3', 'ID4': 'm4', 'ID5': 'm2'},
    ('mark', pd.Period('2020-04', 'M')): {'ID1': 'm1', 'ID2': 'm2', 'ID3': 'm3', 'ID4': 'm4', 'ID5': 'm2'},
}
descr = pd.DataFrame(descr)
descr.index.rename('calculationID', inplace=True)

Ответы (1 шт):

Автор решения: Алекс Серкин

"Костылем" является обращение в слайсе через pd.Period:

total_df.loc[:, idx[:, pd.Period('2020-01'):pd.Period('2020-02')]]

Результат:

              bucket            mark
              2020-01  2020-02  2020-01  2020-02
calculationID
ID1           1.0      1.0      m1       m1
ID2           1.0      1.0      m1       m2
ID3           1.0      1.0      m2       m3
ID4           1.0      1.0      m2       m4
ID5           1.0      1.0      m1       m2

В идеале конечно понять почему в исходных массивах (до объединения) все работает без дополнительного явного преобразования строки в объект класса Period.

→ Ссылка