Установка значений в Pandas Подмножество DataFrame (копия) работает медленно

import timeit
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.rand(10, 10))

dft = df[[True, False] * 5]
# df = dft
dft2 = dft.copy()

new_data = np.random.rand(5, 10)

print(timeit.timeit('dft.loc[:, :] = new_data', setup='from __main__ import dft, new_data', number=100))
print(timeit.timeit('dft2.loc[:, :] = new_data', setup='from __main__ import dft2, new_data', number=100))

Значения параметров моего ноутбука в dft (исходное подмножество) примерно в 160 раз медленнее, чем значения в dft2 (глубокая копия dft).

Почему это так?

Изменить: удалены спекуляции о прокси-объектах.

Как c. кожа предполагает, что это, вероятно, связано с другой кодировкой при установке значений на копии (dft) по сравнению с исходным фреймворком данных (dft2).

Бонусный вопрос: удалив ссылку на исходный DataFrame df (раскомментируя строку df = dft), сокращает коэффициент скорости примерно до 2 на моем ноутбуке. Любая идея, почему это так?

Ответ 1

Это не совсем новый вопрос о SO. Этот и этот являются связанными сообщениями. Это ссылка на текущие документы, которая объясняет это.

Комментарии от @c.leather находятся на правильном пути. Проблема в том, что dft - это представление, а не копия фрейма данных df, как описано в связанных статьях. Но pandas не может знать, действительно ли это или нет копия, и если операция безопасна или нет, и, как таковая, выполняется много проверок, чтобы гарантировать безопасное выполнение задания, и этого можно было бы избежать просто сделав копию.

Это актуальная проблема, и есть целая дискуссия на Github. Я видел много предложений, которые мне больше всего нравятся, поскольку документы должны поощрять идиому df[[True,False] * 5].copy(), можно назвать ее фрагментом и идиомой копирования.

Я не смог найти точные проверки, и по проблеме github этот нюанс производительности упоминается только через некоторые твиты, которые некоторые разработчики отметили в поведении. Возможно, кто-то, кто больше участвует в разработке pandas, может добавить еще несколько данных.