Analise de frequencia de palavras - Função Counter - ajuda

599 views
Skip to first unread message

Bruno Santos

unread,
Oct 5, 2015, 11:50:30 AM10/5/15
to Python Brasil
Olá pessoal,

Tenho uma Lista preenchida com tuplas. Dentro de cada tupla tenho três valores, sendo eles:

[('Meu Nome', ' Minha Cidade', 'Aqui tem um pequeno texto'), ('Nome', ' Cidade', 'texto digitado pelo usuario'), ('Meu Nome', ' Minha Cidade', 'Aqui tem um pequeno texto')]

Desejo percorrer essa lista para saber a quantidade de vezes que as palavras aparaceram na lista como um todo. Seguindo o exemplo acima seria:

(Meu: 2)
(Nome: 3)
(Cidade: 3)
(texto: 3)

e por aí vai.

Quando faço um laço de repetição, o que me é retornado é a tupla inteira. Porém quando trabalho com dois laços, é me retornado a contagem de frequência por caracteres.

Estou utilizando a função Counter.

Como posso fazer esse retorno por ocorrências de palavras?
Existe algum modo melhor para realizar essa tarefa?

Abraço!

Leidson Dias

unread,
Oct 5, 2015, 12:27:23 PM10/5/15
to python...@googlegroups.com
from collections import Counter

lista = [('Meu Nome', ' Minha Cidade', 'Aqui tem um pequeno texto'), ('Nome', ' Cidade', 'texto digitado pelo usuario'), ('Meu Nome', ' Minha Cidade', 'Aqui tem um pequeno texto')]

var args = []

for li in lista:
    for ii in li:
        args.append(ii)

Counter(args)

>>
Counter({' Minha Cidade': 2, 'Meu Nome': 2, 'Aqui tem um pequeno texto': 2, 'Nome': 1, ' Cidade': 1, 'texto digitado pelo usuario': 1})

--
--
------------------------------------
Grupo Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar
 
<*> Para visitar o site do grupo na web, acesse:
http://groups.google.com/group/python-brasil
 
<*> Para sair deste grupo, envie um e-mail para:
python-brasi...@googlegroups.com

---
Você recebeu essa mensagem porque está inscrito no grupo "Python Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para python-brasi...@googlegroups.com.
Para mais opções, acesse https://groups.google.com/d/optout.



--
Graduado em Análise e Desenvolvimento de Sistemas - Estácio IDez

Bruno Santos

unread,
Oct 5, 2015, 12:37:02 PM10/5/15
to Python Brasil
Olá Leidson,

muito obrigado pela resposta!

Acabei escrevendo errado minha pergunta. 

Na verdade, eu desejo é realizar a contagem de palavras presente apenas no "texto digitado pelo usuário" ou seja, na terceira posição da tupla.

for nome, cidade,texto in lista:
   
print texto

Com o for acima, eu tenho como retorno uma string. O que eu queria saber é, como contar as palavras dessa string?

Abraço!

Eduardo Klosowski

unread,
Oct 5, 2015, 1:16:04 PM10/5/15
to python...@googlegroups.com
Para pegar as palavras de uma string use a função split.

Exemplo:
for nome, cidade,texto in lista:
for palavra in texto.split():
print palavra

Esse código imprime a palavra, porém se for o que deseja, só alterar
para fazer a contagem.

