python split函数 空格_python上手--10行代码读懂红楼梦

cb9f12821863301514837e0112a9ad8e.png

取名10行代码看懂红楼梦,是将介绍使用python代码来读红楼梦获取其主要人物。这里的思想就是词频统计,通过分析红楼梦小说文字中出现最多的词语,来概括说明红楼梦的核心人物和事情。实际上如果你能跟着往下看,就开始进入了自然语言处理的一些基础知识。

在正式进入读红楼梦之前,需要先铺垫一些词频统计相关知识。因此首先从英文的词频统计操作开始,其中的思想用到了大数据分布式处理里的mapreduce框架,在该框架中主要包括两个任务:map(映射)和reduce(规约)。这里不具体讨论MapReduce的思想和处理流程,我们来看一下在python中实现wordcount词频统计任务,进而来体验一下其基本思路。后面再来实现中文的词频统计分析,进而看懂红楼梦。

英文文章的词频统计

词频统计任务是一个非常常见的任务,也是相对较为简单的程序。任务就是从一段文字中将单词出现的次数统计出来,例如从ChinaDaily英文网站上关注一段新闻:

CHENGDU -- Rescuers have located 14 miners trapped underground in a flooded coal mine in Southwest China's Sichuan province, local authorities said Sunday.

The rescuers are clearing the shaft and drilling a deep hole to reach the trapped miners. They are also trying to pump and block water in a bid to prevent the rising of underground water levels and are sending more oxygen down the underground shaft.

The accident occurred at 3:26 pm Saturday at the Shanmushu coal mine owned by Sichuan Coal Industry Group in Gongxian County when 347 miners were working underground. A total of 329 escaped and four were killed.

Nearly 200 rescuers are racing against the clock to reach the trapped miners.

Due to communication interruptions in some mining areas, the workers were not immediately located. But through their consistent efforts, the rescue workers have finally located the remaining miners。

那这段话有多少个单词呢?最笨的办法就是一个个的数,但这显然不是我们想要的方式。既然有python,我们可以尝试使用程序来解决这个问题。

我们先来理清一下思路顺序。

(1)首先需要将这段文字从网站上拷贝下来或者爬取下来保存成文本文件;

(2)然后在python中读取该文件开始处理这个段落。因为是单词统计,很明显单词与单词之间主要分割标记就是空格,如果使用空格来分割段落文字,就可以将段落打散为一个个的单词列表了。不过同时看到段落中除了空格外,还有标点符号以及数字,这些也都需要去除。在整理好单词列表后,就可以使用map方式将所有单词与其出现的次数构建成<单词,次数>这种key-value结构对。

(3)然后使用reduce规约思想将这种结构对进一步处理,即将相同单词的次数累加,获得每个单词出现的频率。

根据思路我们来组织程序代码:

第一步,简单点,将新闻段落复制粘贴到记事本里,保存为news.txt文件。这个部分就不需要代码了。

第二步,python读这个文件,将段落读出来。这里定义个函数为readPara,即读取段落文字,函数参数为filename。定义完函数后就可以测试一下。

#定义一个读取段落文字的函数
def getPara(filename):with open(filename,'r') as f:content=f.readlines()return content#给定文本文件的位置
file="news.txt"
print(getPara(file))

测试结果返回一个列表,具体如下:

["CHENGDU -- Rescuers have located 14 miners trapped underground in a flooded coal mine in Southwest China's Sichuan province, local authorities said Sunday.n", 'The rescuers are clearing the shaft and drilling a deep hole to reach the trapped miners. They are also trying to pump and block water in a bid to prevent the rising of underground water levels and are sending more oxygen down the underground shaft.n', 'The accident occurred at 3:26 pm Saturday at the Shanmushu coal mine owned by Sichuan Coal Industry Group in Gongxian County when 347 miners were working underground. A total of 329 escaped and four were killed.n', 'Nearly 200 rescuers are racing against the clock to reach the trapped miners.n', 'Due to communication interruptions in some mining areas, the workers were not immediately located. But through their consistent efforts, the rescue workers have finally located the remaining miners。']

第三步,开始分割段落为单词。这里的任务包括去除其中的非单词字符,如标点符号和数字。

这个段落稍微有点复杂,那就是最后一个单词miners那有个中文的句号,需要先将其清除。清除的办法采用分割方法split函数:split('。')。分割后获得的为两个列表,这里只需要取第一个列表即可,因为第二个列表为标点符号句号。

for para in content:paraText=para.split('。')paraText=para[0]

然后在剩下的段落文本paraText中采用英文的句号继续分割:split('.'),形成多个句子的列表。

for para in content:paraText=para.split('。')paraText=para[0]paraList=paraText.split('.')

紧接着就可以将句子打散为单词了。不过其中还有一些换行符号和非英文单词字符,可以使用python自带的isalpha函数来判断,isalpha函数就是用于判断整个单词是否都是字母组成,如果判断为真,说明就是单词,如果不是,就说明不是单词。这样做问题都不大,不过在本次段落中出现了一个China's,被误杀了。这种连接拼写确实不是很好处理,这里也只能先舍弃掉。后面再想办法来处理。

