Python数据分析——谁才是《三体》的主角?

准备工作

matplotlib库

三体.txt(utf-8编码)

三体主要人物.txt(utf-8编码)

大纲

导入matplotlib.pyplot方法,创建1个Novel类,包含2个属性和4个方法。

import matplotlib.pyplot as plt

class Novel():
    """创建一个小说的类"""
    
    def __init__(self, novel_name, roles_name):
        """初始化类的属性"""
  
  def
one_role_nums(self, role_name): """统计一个人物名字出现的次数"""

  def
main_roles_nums(self): """统计主要人物名字出现的次数"""

  def
show_datas(self): """输出人物名字及出现次数"""

  def
draw_picture(self, title = ""): """可视化数据"""

 初始化

类包含两个属性,小说名字和主要人物名字。

主要人物来源于《三体》百度百科,以每行一个名字的格式存储于txt文档,如下图。

注:艾aa的名字采用aa,因小说中多称呼aa。

def __init__(self, novel_name, roles_name):
    """初始化类的属性"""

    self.novel_name = novel_name
    self.roles_name = roles_name

one_role_nums方法

默认名字为2-4个字,否则不计数。

def one_role_nums(self, role_name):
    """统计一个人物名字出现的次数"""

    with open(self.novel_name, encoding = 'utf-8') as f:
        content = f.read()

    count = 0
    if len(role_name) < 2 or len(role_name) > 4:
        return 0
    if len(role_name) == 2:
        for i in range(len(content) - 1):
            if content[i] + content[i + 1] == role_name:
                count += 1
    if len(role_name) == 3:
        for i in range(len(content) - 2):
            if content[i] + content[i + 1]  + content[i + 2]== role_name:
                count += 1
    if len(role_name) == 4:
        for i in range(len(content) - 3):
            if content[i] + content[i + 1]  + content[i + 2] + content[i + 3] == role_name:
                count += 1
    return count

main_roles_nums方法

返回一个列表,列表元素为字典中的键值对且按value降序排列。

def main_roles_nums(self):
    """统计主要人物名字出现的次数"""

    with open(self.roles_name, encoding = 'utf-8') as f:
        names = [line.strip() for line in f.readlines()]

    dic = {}                    
    for name in names:
        num = self.one_role_nums(name)
        if num:
            dic[name] = num
    dic = sorted(dic.items(), key = lambda k : k[1], reverse = True)
    return dic

show_datas方法

def show_datas(self):
    """输出人物名字及出现次数"""

    dic = self.main_roles_nums()
    for x in dic:
        print(x[0], x[1])

draw_picture方法

运用matplotlib库将所得数据可视化。

调用方法时可赋予一个标题,默认为空。

def draw_picture(self, title = ""):
    """可视化数据"""

    dic = self.main_roles_nums()
    names, nums = [], []
    for x in dic:
        names.append(x[0])
        nums.append(x[1])

    n = list(range(len(names)))
    plt.figure(figsize=(10, 6))    
    plt.bar(n, nums, alpha=0.5)
    plt.xlim((0, len(names)))
    plt.xticks(n, names, rotation = 30, fontproperties = "SimHei", fontsize = 24)
    plt.title(title, fontproperties = "SimHei", fontsize = 40)

    plt.show()

创建对象并调用方法

创建一个对象,赋予两个属性。

novel = Novel("三体.txt", "三体主要人物.txt")   

调用方法show_datas()

novel.show_datas()

调用方法draw_picture()并赋予一个标题

novel.draw_picture("三体主要人物名字出现次数")

结果符合预期,汪淼、罗辑和程心是当之无愧的三大主角,且随着《三体I》《三体II》《三体III》小说的篇幅增多而名字出现次数增多。

其他人物名字出现的次数基本与观感相符合。

全部代码

import matplotlib.pyplot as plt

class Novel():
    """创建一个小说的类"""
    
    def __init__(self, novel_name, roles_name):
        """初始化类的属性"""
        
        self.novel_name = novel_name
        self.roles_name = roles_name
        
    def one_role_nums(self, role_name):
        """统计一个人物名字出现的次数"""
        
        with open(self.novel_name, encoding = 'utf-8') as f:
            content = f.read()
            
        count = 0
        if len(role_name) < 2 or len(role_name) > 4:
            return 0
        if len(role_name) == 2:
            for i in range(len(content) - 1):
                if content[i] + content[i + 1] == role_name:
                    count += 1
        if len(role_name) == 3:
            for i in range(len(content) - 2):
                if content[i] + content[i + 1]  + content[i + 2]== role_name:
                    count += 1
        if len(role_name) == 4:
            for i in range(len(content) - 3):
                if content[i] + content[i + 1]  + content[i + 2] + content[i + 3] == role_name:
                    count += 1
        return count
        
    def main_roles_nums(self):
        """统计主要人物名字出现的次数"""
        
        with open(self.roles_name, encoding = 'utf-8') as f:
            names = [line.strip() for line in f.readlines()]
            
        dic = {}                    
        for name in names:
            num = self.one_role_nums(name)
            if num:
                dic[name] = num
        dic = sorted(dic.items(), key = lambda k : k[1], reverse = True)
        return dic
    
    def show_datas(self):
        """输出人物名字及出现次数"""
        
        dic = self.main_roles_nums()
        for x in dic:
            print(x[0], x[1])
        
    def draw_picture(self, title = ""):
        """可视化数据"""
        
        dic = self.main_roles_nums()
        names, nums = [], []
        for x in dic:
            names.append(x[0])
            nums.append(x[1])

        n = list(range(len(names)))
        plt.figure(figsize=(12, 9))    
        plt.bar(n, nums, alpha=0.5)
        plt.xlim((0, len(names)))
        plt.xticks(n, names, rotation = 30, fontproperties = "SimHei", fontsize = 24)
        plt.title(title, fontproperties = "SimHei", fontsize = 40)

        plt.show()
        
novel = Novel("三体.txt", "三体主要人物.txt")   
novel.show_datas()
novel.draw_picture("三体主要人物名字出现次数")

猜你喜欢

转载自www.cnblogs.com/ruanshuai/p/10126348.html