实现在 文本中 查询字段出现次数 并作图

数据可视化的题目

    需求是说,在一个小说的 txt文件中,查询下面 characers 中,这些 人名 出现次数,并保存在 data.csv 中

    然后,利用收集到的信息 做出 折线图,用 出场最多的5个人的次数 做出饼图。。

    搜索数据,并记录

    首先呢,需要去文本中 查询字段出现次数。

    查询次数的话,就是用 with open("赘婿.txt","r",encoding="utf-8"),打开 赘婿.txt文件,后面的 r 参数代表 访问形式是 读取,最后的 encoding是说 编码方式为 utf-8。

    玩过别的语言的单机游戏的话,相信都碰到过需要改文件编码方式(虽然我忘了在哪碰到过)。中文的编码 貌似有很多种,utf-8 就是一种。

    打开了文件以后呢,我们需要去读取内容对吧?将所有内容 赋值给 content,然后我们 利用 for 的特性,一行一行的方式读取(其实,把文本框拉长会发现,每一段其实算一行,而人物名字明显不会说 从中间截断)。

    使用 .strip(),将 每一行中 前后的空格删去(其实在这里 删不删没啥区别)

    后面 如果是空行,则直接跳过。

    最后就是 对比名字是否出现啦!我的思路是,遍历到每一个字的时候,让这个字和后面一个 或 两个 ,一起与 字典中 人物名字对比。如果匹配 则记录+1。(搜索会很慢,python还不太熟悉,不太会改 哈哈哈)

    上面这些结束后,就完成了 人名出现次数的记录。这时候 characers 中 保存着所有的信息。

characers = {'苏檀儿': 0, '宁毅': 0, '刘西瓜': 0, '秦嗣源': 0, '陆红提': 0, '苏仲堪': 0, '苏文兴': 0, '苏伯庸': 0, '耿护院': 0, '元锦儿': 0, '宋宪': 0,

            '陈凡': 0}

with open("赘婿.txt", "r", encoding="utf-8") as fr:

    content = fr.read()

    # 依次迭代所有⾏

    for line in content:

        # 去除空格

        line = line.strip()

        # 如果是空⾏,则跳过

        if len(line) == 0:

            continue

        # 统计每⼀字出现的个数

        for x in range(0, len(line)):

            for y in characers:

                if line[x:x + 2] == y[0] or line[x:x + 3] == y[0]:

                    characers[y] += 1


导出数据至 data.csv

第二步,我们需要去将 characer 中的数据 导入到 csv文件中。

还是一样,首先先用 with open("data.csv", "w")  以写入形式打开文件,并且用 csv_file 代替访问。

使用csv中自带函数 csv.DictWriter(目标文件,列名) ,并且使用 .writeheader(),将其写入。

后面就是将 characer 变为列表,然后用 for 和 csv_writer.writerow() 将其中 人名和次数 分行写在 “人名”和“次数”下面。


with open("data.csv", "w") as csv_file:

    csv_writer = csv.DictWriter(csv_file, fieldnames=['人名', '次数'])

    csv_writer.writeheader()

    key = list(characers.keys())

    value = list(characers.values())

    for i in range(len(key)):

        dic = {  # 字典类型

            '人名': key[i],

            '次数': value[i]

        }

        csv_writer.writerow(dic)


折线图

第三步就是 读取 data.csv 中数据,将其作成折线图

为了避免后续 饼图中 使用 characers 的数据(不想每次都去重新算 出现了多少次),声明 characters 字典,在下方循环的时候 将data.csv数据 copy

和前面一样,首先打开文件,将其指针赋值给f,然后读取文件,将其中的值 赋给 reader。

然后读取第一行,将其值 赋给 header_row(算是列名)

新建两个列表,分别保存 csv中 人名 和 次数。这里做个条件判断,如果说 这一行是空行,就直接跳过。(不知道为啥,我打开的时候发现,导入一个数据,他就空一行)

这个 for 做完,就有了所有数据。


利用 plt.plot(横坐标,纵坐标,color,)  定义折线图的 横纵坐标,线的颜色

plt.title("标题",fontsize(字体大小))