打散后,然后将单词再一一的添加到一个新的列表中,这样形成整个段落的英文单词列表。所以可以先定义一个words_list空列表,然后后面使用append方法将打散的单词添加进去。

同时在单词处理的时候,大小写还是需要注意的,这里将所有大写都变成小写即可。使用方法就是单词作为字符串对象,使用其lower函数即可。

整个过程的代码组织如下:

def mapper(filename):words_list=[]                   #定义一个空列表with open(filename,'r') as f:   #打开段落所在的文本文件content=f.readlines()       #从头读到尾并保存到content列表中。默认会按段落分割for para in content:            #对每一个段落列表进行处理para=para.split('。')       #如果存在中文句号,将整个段落按句号分割,形成两个大的列表para0=para[0].split('.')    #取第一个列表,并使用英文句号分割,形成多个不含句号的文本列表for item in para0:          #对每一个文本列表进行处理words=item.split(' ')   #采用空格分割方式将文本列表打散为单词或者其他字符for word in words:      #对每个单词或其他字符组合进行判断if word.isalpha()==False:  #如果不是单词时continue               #就不执行下面的操作words_list.append(word.lower())    #将所有的英文单词变成小写后一个个添加到words_list列表中print(words_list)               #打印测试查看最终获得的单词列表

运行后结果如下:

['chengdu', 'rescuers', 'have', 'located', 'miners', 'trapped', 'underground', 'in', 'a', 'flooded', 'coal', 'mine', 'in', 'southwest', 'sichuan', 'local', 'authorities', 'said', 'sunday', 'the', 'rescuers', 'are', 'clearing', 'the', 'shaft', 'and', 'drilling', 'a', 'deep', 'hole', 'to', 'reach', 'the', 'trapped', 'miners', 'they', 'are', 'also', 'trying', 'to', 'pump', 'and', 'block', 'water', 'in', 'a', 'bid', 'to', 'prevent', 'the', 'rising', 'of', 'underground', 'water', 'levels', 'and', 'are', 'sending', 'more', 'oxygen', 'down', 'the', 'underground', 'shaft', 'the', 'accident', 'occurred', 'at', 'pm', 'saturday', 'at', 'the', 'shanmushu', 'coal', 'mine', 'owned', 'by', 'sichuan', 'coal', 'industry', 'group', 'in', 'gongxian', 'county', 'when', 'miners', 'were', 'working', 'underground', 'a', 'total', 'of', 'escaped', 'and', 'four', 'were', 'killed', 'nearly', 'rescuers', 'are', 'racing', 'against', 'the', 'clock', 'to', 'reach', 'the', 'trapped', 'miners', 'due', 'to', 'communication', 'interruptions', 'in', 'some', 'mining', 'the', 'workers', 'were', 'not', 'immediately', 'located', 'but', 'through', 'their', 'consistent', 'the', 'rescue', 'workers', 'have', 'finally', 'located', 'the', 'remaining', 'miners']

除了上述说的China's外,其他的单词都进入了列表。

第四步,开始统计单词出现的次数,处理的时候可以先定义个空字典,然后读取列表中的单词,如果在字典中已存在,则将其出现次数累加,如果不存在,则将其次数设定为1:

     for word in words_list:if word in words_dict:words_dict[word]+=1else:words_dict[word]=1

这里我们可以单独定义一个函数如reduce,其输入为第三步的单词列表。

def reduce(words):words_dict={}for word in words:if word in words_dict:words_dict[word]+=1else:words_dict[word]=1return words_dict 

将第三步的单词列表传入reduce函数,打印一下处理结果如下:

{'chengdu': 1, 'rescuers': 3, 'have': 2, 'located': 3, 'miners': 5, 'trapped': 3, 'underground': 4, 'in': 5, 'a': 4, 'flooded': 1, 'coal': 3, 'mine': 2, 'southwest': 1, 'sichuan': 2, 'local': 1, 'authorities': 1, 'said': 1, 'sunday': 1, 'the': 12, 'are': 4, 'clearing': 1, 'shaft': 2, 'and': 4, 'drilling': 1, 'deep': 1, 'hole': 1, 'to': 5, 'reach': 2, 'they': 1, 'also': 1, 'trying': 1, 'pump': 1, 'block': 1, 'water': 2, 'bid': 1, 'prevent': 1, 'rising': 1, 'of': 2, 'levels': 1, 'sending': 1, 'more': 1, 'oxygen': 1, 'down': 1, 'accident': 1, 'occurred': 1, 'at': 2, 'pm': 1, 'saturday': 1, 'shanmushu': 1, 'owned': 1, 'by': 1, 'industry': 1, 'group': 1, 'gongxian': 1, 'county': 1, 'when': 1, 'were': 3, 'working': 1, 'total': 1, 'escaped': 1, 'four': 1, 'killed': 1, 'nearly': 1, 'racing': 1, 'against': 1, 'clock': 1, 'due': 1, 'communication': 1, 'interruptions': 1, 'some': 1, 'mining': 1, 'workers': 2, 'not': 1, 'immediately': 1, 'but': 1, 'through': 1, 'their': 1, 'consistent': 1, 'rescue': 1, 'finally': 1, 'remaining': 1}