Blog: https://eduardoklosowski.wordpress.com/
GitHub: https://github.com/eduardoklosowski/
> <javascript:>> escreveu:
>
> Olá pessoal,
>
> Tenho uma Lista preenchida com tuplas. Dentro de cada tupla
> tenho três valores, sendo eles:
>
> |
> [('Meu Nome',' Minha Cidade','Aqui tem um pequeno
> texto'),('Nome',' Cidade','texto digitado pelo usuario'),('Meu
> python-brasi...@googlegroups.com <javascript:>
>
> ---
> Você recebeu essa mensagem porque está inscrito no grupo "Python
> Brasil" dos Grupos do Google.
> Para cancelar inscrição nesse grupo e parar de receber e-mails
> dele, envie um e-mail para python-brasi...@googlegroups.com
> <javascript:>.
> Para mais opções, acesse https://groups.google.com/d/optout
> <https://groups.google.com/d/optout>.
>
>
>
>
> --
> Leidson Dias | http://leidsondias.com.br/
> Graduado em Análise e Desenvolvimento de Sistemas - Estácio IDez
>
> --
> --
> ------------------------------------
> Grupo Python-Brasil
> http://www.python.org.br/wiki/AntesDePerguntar
>
> <*> Para visitar o site do grupo na web, acesse:
> http://groups.google.com/group/python-brasil
>
> <*> Para sair deste grupo, envie um e-mail para:
> python-brasi...@googlegroups.com
>
> ---
> Você recebeu essa mensagem porque está inscrito no grupo "Python Brasil"
> dos Grupos do Google.
> Para cancelar inscrição nesse grupo e parar de receber e-mails dele,
> envie um e-mail para python-brasi...@googlegroups.com
> <mailto:python-brasi...@googlegroups.com>.

Bruno Santos

unread,
Oct 5, 2015, 1:58:28 PM10/5/15
to Python Brasil
Olá Eduardo,

Muito obrigado, cara!

Deu certinho, já fiz a modificação aqui. Agora é trabalhar pra ajeitar a codificação do texto que veio atrapalhada.

Ficou assim:

frequencia = []
for nome, cidade,texto in lista_sudeste:
    for palavra in texto.split():
         frequencia.append(palavra.encode('utf-8'))

print Counter(frequencia)


Palavras como "Panelaço" vieram assim: 'Panela\xc3\xa7o'.

Até tentei fazer um encode('utf-8') como mostrado acima mas aconteceu o seguinte erro:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)


Se eu der um print na lista_sudeste, a acentuação dos textos estarão corretas, mas quando faço o Counter eu perco toda a acentuação.

Conseguem me informar o eu posso estar fazer errado?

Essa parte de acentuação está complicada..hehe

Obrigado!

Eduardo Klosowski

unread,
Oct 5, 2015, 2:41:28 PM10/5/15
to python...@googlegroups.com
Uma solução mais simples seria migrar para o Python 3, que já vem com
UTF-8 como padrão em vez de ascii.

Agora uma explicação mais técnica. No Python existe um método chamado
__str__ que converte qualquer objeto para string (ou pelo menos tenta),
normalmente usada como str(variável) por questões de performance. Porém
em alguns casos o método __repr__ é chamado no lugar, já que seria uma
representação em texto do objeto.

Um teste que pode ser feito no console interativo:
>>> a = 'ção'
>>> a
'\xc3\xa7\xc3\xa3o'
>>> print a
ção

Isso também acontece dentro de dicionários, mesmo chamando o print:
>>> d = {'ção': 1}
>>> d
{'\xc3\xa7\xc3\xa3o': 1}
>>> print d
{'\xc3\xa7\xc3\xa3o': 1}

Porém isso não quer dizer que a codificação está incorreta, apenas que
estão mostrando a representação dos bytes e não os caracteres em si.
Trabalhando de outra forma temos:
>>> for k, v in d.items(): print k, v
...
ção 1

No Python 3 muda um pouco a sintaxe, porém como ele trabalha com unicode
por padrão, esse efeito não acontece:
>>> d = {'ção': 1}
>>> d
{'ção': 1}
>>> print(d)
{'ção': 1}

Mais informações na documentação oficial
(https://docs.python.org/2/reference/datamodel.html#object.__repr__),
onde fala que essa representação é tipicamente utilizada em debbug, e
não na aplicação em si.
Em 05-10-2015 14:58, Bruno Santos escreveu:
> Olá Eduardo,
>
> Muito obrigado, cara!
>
> Deu certinho, já fiz a modificação aqui. Agora é trabalhar pra ajeitar a
> codificação do texto que veio atrapalhada.
>
> Ficou assim:
>
> frequencia = []
> for nome, cidade,textoin lista_sudeste:
> for palavrain texto.split():
> > <mailto:python-brasi...@googlegroups.com <javascript:>>.
> --
> ------------------------------------
> Grupo Python-Brasil
> http://www.python.org.br/wiki/AntesDePerguntar
>
> <*> Para visitar o site do grupo na web, acesse:
> http://groups.google.com/group/python-brasil
>
> <*> Para sair deste grupo, envie um e-mail para:
> python-brasi...@googlegroups.com
>
> ---
> Você recebeu essa mensagem porque está inscrito no grupo "Python Brasil"
> dos Grupos do Google.
> Para cancelar inscrição nesse grupo e parar de receber e-mails dele,
> envie um e-mail para python-brasi...@googlegroups.com
> <mailto:python-brasi...@googlegroups.com>.

Bruno Santos

unread,
Oct 5, 2015, 3:25:10 PM10/5/15
to python...@googlegroups.com
Imaginava que a codificação estava incorreta mas com sua explicação eu consegui entender o que está acontecendo.
Consegui arrumar e imprimir isso de um jeito legível. 
Acredito que a migração para o Python 3 na minha situação será a melhor opção.

Muito obrigado pela atenção, Eduardo!

Abraço 

--- Você recebeu esta mensagem porque está inscrito em um tópico do grupo "Python Brasil" dos Grupos do Google.
Para cancelar inscrição nesse tópico, acesse https://groups.google.com/d/topic/python-brasil/t7jfsR7wDI0/unsubscribe.
Para cancelar inscrição nesse grupo e todos os seus tópicos, envie um e-mail para python-brasi...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/d/optout.

Renzo Nuccitelli

unread,
Oct 5, 2015, 8:55:46 PM10/5/15
to python...@googlegroups.com
Independente de ser Python 2 e Python 3, é importante entender o que deu errado. Nesse caso, foi não entender como strings funcionam. Como isso é dúvida recorrente, escrevi esse post para ajudar: http://blog.renzo.pro.br/2015/08/strings-em-python.html

Abs,

Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para python-brasi...@googlegroups.com.

Para mais opções, acesse https://groups.google.com/d/optout.
--
Renzo Nuccitelli

Eu leio email somente uma vez por dia. Se o assunto for urgente, me ligue.


Bruno Santos

unread,
Oct 5, 2015, 11:41:26 PM10/5/15
to Python Brasil
Olá Renzo,

Muito obrigado pelo link, bem esclarecedor.

Depois de ler o post no seu blog, compreendi nesse caso como devo trabalhar com as strings em Python.

Utilizei o  "from_future_import..."  e já estou corrigindo meu código de forma a trabalhar com os decode, encode, regras de negócio e encode para exportação.

Valeu!

=]
     > <mailto:python-brasil+unsub...@googlegroups.com <javascript:>>.

     > Para mais opções, acesse https://groups.google.com/d/optout
    <https://groups.google.com/d/optout>.

--
--
------------------------------------
Grupo Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar

<*> Para visitar o site do grupo na web, acesse:
http://groups.google.com/group/python-brasil

<*> Para sair deste grupo, envie um e-mail para:
python-brasi...@googlegroups.com

---
Você recebeu essa mensagem porque está inscrito no grupo "Python Brasil"
dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele,
envie um e-mail para python-brasi...@googlegroups.com

Hugo Tácito

unread,
Oct 6, 2015, 12:01:02 PM10/6/15
to Python Brasil
Tenta desse jeito:

from collections import OrderedDict
lista = [('Meu Nome', ' Minha Cidade', 'Aqui tem um pequeno texto'), ('Nome', ' Cidade', 'texto digitado pelo usuario'), ('Meu Nome', ' Minha Cidade', 'Aqui tem um pequeno texto')]
dicionario = dict()
for nome, cidade, texto in lista:
for palavra in texto.split():
try:
dicionario[palavra] = dicionario[palavra] + 1
except:
dicionario[palavra] = 1


#ordem original
print dicionario
#ordenado por quantidade de aparecimentos
print OrderedDict(sorted(dicionario.items(), key=lambda t: -t[1]))

Hugo Tácito

unread,
Oct 6, 2015, 12:01:02 PM10/6/15
to Python Brasil
Aproveitando a resposta do Leidson:

from collections import Counter
lista = [('Meu Nome', ' Minha Cidade', 'Aqui tem um pequeno texto'), ('Nome', ' Cidade', 'texto digitado pelo usuario'), ('Meu Nome', ' Minha Cidade', 'Aqui tem um pequeno texto')]
lista_palavras = []
for nome, cidade, texto in lista:
for palavra in texto.split():
lista_palavras.append(palavra)

print Counter(lista_palavras)

Bruno Santos

unread,
Oct 6, 2015, 10:50:55 PM10/6/15
to Python Brasil
Muito obrigado pela ajuda, Hudson!

Problema já resolvido!

Abraço 

Ari Sobel

unread,
Oct 8, 2015, 4:32:49 AM10/8/15
to python...@googlegroups.com
Usando split, uma solução poderia ser:

for nome, cidade,texto in lista:
   print len(texto.split())

Enviado do meu iPhone

Hermogenes Batista

unread,
Oct 10, 2015, 3:38:19 PM10/10/15
to python...@googlegroups.com
Ainda pode ser feito assim:

    1. lista = [('Meu Nome', ' Minha Cidade', 'Aqui tem um pequeno texto'), ('Nome', ' Cidade', 'texto digitado pelo usuario'), ('Meu Nome', ' Minha Cidade', 'Aqui tem um pequeno texto')]
    1. count_words = {}
    2.  
    3. for item in lista:
    4.     temp = ' '.join(item).split()
    5.     for i in temp:
    6.         count_words[i] = count_words.get(i, 0)+1
    Hermogenes Batista

    Sistemas de Informação - UFAL
    Reply all
    Reply to author
    Forward
    0 new messages