plt.xlabel('横坐标显示的文字',fontsize(字体大小))

同理 plt.ylabel 设置纵坐标显示的文字。

最后 plt.show() 即可显示出 图


characters = {}

with open("./data.csv") as f:

    reader = csv.reader(f)

    header_row = next(reader)

    names, times = [], []

    for row in reader:

        if len(row)>1:

            name = row[0]

            time = int(row[1])

            names.append(name)

            times.append(time)

    plt.plot(names, times, c='red', alpha=0.3)

    # plt.fill_between(dates, highs, lows, facecolor='blue', alpha=0.05)

    title = "人物出现次数折线图 "

    plt.title(title, fontsize=24)

    plt.xlabel('name', fontsize=16)

    plt.ylabel('times', fontsize=16)

    plt.show()


饼图

和前面一样,不过因为说,需要数量上为 前五的人,所以需要对数据进行一次排序。

这边的思路是,利用前面新建的 character 字典的数据,排序成 列表形式,采用倒序。

最后把 人名和次数 分别放在 names 和 indexs中

后面就是 画图 .pie(数据,数据对应的标签,数据形式)


n = 5

L = sorted(characers.items(), key=lambda item: item[1], reverse=True)

L = L[:n]

names = []

indexs = []

for name, index in L:

    names.append(name)

    indexs.append(index)

fig = plt.figure()

plt.pie(indexs, labels=names, autopct='%1.2f%%')  # 画饼图(数据,数据对应的标签,百分数保留两位小数点)

plt.title("出场最多的五个角色 ")

plt.show()



源代码

import csv

from matplotlib import pyplot as plt

import pandas as pd

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签

plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

characers = {'苏檀儿': 0, '宁毅': 0, '刘西瓜': 0, '秦嗣源': 0, '陆红提': 0, '苏仲堪': 0, '苏文兴': 0, '苏伯庸': 0, '耿护院': 0, '元锦儿': 0, '宋宪': 0,

            '陈凡': 0}

with open("赘婿.txt", "r", encoding="utf-8") as fr:

    content = fr.read()

    # 依次迭代所有⾏

    for line in content:

        # 去除空格

        line = line.strip()

        # 如果是空⾏,则跳过

        if len(line) == 0:

            continue

        # 统计每⼀字出现的个数

        for x in range(0, len(line)):

            for y in characers:

                if line[x:x + 2] == y[0] or line[x:x + 3] == y[0]:

                    characers[y] += 1

with open("data.csv", "w") as csv_file:

    csv_writer = csv.DictWriter(csv_file, fieldnames=['人名', '次数'])

    csv_writer.writeheader()

    key = list(characers.keys())

    value = list(characers.values())

    for i in range(len(key)):

        dic = {  # 字典类型

            '人名': key[i],

            '次数': value[i]

        }

        csv_writer.writerow(dic)

characters = {}

with open("./data.csv") as f:

    reader = csv.reader(f)

    header_row = next(reader)

    names, times = [], []

    for row in reader:

        if len(row) > 1:

            name = row[0]

            time = int(row[1])

            names.append(name)

            times.append(time)

            characters[name] = time

    plt.plot(names, times, c='red', alpha=0.3)

    # plt.fill_between(dates, highs, lows, facecolor='blue', alpha=0.05)

    title = "人物出现次数折线图 "

    plt.title(title, fontsize=24)

    plt.xlabel('name', fontsize=16)

    plt.ylabel('times', fontsize=16)

    plt.show()

    # title += '\nSitka, AK and Death Valley, CA'

    # fig.autofmt_xdate()  # 绘制斜的日期标签

    # plt.tick_params(axis='both', labelsize=16)

    # plt.ylim(10, 120)  # 设置y轴范围

n = 5

L = sorted(characters.items(), key=lambda item: item[1], reverse=True)

L = L[:n]

names = []

indexs = []

for name, index in L:

    names.append(name)

    indexs.append(index)

fig = plt.figure()

plt.pie(indexs, labels=names, autopct='%1.2f%%')  # 画饼图(数据,数据对应的标签,百分数保留两位小数点)

plt.title("出场最多的五个角色 ")

plt.show()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容