第五步,由此我们将每个单词出现的次数都统计了一下,最后需要对该字典按value方式排序,出现次数多的排列在前面,少的排列在后面,代码为:

def reduce(words):words_dict={}for word in words:if word in words_dict:words_dict[word]+=1else:words_dict[word]=1words_dict=sorted(words_dict.items(),key=lambda x:x[1],reverse=True)  #字典按value排序return dict(words_dict)    #排序后为元组列表,使用dict函数将其转换为字典

再来测试结果就得到了:

{'the': 12, 'miners': 5, 'in': 5, 'to': 5, 'underground': 4, 'a': 4, 'are': 4, 'and': 4, 'rescuers': 3, 'located': 3, 'trapped': 3, 'coal': 3, 'were': 3, 'have': 2, 'mine': 2, 'sichuan': 2, 'shaft': 2, 'reach': 2, 'water': 2, 'of': 2, 'at': 2, 'workers': 2, 'chengdu': 1, 'flooded': 1, 'southwest': 1, 'local': 1, 'authorities': 1, 'said': 1, 'sunday': 1, 'clearing': 1, 'drilling': 1, 'deep': 1, 'hole': 1, 'they': 1, 'also': 1, 'trying': 1, 'pump': 1, 'block': 1, 'bid': 1, 'prevent': 1, 'rising': 1, 'levels': 1, 'sending': 1, 'more': 1, 'oxygen': 1, 'down': 1, 'accident': 1, 'occurred': 1, 'pm': 1, 'saturday': 1, 'shanmushu': 1, 'owned': 1, 'by': 1, 'industry': 1, 'group': 1, 'gongxian': 1, 'county': 1, 'when': 1, 'working': 1, 'total': 1, 'escaped': 1, 'four': 1, 'killed': 1, 'nearly': 1, 'racing': 1, 'against': 1, 'clock': 1, 'due': 1, 'communication': 1, 'interruptions': 1, 'some': 1, 'mining': 1, 'not': 1, 'immediately': 1, 'but': 1, 'through': 1, 'their': 1, 'consistent': 1, 'rescue': 1, 'finally': 1, 'remaining': 1}

上述五步整个代码完整组织如下:

def mapper(filename):words_list=[]with open(filename,'r') as f:content=f.readlines()for para in content:para=para.split('。')para0=para[0].split('.')for item in para0:words=item.split(' ')for word in words:if word.isalpha()==False:continuewords_list.append(word.lower())return words_listdef reduce(words):words_dict={}for word in words:if word in words_dict:words_dict[word]+=1else:words_dict[word]=1words_dict=sorted(words_dict.items(),key=lambda x:x[1],reverse=True)return dict(words_dict)filename="new.txt"     #文件资源位置
wordlist=mapper(filename)   #获取单词列表
wordCount=reduce(wordlist)  #对词频进行统计
print(wordCount)   #打印结果

上述过程就是单文件词频统计,在段落中出现次数最多的是the单词,这个对于段落内容理解没有意义,第二多的是miners、in 和to,这个miners应该是有意义的,in和to也是没有意义的单词。第三多的是underground,a,are和and,这里underground也是有意义的,后两个都没有意义。所以从前面排序结果来看,大概可以知道这个段落里讲的是underground miners,也就是地下挖矿的人,和他们有关。如果进一步往下看的话,出现两次的单词里基本上都把整个段落的内容概括了。

由此可以将没有意义,但出现频率很高的单词过滤掉,这类词在NLP自然语言处理里称之为stop words终止词,过滤的时候在上述代码中循环处理添加进列表的时候就可以判断,如果是终止词,就不添加,即:

def mapper(filename):words_list=[]list_stopWords=['the','a','and','or','is', 'are','to','in','at','by','of','but']#常见终止词列表with open(filename,'r') as f:content=f.readlines()for para in content:para=para.split('。')para0=para[0].split('.')for item in para0:words=item.split(' ')for word in words:if word.isalpha()==False:continueif word in list_stopWords: continue           #过滤终止词words_list.append(word.lower()) return words_list

再来看词频统计结果:

'miners': 5, 'underground': 4, 'rescuers': 3, 'located': 3, 'trapped': 3, 'coal': 3, 'were': 3, 'have': 2, 'mine': 2, 'sichuan': 2, 'the': 2, 'shaft': 2, 'reach': 2, 'water': 2, 'workers': 2, 'chengdu': 1, 'flooded': 1, 'southwest': 1, 'local': 1, 'authorities': 1, 'said': 1, 'sunday': 1, 'clearing': 1, 'drilling': 1, 'deep': 1, 'hole': 1, 'they': 1, 'also': 1, 'trying': 1, 'pump': 1, 'block': 1, 'bid': 1, 'prevent': 1, 'rising': 1, 'levels': 1, 'sending': 1, 'more': 1, 'oxygen': 1, 'down': 1, 'accident': 1, 'occurred': 1, 'pm': 1, 'saturday': 1, 'shanmushu': 1, 'owned': 1, 'industry':1

