Как заставить уровень MultiIndex для dtype

1

Я использую combine_first для объединения двух DataFrames на основе двух ключей, цель состоит в том, чтобы добавить индексы df2, которые не содержатся в df1 к результату, и перезаписать индексы, которые содержатся в обоих значениях из df2.

Пример df1:

df1 = pd.DataFrame({
    "key1": ["A", "A", "A", "B", "B", "C", "C"],
    "id": ["a1", "a2", "a3", 1, 2, "c1", "c2"],
    "data1": [pd.np.random.randint(5) for i in range(7)],
    "data2": [pd.np.random.randint(1000) for i in range(7)]
})

Пример df2:

df2 = pd.DataFrame({
    "key1": ["B", "B", "B"],
    "id": [2, 3, 4],
    "data1": [pd.np.random.randint(5) for i in range(3)],
    "data2": [pd.np.random.randint(1000) for i in range(3)]
})

df1.set_index(["key1", "id"]).combine_first(df2.set_index(["key1", "id"])) дает желаемый результат:

         data1  data2
key1 id              
A    a1    0.0  588.0
     a2    2.0  709.0
     a3    3.0  877.0
B    1     3.0  468.0
     2     0.0  612.0
     3     2.0  139.0
     4     3.0  154.0
C    c1    4.0  855.0
     c2    4.0  564.0

Однако после сохранения результата в виде csv, снова загрузив его и запустив ту же команду, я получаю следующую ошибку:

TypeError: '<' not supported between instances of 'str' and 'int'

Но только для df2, где id - только int. Когда id содержит символы, он работает без проблем.

Я нашел это в документах Pandas:

Другая операция индексирования может потенциально изменить dtype серии.

Это объясняет, почему проблема сохраняется, если я изменяю dtype df2.id на object перед установкой индекса и объединением. Как я могу конкретно установить dtype уровня MultiIndex, чтобы комбинация работала?


EDIT Чтобы еще раз проиллюстрировать проблему:

df = df1.set_index(["key1", "id"]).combine_first(df2.set_index(["key1", "id"]))
df.to_csv("tests/combtest2.csv", sep=";")
df_loaded = pd.read_csv("tests/combtest2.csv", sep=";", index_col=["key1", "id"])

Выглядит хорошо:

         data1  data2
key1 id              
A    a1    0.0  588.0
     a2    2.0  709.0
     a3    3.0  877.0
B    1     3.0  468.0
     2     0.0  612.0
     3     2.0  139.0
     4     3.0  154.0
C    c1    4.0  855.0
     c2    4.0  564.0

Но df_loaded.combine_first(df2.set_index(["key1", "id"])) приводит к:

         data1  data2
key1 id              
A    a1    0.0  588.0
     a2    2.0  709.0
     a3    3.0  877.0
B    1     3.0  468.0
     2     0.0  612.0
     3     2.0  139.0
     4     3.0  154.0
C    c1    4.0  855.0
     c2    4.0  564.0
B    2     2.0  317.0
     3     2.0  139.0
     4     3.0  154.0
  • 0
    В качестве обходного пути я прибегнул сначала к объединению всех старых и новых наблюдений для определенного key1 а затем добавил их, чтобы получить окончательный результат. Я бы предпочел не включать этот дополнительный шаг, а просто установить для level (1) dtype для df2 значение object.
  • 0
    Вы уверены, что изменение dtype df2.id на object перед установкой индекса и объединением не решает проблему? Я только что попробовал, и это сработало.
Показать ещё 5 комментариев
Теги:
pandas

1 ответ

1
Лучший ответ

Перед объединением вы должны преобразовать столбец id в str, а не object.

Это будет работать:

df2.id = df2.id.astype(str)
df_loaded.combine_first(df2.set_index(["key1", "id"]))

Ещё вопросы

Сообщество Overcoder
Наверх
Меню