Como resolver o SettingWithCopyWarning do pandas?

Pandas é uma biblioteca de software criada para a linguagem de programação Python para manipulação e análise de dados, sendo muito usada para manipular tabelas numéricas e séries temporais por oferecer estruturas (como o dataframe, que é basicamente uma matriz) e operações com essa finalidade. O aviso “SettingWithCopyWarning” é constante termo de busca na internet. Embora não seja um erro e o processo continue em execução, pode levar a resultados inesperados se não for resolvido.

SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

Como a mensagem indica, esse aviso normalmente surge quando um valor está tentando ser definido em uma cópia de uma fatia de um pandas.DataFrame. Uma “operação de fatiamento” refere-se ao ato de selecionar partes específicas de um DataFrame ou de outra estrutura de dados em Python. No contexto do Pandas, isso geralmente é feito usando as funções “.loc[]” (fatiar baseado em rótulos de índice), “.iloc[]” (fatiar baseado em índices inteiros), ou operadores de fatiamento diretamente em um DataFrame ou (como “Série[start:end:step]”).

Veja duas soluções que você pode usar, dependendo de como for o seu problema. Conforme o código, talvez seja necessário usar as duas soluções. Por exemplo: se selecionar linhas em um dataframe e, na variável resultante desse processo, incluir uma coluna, você poderá criar uma cópia ao realizar a seleção e usar a sugestão do pandas de alterar a formatação e usar o método “.loc[]”.

Incluir “.copy()” quando selecionar partes de um dataframe

Vejamos o exemplo de selecionar algumas linhas de um dataframe usando o método “.iloc[]” na matriz df e uma lista com índices, conforme segue:

df_sel = df.iloc[indices]

O método copy() em Pandas cria uma cópia profunda do objeto, ou seja, ele cria uma nova instância do DataFrame (ou da série, se aplicável), em vez de apenas uma referência para o mesmo objeto. Isso significa que qualquer modificação feita na cópia não afetará o DataFrame original, e vice-versa. Veja como o código fica com a alteração:

df_sel = df.iloc[indices].copy()

Dessa forma, você garante que df_sel seja uma cópia independente do DataFrame df, e não uma visualização do mesmo. Isso evita que o aviso SettingWithCopyWarning apareça, porque agora df_sel é uma cópia completa e as modificações nele não afetarão o DataFrame original.

Alterar formatação e usar “.loc[row_indexer,col_indexer]”

Quando você está tentando modificar um DataFrame que é uma cópia de outro DataFrame originalmente criado por meio de uma operação de fatiamento, o aviso sugere alterar a sintaxe do comando. Por exemplo, suponha que você vai criar uma nova coluna naquela dataframe trabalhada no exemplo anterior da seguinte forma:

df_sel['new_column'] = new_values

A maneira recomendada de evitar esse aviso é usar .loc[] para atribuir valores a um DataFrame quando você estiver fazendo modificações. Aqui está como você pode ajustar seu código de acordo com a sugestão do aviso:

df_sel.loc[:, 'new_column'] = new_values

Isso garantirá que você esteja modificando o DataFrame original e não uma cópia dele. O : dentro do .loc[] seleciona todas as linhas do DataFrame. Se você precisar selecionar apenas linhas específicas, você pode substituir : pelos índices ou rótulos das linhas que deseja modificar.

Se você ainda está recebendo o aviso SettingWithCopyWarning após modificar seu código para usar .loc[], isso pode indicar que ainda há operações anteriores em seu código que estão criando uma cópia do DataFrame em vez de uma visualização (view) do DataFrame original. Para resolver isso, você pode tentar garantir que está manipulando o DataFrame original em todas as etapas do seu código.

Obs.: “Copy-on-Write” se tornará o novo padrão no pandas 3.0. Isso significa que a indexação encadeada nunca funcionará. Como consequência, o SettingWithCopyWarning não será mais necessário. Fonte: documentação do pandas

Extra Warning: Dtype inference on a pandas object

FutureWarning: Dtype inference on a pandas object (Series, Index, ExtensionArray) is deprecated. The Index constructor will keep the original dtype in the future. Call infer_objects on the result to get the old behavior.
  return Index(sequences[0], name=names)

Esse warning está relacionado à maneira como o Pandas lida com a inferência de tipos de dados ao criar um índice a partir de uma ‘Series’ ou ‘Index’. Especificamente, no futuro, o Pandas manterá o tipo de dado original ao criar o índice, em vez de inferir o tipo. Para resolver esse aviso, você pode converter explicitamente a coluna ‘timestamp’ para o tipo ‘datetime’ antes de defini-la como índice. Isso garantirá que o tipo de dado está correto e evitará a necessidade de inferência pelo Pandas. Aqui está como você pode fazer isso:

df['timestamp'] = pd.to_datetime(df['timestamp'])  # Converte a coluna 'timestamp' para datetime
df.set_index('timestamp', inplace=True)  # Define 'timestamp' como índice

Essa abordagem elimina o warning porque o tipo de dado da coluna já estará definido como ‘datetime64’, e não haverá necessidade de inferência adicional.

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.