Ao selecionar um sub-quadro de dados de um quadro-pai pai, notei que alguns programadores fazem uma cópia do quadro de dados usando o .copy()
método Por exemplo,
X = my_dataframe[features_list].copy()
... em vez de apenas
X = my_dataframe[features_list]
Por que eles estão fazendo uma cópia do quadro de dados? O que acontecerá se eu não fizer uma cópia?
python
pandas
chained-assignment
Elizabeth Susan Joseph
fonte
fonte
Respostas:
Isso se expande na resposta de Paulo. No Pandas, a indexação de um DataFrame retorna uma referência ao DataFrame inicial. Assim, alterar o subconjunto alterará o DataFrame inicial. Portanto, você deseja usar a cópia se quiser garantir que o DataFrame inicial não seja alterado. Considere o seguinte código:
Você terá:
Por outro lado, o seguinte deixa df inalterado:
fonte
Como se você não fizer uma cópia, os índices ainda poderão ser manipulados em outro local, mesmo se você atribuir o dataFrame a um nome diferente.
Por exemplo:
func1 pode modificar o df modificando o df2, para evitar que:
fonte
, both variables reference the same DataFrame instance. So any changes made to
df` oudf2
será feito na mesma instância do objeto. Enquanto nadf2 = df.copy()
segunda instância do objeto é criada, uma cópia da primeira, mas agora,df
e adf2
referência a diferentes instâncias do objeto e quaisquer alterações serão feitas na respectiva instância do DataFrame.É necessário mencionar que o retorno da cópia ou exibição depende do tipo de indexação.
A documentação do pandas diz:
fonte
O objetivo principal é evitar a indexação encadeada e eliminar o
SettingWithCopyWarning
.Aqui a indexação encadeada é algo como
dfc['A'][0] = 111
O documento dizia que a indexação encadeada deve ser evitada em Retornando uma exibição versus uma cópia . Aqui está um exemplo ligeiramente modificado desse documento:
Aqui
aColumn
está uma visualização e não uma cópia do DataFrame original; portanto, a modificação tambémaColumn
fará com que o originaldfc
seja modificado. Em seguida, se indexarmos a linha primeiro:Desta vez
zero_row
é uma cópia, portanto o originaldfc
não é modificado.A partir desses dois exemplos acima, vemos que é ambíguo se você deseja ou não alterar o DataFrame original. Isso é especialmente perigoso se você escrever algo como o seguinte:
Desta vez, não funcionou. Aqui queríamos mudar
dfc
, mas na verdade modificamos um valor intermediáriodfc.loc[0]
que é uma cópia e é descartado imediatamente. É muito difícil prever se o valor intermediário comodfc.loc[0]
oudfc['A']
é uma visão ou uma cópia, por isso não é garantido ou não trama de dados original será atualizado. É por isso que a indexação em cadeia deve ser evitada, e o pandas gera oSettingWithCopyWarning
para esse tipo de atualização de indexação em cadeia.Agora é o uso de
.copy()
. Para eliminar o aviso, faça uma cópia para expressar sua intenção explicitamente:Como você está modificando uma cópia, sabe que o original
dfc
nunca será alterado e não espera que seja alterado. Sua expectativa corresponde ao comportamento e depoisSettingWithCopyWarning
desaparece.Nota, se você deseja modificar o DataFrame original, o documento sugere que você use
loc
:fonte
Em geral, é mais seguro trabalhar em cópias do que em quadros de dados originais, exceto quando você sabe que não precisará mais do original e deseja continuar com a versão manipulada. Normalmente, você ainda teria algum uso para o quadro de dados original para comparar com a versão manipulada, etc. Portanto, a maioria das pessoas trabalha com cópias e mescla no final.
fonte
Supondo que você tenha um quadro de dados como abaixo
Quando você deseja criar outro
df2
que seja idênticodf1
, semcopy
E gostaria de modificar o valor df2 apenas como abaixo
Ao mesmo tempo, o df1 também é alterado
Como dois df são iguais
object
, podemos verificá-lo usando oid
Portanto, eles têm o mesmo objeto e um muda outro, também passa o mesmo valor.
Se adicionarmos o
copy
, e agora,df1
e formosdf2
considerados diferentesobject
, se fizermos a mesma alteração em um deles, o outro não será alterado.É bom mencionar que, quando você define o quadro de dados original, também é seguro adicionar a cópia para evitar a
SettingWithCopyWarning
fonte