Пожалуйста, ознакомьтесь со следующими простыми сценариями и дайте мне знать, если я делаю что-то не так, или это, возможно, ошибка в Pandas MultiIndex DataFrames?
index = pd.MultiIndex.from_tuples((), names=[ "i1", "i2" ] )
df = pd.DataFrame( index = index, columns = [ "c1", "c2" ] )
df
c1 c2
i1 i2
Результатом является пустой кадр данных с двухуровневым мультииндексом (i1, i2) и двумя столбцами (c1, c2), как показано выше. Теперь вставьте первую строку в этот фрейм данных:
df.loc[ ( "x", "y" ) ] = 1
df
c1 c2 y
i1 i2
x NaN NaN 1.0
Такого результата я не ожидал. Он вставляет новую строку (правильно) с новым столбцом с именем «y» (на мой взгляд, неправильно), используя значение, которое должно было быть вставлено в индекс i2, и не присваивая значений i2, c1 и c2.
Сравните это с аналогичным случаем одноуровневого MultiIndex:
index = pd.MultiIndex.from_tuples((), names=[ "i1" ] )
df = pd.DataFrame( index = index, columns = [ "c1", "c2" ] )
df
c1 c2
i1
df.loc[ "x" ] = 1, 2
df
c1 c2
i1
x 1 2
Здесь мы находим новую строку «x» со значением индекса в индексе, значениями данных в столбцах и без добавления дополнительного столбца.
Или с еще более подходящим случаем 3-уровневого MultiIndex:
index = pd.MultiIndex.from_tuples((), names=[ "i1", "i2", "i3" ] )
df = pd.DataFrame( index = index, columns = [ "c1", "c2" ] )
df
c1 c2
i1 i2 i3
df.loc[ ("x", "y", "z") ] = 1, 2
df
c1 c2
i1 i2 i3
x y z 1 2
Также в этом случае вставляется новая строка («x», «y», «z») со значениями индекса в индексе, значениями данных в столбцах и без добавления дополнительного столбца.
Так почему же такое девиантное поведение в случае двухуровневого MultiIndex DataFrame? Обратите внимание, что я обнаружил такое же поведение при добавлении строки с помощью pd.concat вместо df.loc.
Также обратите внимание, что только для двухуровневого MultiIndex DataFrame инструкция:
df.loc[ ( "x", "y" ) ] = 1, 2
генерирует ValueError: «невозможно установить с помощью индексатора выбора с несколькими индексами длину, отличную от значения».
Использование Python 3.6 (x64) и Pandas 0.20.3.