При выборе подкадра данных из родительского, я заметил, что некоторые программисты делают копию фрейма данных, используя .copy()
метод. Например,
X = my_dataframe[features_list].copy()
... а не просто
X = my_dataframe[features_list]
Почему они делают копию фрейма данных? Что будет, если я не сделаю копию?
python
pandas
chained-assignment
Элизабет Сьюзан Джозеф
источник
источник
Ответы:
Это расширяет ответ Павла. В Pandas индексирование DataFrame возвращает ссылку на начальный DataFrame. Таким образом, изменение подмножества изменит начальный DataFrame. Таким образом, вы захотите использовать копию, если хотите убедиться, что исходный DataFrame не должен изменяться. Рассмотрим следующий код:
Ты получишь:
Напротив, следующее оставляет df без изменений:
источник
Потому что, если вы не сделаете копию, то индексами все равно можно будет манипулировать в другом месте, даже если вы присваиваете dataFrame другое имя.
Например:
func1 может изменить df, изменив df2, чтобы избежать этого:
источник
, both variables reference the same DataFrame instance. So any changes made to
df` илиdf2
будет создан для того же экземпляра объекта. Принимая во внимание, чтоdf2 = df.copy()
во втором экземпляре объекта создается копия первого, но теперьdf
иdf2
ссылки на разные экземпляры объекта, и любые изменения будут внесены в их соответствующий экземпляр DataFrame.Необходимо отметить, что возвращаемая копия или представление зависит от вида индексации.
Документация панд гласит:
источник
Основная цель состоит в том, чтобы избежать цепной индексации и устранить
SettingWithCopyWarning
.Здесь цепная индексация что-то вроде
dfc['A'][0] = 111
В документе говорится, что при возвращении представления вместо копии следует избегать цепной индексации . Вот немного измененный пример из этого документа:
Здесь
aColumn
это представление, а не копия исходного DataFrame, поэтому изменениеaColumn
также приведет к изменению оригиналаdfc
. Далее, если мы сначала проиндексируем строку:На этот раз
zero_row
это копия, поэтому оригиналdfc
не изменяется.Из этих двух примеров выше мы видим неоднозначно, хотите ли вы изменить исходный DataFrame. Это особенно опасно, если вы напишите что-то вроде следующего:
На этот раз это не сработало. Здесь мы хотели изменить
dfc
, но мы фактически изменили промежуточное значение,dfc.loc[0]
которое является копией и немедленно отбрасывается. Это очень трудно предсказать , будет ли промежуточное значение , какdfc.loc[0]
иdfc['A']
вид или копию, так что это не гарантировано , будет ли или не будет обновляться оригинал DataFrame. Вот почему следует избегать цепной индексации, и pandas генерируетSettingWithCopyWarning
для этого вида обновления цепочечной индексации.Теперь это использование
.copy()
. Чтобы устранить предупреждение, сделайте копию, чтобы явно выразить свое намерение:Поскольку вы
dfc
изменяете копию, вы знаете, что оригинал никогда не изменится, и вы не ожидаете, что она изменится. Ваше ожидание соответствует поведению, а затемSettingWithCopyWarning
исчезает.Примечание. Если вы хотите изменить исходный DataFrame, в документе предлагается использовать
loc
:источник
В целом, работать с копиями безопаснее, чем с исходными фреймами данных, за исключением случаев, когда вы знаете, что вам больше не понадобится оригинал, и хотите перейти к манипулированной версии. Обычно вам все равно придется использовать исходный фрейм данных для сравнения с манипулированной версией и т. Д. Поэтому большинство людей работают с копиями и объединяются в конце.
источник
Предполагается, что у вас есть фрейм данных, как показано ниже
Когда вы хотели бы создать другой,
df2
который идентиченdf1
, безcopy
И хотел бы изменить значение df2 только как показано ниже
В то же время df1 также изменяется
Поскольку два df одинаковы
object
, мы можем проверить это, используяid
Таким образом, они как один и тот же объект, и один изменяет другой, передают одинаковое значение.
Если мы добавим
copy
, а теперьdf1
и будемdf2
считать разнымиobject
, если мы сделаем одно и то же изменение, то одно из них не изменится.Стоит упомянуть, что, когда вы задаете исходный фрейм данных, можно также добавить копию, чтобы избежать
SettingWithCopyWarning
источник