利用python进行word_count
来源:互联网 发布:鞋子价格,淘宝 编辑:程序博客网 时间:2024/06/06 04:14
一、动机
Word count就是统计文章中每个单词出现的次数,在自然语言处理和机器学习中是一个很基础的工作。Word count是如此的常见以至于学习Spark等工具时,给出的第一个例子就是它(有点像hello world)。于是这里就记录一下用python(主要是pandas模块)要如何进行word count,及一些基础的优化。
二、基础
1、思路
文章以txt文件的形式存在于D:\english_article\文件夹及其子文件夹下,那么首先要设计一个函数来把这些文件的地址都读进来,这里用递归的方法。
files = []
file_num = 0
def get_path(main_path):
global files
global file_num
try:
tmp = os.listdir(main_path)
for fil in tmp:
dir_path = main_path+'\\'+fil
if '.txt' in fil:
files.append(dir_path)
file_num += 1
else:
get_path(dir_path)
except Exception as e:
print e.message
对于读入的字符串,可以利用内建的split函数以空格来划分。然而要考虑到可能单词之间会出现多个空格,所以这里用python的正则表达式模块来划分:
re.split(re.compile(r'\s*'), article)
对于划分好的字符串,要考虑它是不是我们要统计的单词,还是其他字符。这个可以用string对象的isalpha()函数来判断。
对于需要记录的单词,还要把他们都变成小写,以防止同一个单词被分成好几类,这个用string对象的lower()函数来转换。
Pandas有一个函数value_counts,专门用来统计一个list中各项出现的次数,并返回一个Series。同时Series对象有add函数,可以将多次统计结果加在一起。
2、代码
用了一部分函数式编程的思想,最后打印出使用次数最多的前30个单词及其使用次数。
import sys
import pandas as pd
import re
from pandas import Series
import os
files = []
file_num = 0
def get_path(main_path):
global files
global file_num
try:
tmp = os.listdir(main_path)
for fil in tmp:
dir_path = main_path+'\\'+fil
if '.txt' in fil:
files.append(dir_path)
file_num += 1
else:
get_path(dir_path)
except Exception as e:
print e.message
path = 'D:\\english_article'
get_path(path)
counter = Series()
print ' '
num = 1
for txt_file in files:
with open(txt_file) as s:
a = pd.value_counts(filter(lambda x: x.isalpha(), map(lambda x:x.lower(), re.split(re.compile(r'\s*'), s.read()))))
counter = counter.add(a, fill_value=0)
sys.stdout.write('\r%d/%d' % (num, file_num+1))
num += 1
print ' '
counter =counter.sort_values(ascending=False)
print counter[:30]
三、优化
我用的IDE是pycharm专业版,我觉得和裸写代码相比,最大的好处就是他自带图形化的profile工具。现在用这个工具分析一下,发现总共用时128342ms。
如图,其中88.8%的时间都用在了join函数上,62.1%的时间用在了union函数上。这说明大部分时间都花在了Series对象的并操作上。既然如此,考虑到文章并不大,可以全部读到内存里,就在这里优化。全部读入,只统计一次。
import pandas aspd
import re
import os
files = []
file_num = 0
article = ''
defget_path(main_path):
global files
global file_num
try:
tmp = os.listdir(main_path)
for fil in tmp:
dir_path = main_path+'\\'+fil
if '.txt' in fil:
files.append(dir_path)
file_num += 1
else:
get_path(dir_path)
except Exception as e:
print e.message
path ='D:\\english_article'
get_path(path)
print ' '
num = 1
for txt_file infiles:
with open(txt_file) as s:
article += s.read()
print ' '
counter =pd.value_counts(map(lambda x: x.lower(), filter(lambda x: x.isalpha(),re.split(re.compile(r'\s*'),article))))
counter =counter.sort_values(ascending=False)
printcounter[:30]
这次用时20670ms,比之前快了6倍!
不过对于之前的获得所有文件地址操作和读取所有文件的内容操作,python本身就自带相应的模块和函数os.walk和fileinput.input ,套用他们对程序重写如下:
import pandas as pd
import re
import os
import fileinput
files = []
path = 'D:\\english_article'
for data in os.walk(path):
files.extend(map(lambda x: os.path.join(data[0], x), data[2]))
article =''.join(list(fileinput.input(files)))
counter = pd.value_counts(map(lambda x:x.lower(), filter(lambda x: x.isalpha(),re.split(re.compile(r'\s*'),article))))
counter =counter.sort_values(ascending=False)
print counter[:30]
实际有用的代码只有5行,确实是非常精简。但运行时间变成了31256ms,看来有时候确实不是代码越简单速度越快嘛。
- 利用python进行word_count
- word_count
- word_count
- 利用python进行图像处理
- 利用Python进行数据处理 笔记
- 利用python进行T检验
- 《利用Python进行数据挖掘》
- modprobe word_count
- [Python]利用Python进行网络爬虫
- 利用python特性进行提权
- 利用python对rrd进行resize
- 利用python对rrd进行resize
- 利用python进行批量导出时态图片
- python:利用asyncio进行快速抓取
- 利用Python进行数据分析--时间序列
- python利用cookie登录网站进行访问
- python 利用Raw Socket进行以太网帧嗅探
- 利用Python 的 Pandas进行数据分析
- x265-1.8版本-common/threading.h注释
- Git使用教程
- 在你的Mac上安装Docker Toolbox
- x265-1.8版本-common/threadpool.h注释
- 做软件测试的节操和底线
- 利用python进行word_count
- bzoj3123 森林 主席树&启发式合并
- x265-1.8版本-common/wavefront.cpp注释
- x265-1.8版本-common/wavefront.h注释
- 判断 ttf 字体文件是否包含某个字
- x265-1.8版本-common/yuv.h注释
- HDU-1016-Prime Ring Problem( C && 经典DFS题 )
- 深拷贝与浅拷贝
- 个人关于对KVC和KVO