原文连接:Hzy 博客
今天试试对数据进行一些简单的处理,然后可视化出来,于是我就想到对出现过的动漫进行一些粗略的统计,然后根据词语频率
来输出成词云!
先看下效果图
代码的在我的GitHub上,里面放了一些在学习go过程中一些小项目。
跟着昨天来,昨天把知乎山的回答抓取了下来,放到了一个文件中。
- 首页要从文件中一行一行的读取(每一行就是一个回答)。
- 读取出来的句子,还得进行一些简单的分割,比如就只提取书名号中的动漫。(ps:当然还可以用其他语言分析的库,想python中的jieba,但我在go中好像没有发现类似的库),那就只要自己动手写个简单的啦。
- 提取出动漫并且统计后,我们就要进行可视化啦,我在github上发现了
go-echarts
2.go-charts简单介绍
安装
1
go get -u github.com/go-echarts/go-echarts
文档:https://go-echarts.github.io/go-echarts/
go-ehcharts 用的是百度开源的echarts图表库,并提供了简洁的api。
3.准备的都好啦,下面就是打代码的时间啦
3.1 首先是打开文件,然后读取其中的每一行,然后分割找到动漫名称,然后统计。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
单词统计
*/
//这个结构体时为了实现sort接口使用的,因为map如果按照value不好排序。
type Pair struct {
Key string
Value int
}
type PairList []Pair
func (p PairList) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p PairList) Len() int { return len(p) }
func (p PairList) Less(i, j int) bool { return p[j].Value < p[i].Value } // 逆序
type WordCount map[string]interface{}
//遇到以下符号,对句子进行分割
func SplitByMoreStr(r rune) bool{
splitSymbol := []rune("《》<>")
for _,v:=range(splitSymbol){
if r == v{
return true
}
}
return false
}
// 这里切割读取的行,并简单的统计
func (wc WordCount)SplitAndStatistics(s string){
dist1 := strings.FieldsFunc(s,SplitByMoreStr)
for _,v :=range(dist1){
flag :=0
v = strings.Replace(v," ","",-1)
for key :=range wc {
if strings.Index(v,key)!=-1{ //新的字段中包含了map中曾经出现过的字段,则直接+1
wc[key]=wc[key].(int)+1
flag =1
}
}
if flag==0{
if wc[v]==nil{
wc[v] =1
}else{
wc[v]=wc[v].(int)+1
}
}
//fmt.Println(v)
}
}
// 读取文件的每一行,并进行统计
func (wc WordCount)ReadFile(f *os.File){
rd := bufio.NewReader(f)
for{
line, err := rd.ReadString('\n') //以'\n'为结束符读入一行
if err != nil || io.EOF == err {
break
}
wc.SplitAndStatistics(line)//切割并统计
}
}
//这个函数用来排序,展示结果,但没有用到。
func(wc WordCount)AnalysisResut(){
//将map[string][int] 转成struct 实现sort接口实现排序功能
pl :=make(PairList,len(wc))
i:=0
for k,v :=range(wc){
pl[i] = Pair{k,v.(int)}
i++
}
sort.Sort(pl)
for _,pair :=range(pl){
fmt.Println(pair.Value,pair.Key)
}
}
3.42 切割完后,我们就要输出成词云才算完事。
安装了上面的库,就可以啦。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//路由,输出词云
func handler(w http.ResponseWriter, _ *http.Request) {
nwc := charts.NewWordCloud()
nwc.SetGlobalOptions(charts.TitleOpts{Title: "知乎问题:"})
wc :=make(wordCount.WordCount)
f, err := os.Open(wordCount.Path+"answer.txt")
if err!=nil{
panic(err)
}
defer f.Close()
wc.ReadFile(f)
nwc.Add("wordcloud", wc, charts.WordCloudOpts{SizeRange: []float32{14, 250}})
nwc.Render(w)
}
// 判断文件是否存在
func Exists(path string) bool {
_, err := os.Stat(path) //os.Stat获取文件信息
if err != nil {
if os.IsExist(err) {
return true
}
return false
}
return true
}
func main(){
if !Exists(wordCount.Path+"answer.txt"){
wordCount.QuestionAnswer()
}
http.HandleFunc("/", handler)
http.ListenAndServe(":8081", nil)
}