这样再来看,就明白了这个新闻里说的就是,四川挖煤矿的工人被困在井下,救援者进行施救。所以词频统计对理解段落含义很有意义。

最后再来一个词云展示,也就是将上述词频统计里出现的词用一种图来表示出来,比较直观。具体实现的时候需要先安装一个wordcloud词云第三方库,matplotlib绘图库,然后先设置绘图背景,然后将词频统计结果放置到背景上呈现效果。整个代码组织如下:

from wordcloud import WordCloud, STOPWORDS  #生成词云、通用词
import matplotlib.pyplot as plt  # 在线显示def mapper(filename):words_list=[]list_stopWords=['the','a','and','or','is', 'are','to','in','at','by','of','but']#常见终止词列表with open(filename,'r') as f:content=f.readlines()for para in content:para=para.split('。')para0=para[0].split('.')for item in para0:words=item.split(' ')for word in words:if word.isalpha()==False:continueif word in list_stopWords: continue           #过滤终止词words_list.append(word.lower()) return words_listdef reduce(words):words_dict={}for word in words:if word in words_dict:words_dict[word]+=1else:words_dict[word]=1words_dict=sorted(words_dict.items(),key=lambda x:x[1],reverse=True)return dict(words_dict)filename="new.txt"     #文件资源位置
wordlist=mapper(filename)   #获取单词列表
wordCount=reduce(wordlist)  #对词频进行统计#准备绘制词云图
wc = WordCloud(background_color="white",width=600, height=400, margin=5)  #准备一个背景
wc.generate_from_frequencies(wordCount)                                  #根据词频统计结果产生词云
plt.imshow(wc)                            #显示出来
plt.axis("off")
plt.show()

执行后效果如下:

25db3550e33f5146baaa793ad0e4f0f3.png

词频统计思路就是如上分步骤所述,但具体到每篇文章,由于文章的格式、标准等都不一样,所以还需要具体问题去分析,需要哪些步骤来实现。

上述的词频统计是自然语言处理的一个最基本阶段,即Tokenization标识化。这部分任务在nltk自然语言处理库里调用其word_tokenize方法就可以完成。用法为:

import nltk
text="I love China and I was born in Hubei Province"
tokens=nltk.word_tokenize(text)
print(tokens)

另外还可以使用python自带的collections库里的counter函数,直接获得词频统计结果。我们上述的代码实际上就是将这个词频统计Counter函数进行了详细解析。例如:

import collections 
text = "I love China and I was born in Hubei Province"
words=collections.Counter(text.split(' '))
print(words)

打印结果为:

Counter({'I': 2, 'love': 1, 'China': 1, 'and': 1, 'was': 1, 'born': 1, 'in': 1, 'Hubei': 1, 'Province': 1})

10行代码读懂红楼梦

中文文章词频统计任务相对英文要稍微复杂一些,因为英文单词与单词之间天然就用空格空隔开,所以很容易处理;但中文就不一样了,一段中文话里每个字与每个字之间没有天然的分割标记,而且还有含义的理解。比如“我看他们在跳舞”这句话,“我”是一个词,“看”是一个词,“他们”是一个词,“在”是一个词,“跳舞”是一个词。也就是一个词可能是一个字,也有可能是多个字构成。这样在处理的时候就麻烦了。如何确定是一个词语呢?

这里就需要引入前人所做的工作,把所有词语都统计好了,形成一个字典库,名称叫结巴分词,直接从cmd窗口使用pip install jieba命令就可以下载到本地:

pip install jieba

为了了解结巴分词模块的用法,可以去python安装目录下找到site-packages里的jieba文件夹,如下:

9697a293e7b6e1f587436172e6a77dc9.png

使用文本编辑器打开其中的_init_.py文件,查看其源代码,定位其中常用的cut方法,即分词方法。

 def cut(self, sentence, cut_all=False, HMM=True):'''The main function that segments an entire sentence that containsChinese characters into seperated words.Parameter:- sentence: The str(unicode) to be segmented.- cut_all: Model type. True for full pattern, False for accurate pattern.- HMM: Whether to use the Hidden Markov Model.'''sentence = strdecode(sentence)if cut_all:re_han = re_han_cut_allre_skip = re_skip_cut_allelse:re_han = re_han_defaultre_skip = re_skip_defaultif cut_all:cut_block = self.__cut_allelif HMM:cut_block = self.__cut_DAGelse:cut_block = self.__cut_DAG_NO_HMMblocks = re_han.split(sentence)for blk in blocks:if not blk:continueif re_han.match(blk):for word in cut_block(blk):yield wordelse:tmp = re_skip.split(blk)for x in tmp:if re_skip.match(x):yield xelif not cut_all:for xx in x:yield xxelse:yield xdef cut_for_search(self, sentence, HMM=True):"""Finer segmentation for search engines."""words = self.cut(sentence, HMM=HMM)for w in words:if len(w) > 2:for i in xrange(len(w) - 1):gram2 = w[i:i + 2]if self.FREQ.get(gram2):yield gram2if len(w) > 3:for i in xrange(len(w) - 2):gram3 = w[i:i + 3]if self.FREQ.get(gram3):yield gram3yield w

