4
respostas

Renomeando nomes iguais porém com escritas diferentes

Tenho esse arquivo csv onde, por exemplo, existem x ocorrências da palavra "Brasília", porém escritas de diversas maneiras, na qual, quando quero buscar por todas, os resultados não são somados pois eu só peguei as que estavam de acordo com a minha escrita (visto que aqui o propósito é fazer a contagem total de ocorrências usando pandas). Há muitas ocorrões de diversas cidades, ex.: São Paulo, sao paulo, Sao paulo, são Paulo; Brasília, brasilia; etc.

Há alguma maneira de renomear/padronizar essas várias palavras afim de que eu consigar fazer a contagem total de ocorrências? Se houver também uma maneira onde eu consiga contar o total de ocorrências mesmo com escritas diferentes, por favor me ilumine. Vale ressaltar que quero usar esses dados no seaborn/matplotlib (não se essa informação altera a resposta mas ta ae) Muito obrigado.

4 respostas

Boas Felipe!Tudo bem? Espero que sim!

Esse problema que você relatou é uma das coisas que ocorrem quando trabalhamos com dados no mundo real, especialmente quando a origem de dados não é padronizada. Nesse caso, existem algumas formas de tratar esses dados, Vou mostrar uma que creio ser a mais eficiente.

Primeiro, vou criar um Dataset que imita o que você reportou:

cidades = ['São Paulo', 'sao paulo', 'são Paulo', 'São Paulo']

df = pd.DataFrame(cidades, columns=['cidade'], index=range(4))
df

Que resulta em:

cidade
0São Paulo
1sao paulo
2são Paulo
3São Paulo

Agora, precisamos instalar a biblioteca unidecode, que faz retirar os acentos das palavras sem grandes dificuldades, através do comando ! pip install unidecode, se estiver usando o Google Collab, ou o mesmo comando sem o ! na frente, caso esteja utilizando o terminal.

Agora, vamos importar a biblioteca e usar a função unidecode para retirar os acentos das várias grafias de São Paulo:

from unidecode import unidecode

df.cidade = df.cidade.map(unidecode)

Agora, nosso dataframe está com os nomes das cidades sem acento:

cidade
0Sao Paulo
1sao paulo
2sao Paulo
3Sao Paulo

Para resolver a questão dos caracteres maísculos e minúsculos, existem algumas técnicas, que normalmente consistem em deixar todos os caracteres da palavra maiúsculos ou minusculos, o que não é muito elegante, mas funciona. Nesse caso, vamos usar uma função parecida da biblioteca str que está inclusa no python base:

df.cidade = df.cidade.str.title()
df.to_markdown()

A função title()transforma a primeira letra de cada palavra em maiúscula, o que eu considero uma solução mais elegante. Agora, temos em nosso DataFrame:

cidade
0Sao Paulo
1Sao Paulo
2Sao Paulo
3Sao Paulo

E é nesse ponto que gostaríamos de chegar, pois agora, basta restituir o til (~) na palavra, o que vamos fazer através de um outro map() na Series da cidade:

cidades_corretas = {'Sao Paulo': 'São Paulo'}
df.cidade = df.cidade.map(cidades_corretas)

Que resulta em:

cidade
0São Paulo
1São Paulo
2São Paulo
3São Paulo

Em suma, devemos tentar trabalhar com as possibilidades aproximando o máximo de um padrão, para isso retiramos os caracteres especiais e utilizamos uma estratégia para ignorar mudanças de letras minúsculas e maiúsculas. Por fim, quando obtivemos o mesmo resultado de caracteres para todas as variações, voltamos à palavra que nos interessava através do mapeamento via dicionário.

Espero ter ajudado!Bons estudos!!

Deu um erro aqui de 'float' object has no attribute 'encode' ao rodar esse código nos meus dados, porém repetindo o exemplo aqui, deu certo. Acho que o problema é que eu to com uma lista de mais de 90 mil nomes de Municipios...

Boas Felipe,

Esse erro aparenta que você está tentando usar o encode() ou decode() em um número e não em uma string.

Errros de encoding ocorrem quando os caracteres estão sendo usados não correspondem ao que o python está esperando. É uma questão bastante importante então vou deixar o link da documentação oficial que nos ajuda nesse sentido.

Espero que lhe ajude! Bons estudos!

Okay, vou dar uma olhada, valeu!