【问题标题】:Using Counter in Python, how do I filter the most common words在 Python 中使用 Counter,如何过滤最常用的单词
【发布时间】:2018-04-01 22:04:18
【问题描述】:

我正在尝试查找导出到 .txt 文件的 whatsapp 聊天中最常用的单词。 此代码有效...

from collections import Counter
import re
words = re.findall(r'\w+', open('chat.txt').read().lower())
print(Counter(words).most_common(10))

...但是它包括所有日期以及我自己的姓名和收件人姓名。 我可以添加什么让它忽略某些单词? (我确信有一个非常简单的解决方案,但我对 python 很陌生。) 谢谢!

编辑:

我没有很好地解释我的问题,我现在明白了。我意识到我不能说得很具体,因为我主要只是在复制代码示例并试验什么是有效的,而不是分析代码本身。

我试图在 .txt 文件中找到最常用的单词,这是一个存档的 whatsapp 聊天,一个有点无聊的例子:

“[2017 年 6 月 12 日,18:09:10] 姓名 1 姓 1:现在就在地铁上

[2017 年 6 月 12 日,18:09:29] 姓名 1 姓 1:我大概需要 25 分钟,所以我会做得很好

[06/12/2017, 18:36:16] Name2 Surname2: 我在 11 号站台等着

[16/12/2017, 00:06:34] Name2 Surname2:我的消息没有发送

[16/12/2017, 00:10:55] Name1 Surname1: ?

[16/12/2017, 00:11:14] Name1 Surname1:出于某种原因,这些只是刚刚出现”

在使用上述代码对这篇文章进行第一次编辑时,结果如下:

[('2018', 8552), ('name1', 6753), ('surname1', 6625), ('02', 4520), ('03', 3810), ('i', 3322), ('you', 2275), ('name2', 2016), ('01', 1995), ('surname2', 1991)]

所以它包括了我想排除的日期和名称。

但是这段代码:

from collections import Counter

with open('_chat.txt') as fin:
counter = Counter(fin.read().strip().split())

print(counter.most_common(10))

不包括数字。但是,它仍然包含一些不需要的词,例如名称和“无意义”的词,例如“the”和“and”:

[('Name1', 6686), ('Surname1:', 6615), ('I', 2277), ('Name2', 2000), ('Surname2:', 1990), ('you', 1714), ('to', 1488), ('and', 1084), ('a', 885), ('the', 881)]

我可以添加什么来删除这些类型的词?

我知道这类似于How do I remove entries within a Counter object with a loop without invoking a RuntimeError? 但是当我尝试以类似于此的方式格式化我的代码时,它并没有成功,并且对它的工作原理也有点困惑。 (很抱歉,我说我对 python 很陌生,我的意思是非常非常新。)

【问题讨论】:

  • 你尝试过更精致的正则表达式吗? \w+ 太宽泛了。
  • 您可以尝试将 Counter(words) 存储到变量中。应用循环(跟随骗子)删除不需要的元素,最后得到最常见的。
  • 我们无法为您提供太多帮助,因为我们不知道您为什么使用\w+、日期的格式以及示例输入。请编辑问题以便回答。
  • 我已经编辑了这个问题,不确定这是否更有意义。很抱歉造成混乱:-(

标签: python regex counter


【解决方案1】:

查看您的输入,我建议您在将其放入 Counter 之前对其进行清理。

如果您的文件中的行如下所示:

[06/12/2017, 18:09:10] Name1 Surname1: just on the tube now

然后您可以通过查找第一个结束 ] 并在此之后切片来清除日期,然后通过对 : 执行类似操作来清除名称。可以使用file.readlines() 读取文件中的行,然后处理每一行,例如

with open('chat.txt') as f:
    lines = f.readlines()
def clean_line(line):
    """
       Find the first ], assume it's followed by a space and
         slice off everything after that
       Split the line on the first : and take the second part
         of the resulting list
    """
    return line[line.find(']')+2:].split(':', 1)[1]
words = []
for line in lines:
    words += clean_line(line).lower().split()

counted_words = Counter(words)

【讨论】:

  • 啊,我明白了,这更有意义,谢谢。我试过添加这个,但我收到一个语法错误,说“words = [clean_line(line).lower().split() for line in lines)”无效?另外,我在哪里重新引入柜台?我不确定如何整体构建代码。 (((((再次为昏暗感到抱歉))))
  • 无需道歉。我犯了一个语法错误,我修复了它,但我不应该做一个列表理解,因为我们最终得到了一个列表列表,它必须被展平。相反,我将其作为一个简单的循环完成并附加到另一个变量,然后添加 Counter 作为示例。希望对您有所帮助。
  • 不幸的是,这仍然对我不起作用,我收到“IndexError: list index out of range”?
  • 如果不查看您的代码及其操作的数据,很难准确地判断该错误指的是什么。我猜它一定是没有: 字符的行,因此.split(':, 1)` 会生成一个包含1 个项目的列表,并尝试访问第二个项目([1])失败。您可以try/except words += clean_line... 部分并打印出except 块中的失败行。 (希望这是有道理的)。
猜你喜欢
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 2012-11-19
  • 1970-01-01
  • 1970-01-01
  • 2017-04-23
  • 1970-01-01
  • 2020-08-16
相关资源
最近更新 更多