代码中有关cut方法的参数说明:cut_all: 如果设置为true则为全模式分词,如果为false,就为精确分词,如果使用HMM就使用隐层马尔科夫模型。具体效果如何,使用代码来实践看看:

import jieba
text="我在看他们跳舞,我心里高兴得不得了。有时候我也想也许我也可以这样随便跳起舞来"
#设置参数cut_all=True,即全模式分词
word_sep1=list(jieba.cut(text,cut_all=True))
print("全模式分词效果为:",word_sep1)
#设置参数cut_all=False,即精确模式分词
word_sep2=list(jieba.cut(text,cut_all=False))
print("精确模式分词效果为:",word_sep2)

运行后结果返回列表结果如下:

全模式分词效果为 :['我', '在', '看', '他们', '跳舞', '', '', '我心', '心里', '高兴', '得', '不得', '不得了', '', '', '有时', '有时候', '时候', '我', '也', '想', '也许', '我', '也', '可以', '这样', '随便', '跳起', '起舞', '来']

精确模式分词效果为: ['我', '在', '看', '他们', '跳舞', ',', '我', '心里', '高兴', '得', '不得了', '。', '有时候', '我', '也', '想', '也许', '我', '也', '可以', '这样', '随便', '跳', '起舞', '来']

对比而言,精确分词更为准确,全模式分词还有词的联想效果。

有了这个非常好用的分词方法,那对于大段中文文章的词频统计过程就与上述的英文文章类似了。也是分:首先分词处理,获得词语的列表,然后进行map操作,构建字典,每个词语出现过,就给次数1,最后再进行reduce操作,将相同词语出现的次数相加,获得出现频率结果。

下面我对红楼梦相关章节进行分词处理。这个难度还是比较大的,主要是红楼梦属于古典小说,有许多文言文表达,而不是白话文。所以分词效果并不是非常准确。不过对于练习已经足够有吸引力了。

第一步,从网上下载红楼梦小说txt文本,保存成一个文本文件。

efac0fd98abdf03210d2c0b1f87e5a75.png

第二步,开始在python中编写代码,首先读取这个文本文件,获得红楼梦中文文本。并使用分词结果构建一个字典,字典内容为<词语,次数1>。由于全部回数的文本很长,在练习时可以选择其中一部分来进行测试。代码参考如下:

import jieba#定义函数mapper,用于构建字典
def mapper(file):word_sep=[]word_map={}punctuation=['?','!',',','。',';',':','“','”','n','u3000','(',')']stopwords=["之","的","一","他","她","我","我们","可以","你","里","去","来","那","在","上","下"]with open(file,'r') as f:text=f.readlines()    for i in range(50):words=list(jieba.cut(text[i],cut_all=False))for word in words:if word in punctuation:continue   #去除标点符号if word in stopwords:continue     #去除终止词word_sep.append(word)for word in word_sep:word_map[word]=1return word_map#主函数
if __name__=="__main__":file='红楼梦.txt'print(mapper(file))

在这一步中使用了标点符号和终止词,当分词后的字符是标点符号和终止词时,就不加入字典。不过这里终止词是我自己构建的列表,内容相对较少。这块可以自行增加。

运行上述代码后就可以获得如下结果(这里受限篇幅仅显示部分结果):

{'甄士隐': 1, '梦幻': 1, '识通灵': 1, '贾雨村': 1, '风尘': 1, '怀': 1, '闺秀': 1, '1': 1, '列位': 1, '看官': 1, '道': 1, '此书': 1, '从何而来': 1, '说起': 1, '根由': 1, '虽近': 1, '荒唐': 1, '细': 1, '按': 1, '则': 1, '深有': 1, '趣味': 1, '待': 1, '将': 1, '此': 1, '来历': 1, '注明': 1, '方使': 1, '阅者': 1, '了然': 1, '不惑': 1, '原来': 1, '女娲': 1, '氏': 1, '炼石补天': 1, '时': 1, '于': 1, '大': 1, '荒山': 1, '无稽': 1, '崖': 1, '炼成': 1, '高经': 1, '十二': 1, '丈': 1, '、': 1, '方经': 1, '二十四丈': 1, '顽石': 1, '三万': 1, '六千五百': 1, '零': 1, '一块': 1, '娲': 1, '皇氏': 1, '只用': 1, '了': 1, '块': 1, '只': 1, '单单': 1, '剩': 1, '未': 1, '用': 1, '便弃': 1, '此山': 1, '青埂峰': 1, '谁知': 1, '此石': 1, '自经': 1, '煅炼': 1, '之后': 1, '灵性': 1, '已通': 1, '因见': 1, '众': 1, '石俱得': 1, '补天': 1, '独': 1, '自己': 1, '无材': 1, '不堪': 1, '入选': 1, '遂': 1, '自怨': 1, '自叹': 1, '日夜': 1, '悲号': 1, '惭愧': 1, '一日': 1, '正当': 1, '嗟悼': 1, '之际': 1, '俄见': 1, '一僧': 1, '一道': 1, '远远': 1, '而': 1, '生得': 1, '骨格': 1, '不凡': 1, '丰神': 1, '迥别': 1, '说说笑笑': 1, '至峰': 1, '坐于': 1, '石边': 1, '高谈': 1, '快论': 1, '先是': 1, '说些': 1, '云山': 1, '雾海': 1, '神仙': 1, '玄幻': 1, '之事': 1, '后': 1, '便': 1, '说': 1, '到': 1, '红尘': 1, '中': 1, '荣华富贵': 1, '听': 1, '不觉': 1, '打动': 1, '凡心': 1, '也': 1, '想要': 1, '人间': 1, '享一享': 1, '这': 1, '但': 1, '自恨': 1, '粗蠢': 1, '不得已': 1}

第三步,有了上述的词语字典后,就可以进行词频统计了。此时增加一个reducer函数,专门用于处理统计。

def reducer(word_dict):word_freq={}for key in word_dict:        if key in word_freq:word_freq[key]+=1            else:word_freq[key]=1word_freq=sorted(word_freq.items(),key=lambda x:x[1],reverse=True)return dict(word_freq) 

输出词频统计结果,如下示例:

文字出现的频率为: {'道': 8, '弟子': 6, '一块': 4, '便': 4, '到': 4, '红尘': 4, '听': 4, '不知': 4, '补天': 3, '说': 3, '不能': 3, '却': 3, '如此': 3, '自然': 3, '则': 2, '将': 2, '此': 2, '不惑': 2, '原来': 2, '时': 2, '荒山': 2, '无稽': 2, '崖': 2, '三万': 2, '六千五百': 2, '只': 2, '青埂峰': 2, '此石': 2, '无材': 2, '一日': 2, '一僧': 2, '一道': 2, '而': 2, '荣华富贵': 2, '凡心': 2, '但': 2, '粗蠢': 2, '繁华': 2, '富贵': 2, '善哉': 2, '好': 2, '这石': 2, '再': 2, '那僧': 2, '助': 2, '还': 2, '石头': 2, '个': 2, '携': 2, '空空': 2, '道人': 2, '甄士隐': 1, '梦幻': 1, '识通灵': 1, '贾雨村': 1, '风尘': 1, '怀': 1, '闺秀': 1, '1': 1, '列位': 1, '看官': 1, '此书': 1, '从何而来': 1, '说起': 1, '根由': 1, '虽近': 1, '荒唐': 1, '细': 1, '按': 1, '深有': 1, '趣味': 1, '待': 1, '来历': 1, '注明': 1, '方使': 1, '阅者': 1, '了然': 1, '女娲': 1, '氏': 1, '炼石补天': 1, '于': 1, '大': 1, '炼成': 1, '高经': 1, '十二': 1, '丈': 1, '方经': 1, '二十四丈': 1, '顽石': 1, '零': 1, '娲': 1, '皇氏': 1, '只用': 1, '块': 1, '单单': 1, '剩': 1, '未': 1, '用': 1, '便弃': 1, '此山': 1, '谁知': 1, '自经': 1, '煅炼': 1, '之后': 1, '灵性': 1, '已通': 1, '因见': 1, '众': 1, '石俱得': 1, '独': 1, '自己': 1, '不堪': 1, '入选': 1, '遂': 1, '自怨': 1, '自叹': 1, '日夜': 1, '悲号': 1, '惭愧':1}

细看统计结果,里面出现许多一个字的词语,一般情况下中文单个文字表达的意思还是很有限的,多以词组的形式来表示含义。因此需要将单个文字从词语统计中剔除。

另外为了统计结果更直观,代码中也增加词云库,使用词云来显示词频统计的结果。词云显示的时候由于是汉字,所以需要增加汉字字库。即给定font_path,代码中直接调用windows系统的字体库中的宋体。

wc = WordCloud(background_color="white",width=600, height=400, margin=5,font_path="C:/Windows/Fonts/simsun.ttc")  

将上述三步合起来,代码整体组织如下:

import jieba
from wordcloud import WordCloud, STOPWORDS  #生成词云、通用词
import matplotlib.pyplot as plt  # 在线显示#定义函数mapper,用于构建词语列表
def mapper(file):word_sep=[]word_map={}punctuation=['?','!',',','。',';',':','“','”','’','‘','n','u3000','(',')','、']stopwords=["之","的","一","他","她","我","我们","可以","你","里","去","来","那","在","上","下","了","又","是","这","着","也","人",'不','有']with open(file,'r') as f:text=f.readlines()    for i in range(50):                      #取前50列表测试words=list(jieba.cut(text[i],cut_all=False))   #结巴分词for word in words:if word in punctuation:continue         #去除标点符号if word in stopwords:continue           #去除终止词if len(word)<2:continue                 #去除单个字word_sep.append(word)                   #将分好的词语添加到空列表return word_sep#定义函数,用于词频统计
def reducer(word_dict):word_freq={}for key in word_dict:        if key in word_freq:word_freq[key]+=1            else:word_freq[key]=1word_freq=sorted(word_freq.items(),key=lambda x:x[1],reverse=True)return dict(word_freq)       #主函数
if __name__=="__main__":file='红楼梦.txt'word_dict=mapper(file)    word_freq=reducer(word_dict)#print("文字出现的频率为:",word_freq)wc = WordCloud(background_color="white",width=600, height=400, margin=5,font_path="C:/Windows/Fonts/simsun.ttc")wc.generate_from_frequencies(word_freq)plt.imshow(wc)plt.axis("off")plt.show()

运行程序,获得如下词云图:

f9ad255f20cabbce90e02af6144b8f48.png

这个图云是对前几回的文本进行的统计,所以里面出现了雨村、士隐、道人、封肃、丫鬟、那僧、世人、弟子等较高出现的词语,基本上能够概括前几回的主要人物和事情。

如果把全部红楼梦的文字都拿进来,最后的词云图如下(效果与选择终止词有关):

f1feded6f46a9f850ffb04e45ebce6c6.png

再来对比整个红楼梦,这张词云图上出现的就是宝玉、贾母、王夫人、凤姐、姑娘、奶奶、黛玉、袭人、宝钗等红楼梦核心人物。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/534071.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

k8s 安装nfs_K8s--06 K8s数据持久化

K8s数据持久化数据持久化 Volume介绍Volume介绍&#xff1a;Volume是Pad中能够被多个容器访问的共享目录Kubernetes中的Volume不Pad生命周期相同&#xff0c;但不容器的生命周期丌相关Kubernetes支持多种类型的Volume&#xff0c;并且一个Pod可以同时使用任意多个VolumeVolume类…

matlab为自定义后缀文件设置图标_【V3.0更新】| 这可能是全网最好用的文件管理神器了......

?点击关注Excel表哥公众号使用Excel制作自带超链接的文件目录索引确实可以很好地帮忙大家管理电脑里的文件。在此分享几个各行各业朋友们的使用截图&#xff1a;▲一个硬件工程师朋友的使用截图▲一个医院工作人员的数据统计文件管理▲学生朋友用来管理论文文献▲VBA编程爱好者…

#中队列的数据结构_数据结构与算法拓展(一)

栈与队列申明&#xff1a;由于篇幅限制&#xff0c;文章可能有些简略&#xff0c;如果大家想要详细了解&#xff0c;请一定要百度一下&#xff0c;并阅读例题&#xff0c;完成习题绪言&#xff1a;计算机科学在过去的数十年内发展飞速&#xff0c;各种新颖的技术纷至沓来&#…

display属性_Numpy知识点(1)讲解实操安装/属性/数组创建/运算

# 1、安装包# pip install numpy #原生python安装# conda install numpy #Anaconda的安装# 使用Numpyimport numpy as np a np.arange(15) #生成0-14的一维数组display(a)display( )和print( )都是打印,在大多数编程软件上都使用print,jupyter notebook中我们可以使用d…

springboot怎么设置多个路径全部跳转首页_SpringBoot(四)—Web开发(二)

这篇文章准备来记录一下一个restful风格小项目的流程&#xff0c;上篇文章为它做了一个基础&#xff0c;如果有什么错误希望大家能够指出。目录首页国际化登录拦截器CRUD一、首页在访问localhost:8080/的时候&#xff0c;默认访问首页在自己配置的SpringMVC的配置类中Configura…

计算机英语六级,英语六级作文范文:计算机

英语六级考试时间越来越近了&#xff0c;所以在备考的时候就更要掌握技巧&#xff0c;勤加练习。在备考英语六级写作时&#xff0c;学习一篇好的范文&#xff0c;会给复习带来事半功倍的效果。Using a computer every day can have more negative than positive effects on you…

python软件_Python自制照片美颜软件~

下午被一个骗子恶心到了&#xff0c;本来听公开课听得好好的&#xff0c;搞得心情极差&#xff0c;于是就中断了网课&#xff0c;听听音乐&#xff0c;写一下文章吧&#xff01;前期准备①Python编译环境以及Python代码编辑器Pycharm的安装&#xff1a;请在【微信公众后台】找到…

数据集怎么导出_PCA算法 | 数据集特征数量太多怎么办?用这个算法对它降维打击...

今天是机器学习专题的第27文章&#xff0c;我们一起来聊聊数据处理领域的降维(dimensionality reduction)算法。我们都知道&#xff0c;图片格式当中有一种叫做svg&#xff0c;这种格式的图片无论我们将它放大多少倍&#xff0c;也不会失真更不会出现边缘模糊的情况。原因也很简…

常用命令_GIT常用命令大全

Git 是一个很强大的分布式版本控制系统。它不但适用于管理大型开源软件的源代码&#xff0c;管理私人的文档和源代码也有很多优势。克隆远程文件&#xff1a;git clone https://gitee.com/abcd/codefile.git projectgit checkout -b dev(本地分支名称) origin/dev(远程分支名称…

nvidia显示设置不可用_Nvidia显示设置不可用,您当前未使用连接到NVIDIA GPU的显示器的解决方法...

相信不少用户遇到这样一个问题&#xff0c;就是新购买的台式机电脑&#xff0c;配置达标的情况下&#xff0c;玩游戏出现卡顿不流畅的现象&#xff0c;准备在NVIDIA控制面板查看是否设置的问题&#xff0c;在打开NVIDIA控制面板的时候&#xff0c;提示了“Nvidia显示设置不可用…

oracle tns 代理配置_Toad for oracle安装配置与使用

一.toad安装与配置注意:toad的使用本机电脑必须安装完整版oracle客户端,不能是精简版的.1.1完整版oracle客户端的安装.1.解压文件&#xff0c;安装oracle客户端打开安装包&#xff0c;找到setup.ext&#xff0c;开始安装。提示下图弹窗,可根据此网址内容进行更改(https://blog.…

吴枫 python小课账号_无门槛速学编程——Python小短课,自上而下分而治之

【Python小短课 11】自上而下&#xff0c;分而治之 做任何事都需计划&#xff0c;编程也是。 譬如写文章要列大纲、作画要想布局&#xff0c;编程也需先谋全局&#xff0c;而后思虑细节。 就以上回说到的“找宝藏”这个程序举例&#xff0c;最顶层的需求自然就是“找宝藏”&…

计算机本地磁盘D无法扩展,计算机上的本地磁盘D突然无法打开,表明它需要格式化...

接受使用数据恢复软件将重要数据保存到其他磁盘FindDate特定操作: 运行软件----“打开”后&#xff0c;将显示要还原的驱动器. C \ D \ E \ F选择您要还原的一个&#xff0c;它将开始. 扫描后&#xff0c;再次保存扫描的文件. 哈哈&#xff0c;希望对您有所帮助.最后&#xff0…

caffe运行不停止_caffe(gpu)安装过程及问题解决

2019.12.05 caffe(gpu)安装参考网址&#xff1a;教程1&#xff1a;weiliu89/caffe​github.com教程2&#xff1a;https://blog.csdn.net/yggaoeecs/article/details/79163789​blog.csdn.net环境&#xff1a;Ubuntu16.04cuda10.0安装过程&#xff1a;git clone https://github.…

2021年考计算机考研三战,2021考研的小伙伴有3条忠告一定要记得,这些都是历年实战经验...

2021考研的小伙伴有3条忠告一定要记得&#xff0c;这些都是历年实战经验&#xff0c;考研一定要记得避开三个大坑。1&#xff0c;分数线低的学校就一定容易考。有一些学校分数线看着很低但实际上难度不低&#xff0c;比如首都师范大学 &#xff0c;很多专业就是国家线录取甚至招…

c++ 返回string_JVM系列之:String.intern和stringTable

简介StringTable是什么&#xff1f;它和String.intern有什么关系呢&#xff1f;在字符串对象的创建过程中&#xff0c;StringTable有起到了什么作用呢&#xff1f;一切的答案都在本文中&#xff0c;快来看看吧。intern简介intern是String类中的一个native方法&#xff0c;所以它…

华为 虚拟键盘_华为mate30 pro虚拟机械键盘特有体验,虽是虚拟,但却感受逼真...

华为Mate30 pro已于26日在国内正式发布了。此外&#xff0c;根据了解华为Mate30系列现在已经突破了5亿的销售额。看来&#xff0c;华为的这个下半年旗舰手机非常受欢迎啊。华为Mate30系列现在在国内已经发布了&#xff0c;其整体感官看上去与海外的没有多大的区别。其实&#x…

计算机有什么著名基金经理排名,百万年薪的基金经理,都是什么专业出身?!...

有人会说了“小哔君你四不四撒&#xff01;基金经理肯定是金融专业出身的咯&#xff1f;不然嘞&#xff1f;”但事实的真相是许多基金经理都并非科班出身这要从基金经理的晋升机制说起了&#xff01;如下图基金经理都是从研究员做起的&#xff01;那么问题来了&#xff0c;如何…

遍历children_589. N叉树的前序遍历

589. N叉树的前序遍历给定一个 N 叉树&#xff0c;返回其节点值的前序遍历。例如&#xff0c;给定一个 3叉树 :返回其前序遍历: [1,3,5,6,2,4]。说明: 递归法很简单&#xff0c;你可以使用迭代法完成此题吗?题解&#xff1a;既然是树的遍历&#xff0c;那么一共就是两种思路&a…

计算机未显示移动硬盘,电脑不显示移动硬盘怎么办_移动硬盘已连接不显示解决教程...

最近有很多小伙伴咨询小编&#xff0c;电脑不显示移动硬盘怎么办&#xff0c;怎么设置才能恢复呢&#xff1f;其实操作内容很简单&#xff0c;尝试删除你的USB3.0可扩展主机控制器,再扫描硬件改动&#xff0c;今天就由小编来告诉你&#xff0c;移动硬盘已连接不显示的解决方法。…