• Python第三方库 -> 由于是ipynb格式,所以没有对应的输出结果


    from bs4 import BeautifulSoup,element
    # 导入 BeautifulSoup
    
    import lxml
    import requests
    
    html_doc = """
    <html><head><title>The Dormouse's story</title></head>
    <body>
    <p class="title"><b>The Dormouse's story</b></p>
    
    <p class="story">Once upon a time there were three little sisters; and their names were
    <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
    <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
    <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
    and they lived at the bottom of a well.</p>
    
    <p class="story">...</p>
    """
    
    soup = BeautifulSoup(html_doc,'lxml')  #创建 beautifulsoup 对象
    
    soup1 = BeautifulSoup(open('index.html'))
    
    soup.prettify()#打印 soup 对象的内容,格式化输出
    
    # Beautiful Soup 所有对象可以归纳为4种:
    # • Tag
    # • NavigableString
    # • BeautifulSoup
    # • Comment
    
    
    soup.title # 获取标题信息
    
    soup.head # 获取头
    
    soup.a # 获取第一个 a 链接
    
    soup.p # 获取第一个 p 段落
    
    soup.name
    
    soup.a.attrs # 第一个a标签的属性
    
    soup.p.attrs
    
    soup.a.get('href') # 单独获取某一个属性
    
    soup.a['href']
    
    soup.a['href'] = 'https://www.cnblogs.com/hany-postq473111315/'
    # 对属性进行修改
    
    del soup.a['href'] # 删除属性
    
    soup.p.string # 使用 string 获取内容
    
    soup.a.string # 输出 a 的内容
    
    '''
    .string 输出的内容,已经把注释符号去掉了,可能会带来麻烦
    '''
    print(type(soup.a.string))
    if type(soup.a.string)==element.Comment:
        print(soup.a.string)
    
    
    soup
    
    soup.head.contents # 将tag的子节点以列表的方式输出
    
    soup.head.contents[0] # 列表方式取值
    
    soup.head.children # list 生成器对象
    
    for item in soup.head.children:
        print(item)
        # 通过循环输出
    
    '''
    .contents 和 .children 属性仅包含tag的直接子节点,
    .descendants 属性可以对所有tag的子孙节点进行递归循环
    
    '''
    for item in soup.descendants:
        print(item)
    
    soup.head.string # 查看内容
    
    soup.title.string
    
    soup.strings
    
    for string in soup.strings:
        # soup.strings 为 soup 内的所有内容
        print(string)
    
    # 使用 .stripped_strings 可以去除多余空白内容
    for string in soup.stripped_strings:
        print(string)
    
    soup
    
    soup.p.parent.name # 父标签的名称
    
    soup.head.title.string.parent.name
    
    '''
    通过元素的 .parents 属性可以递归得到元素的所有父辈节点
    '''
    for parent in soup.head.title.string.parents:
    #     print(parent)
        print(parent.name)
    
    '''
    .next_sibling 属性获取了该节点的下一个兄弟节点,
    .previous_sibling 属性获取了该节点的上一个兄弟节点,
    如果节点不存在,则返回 None
    注:
    因为空白或者换行也可以被视作一个节点,
    所以得到的结果可能是空白或者换行。
    '''
    soup.p.next_sibling
    
    soup.p.previous_sibling
    
    soup.p.next_sibling.next_sibling
    
    '''
    .next_siblings 和 .previous_siblings 
     可以对当前节点的兄弟节点迭代
    '''
    for sibling in soup.a.next_siblings:
        print(sibling)
    
    soup.head.next_element # 后一个节点
    
    soup.head.previous_element # 前一个节点
    
    '''
    通过 .next_elements 和 .previous_elements 的迭代器
    可以向前或向后访问文档的解析内容
    '''
    
    for element in soup.a.next_elements:
        print(element)
    
    '''
    find_all() 方法搜索当前tag的所有tag子节点,
    并判断是否符合过滤器的条件
    '''
    soup.find_all('b')
    
    import re 
    for tag in soup.find_all(re.compile('^b')):
        # 通过传入正则表达式,进行查找
        print(tag)
        print(tag.name)
    
    soup.find_all(['a','b'])
    # 传递列表,查找元素
    
    soup.find_all(['a','b'])[2]['href']
    # 查找指定元素
    
    for tag in soup.find_all(True):
        # 查找所有的 tag,不会返回字符串节点
        print(tag.name)
    
    # 传递方法
    def has_href(tag):
        # 如果存在就返回 True
        return tag.has_attr('href')
    soup.find_all(has_href)
    
    soup.find_all(id = 'link2')
    # 寻找指定的属性值
    
    soup.find_all(href = re.compile('tillie'))
    
    # 使用多个指定名字的参数可以同时过滤tag的多个属性
    soup.find_all(href=re.compile("tillie"), id='link3')
    
    # class_ 代替 class 进行查找
    soup.find_all('a',class_ = 'sister')
    
    '''
    通过 find_all() 方法的 attrs 参数定义一个字典参数来搜索包含特殊属性的tag
    '''
    data_soup = BeautifulSoup('<div data-foo="value">foo!</div>')
    data_soup.find_all(attrs = {'data-foo':'value'})
    # attrs = {'data-foo':'value'} 进行筛选
    
    '''
    通过 text 参数可以搜索文档中的字符串内容
    text 参数接受 字符串 , 正则表达式 , 列表, True
    '''
    soup.find_all(text=["Tillie", "Elsie", "Lacie"])
    
    soup.find_all(text="Tillie")
    
    soup.find_all(text=re.compile("Dormouse"))
    
    # 使用 limit 参数限制返回结果的数量
    soup.find_all('a',limit = 2)
    
    '''
    调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点
    如果只想搜索tag的直接子节点,可以使用参数 recursive=False
    '''
    soup.html.find_all('title',recursive=False)
    
    soup.html.find_all('title',recursive=True)
    
    '''
    CSS选择器
    标签名不加任何修饰,类名前加点,id名前加 #
    '''
    soup.select('title')
    
    soup.select('a')
    
    soup.select('.sister')
    # 通过类名查找
    
    soup.select('#link2')
    
    '''
    查找 p 标签中,id 等于 link1的内容,二者需要用空格分开
    一定注意是 p 标签下的
    '''
    soup.select("p #link1")
    
    
    soup.select('head > title')
    
    soup.select('a[class="sister"]')
    # 查找时还可以加入属性元素,属性需要用中括号括起来
    
    '''
    select 选择后,使用 get_text() 方法获取内容
    '''
    soup.select('title')
    
    soup.select('title')[0].get_text()
    
    soup.select('title')[0].string
    
    for title in soup.select('p .sister'):
        print(title.get_text())

    # 导入 jieba
    import jieba
    import jieba.posseg as pseg #词性标注
    import jieba.analyse as anls #关键词提取
    
    
    
    seg_list = jieba.cut("他来到上海交通大学", cut_all=True)
    print("【全模式】:" + "/ ".join(seg_list))
    print(type(seg_list))
    
    # 精确模式
    seg_list = jieba.cut("他来到上海交通大学", cut_all=False)
    print("【精确模式】:" + "/ ".join(seg_list))
    print(type(seg_list))
    
    
    # 搜索引擎模式
    seg_list = jieba.cut_for_search("他毕业于上海交通大学机电系,后来在一机部上海电器科学研究所工作")
    print("【搜索引擎模式】:" + "/ ".join(seg_list))
    
    
    
    # 返回列表
    seg_list = jieba.lcut("他来到上海交通大学", cut_all=True)
    print("【返回列表】:{0}".format(seg_list))
    
    
    
    # 返回列表
    seg_list = jieba.lcut_for_search("他毕业于上海交通大学机电系,后来在一机部上海电器科学研究所工作")
    print("【返回列表】:{0}".format(seg_list))
    
    
    
    # 未启用 HMM
    seg_list = jieba.cut("他来到了网易杭研大厦", HMM=False) #默认精确模式和启用 HMM
    print("【未启用 HMM】:" + "/ ".join(seg_list))  
    
    # 识别新词
    seg_list = jieba.cut("他来到了网易杭研大厦") #默认精确模式和启用 HMM
    print("【识别新词】:" + "/ ".join(seg_list))  
    
    # 繁体字文本
    ft_text = """人生易老天難老 歲歲重陽 今又重陽 戰地黃花分外香 壹年壹度秋風勁 不似春光 勝似春光 寥廓江天萬裏霜 """
    
    # 全模式
    print("【全模式】:" + "/ ".join(jieba.cut(ft_text, cut_all=True)))
    
    # 精确模式
    print("【精确模式】:" + "/ ".join(jieba.cut(ft_text, cut_all=False)))  
    
    # 搜索引擎模式
    print("【搜索引擎模式】:" + "/ ".join(jieba.cut_for_search(ft_text))) 
    
    # 示例文本
    sample_text = "周大福是创新办主任也是云计算方面的专家"
    
    # 未加载词典
    print("【未加载词典】:" + '/ '.join(jieba.cut(sample_text)))
    
    # 载入词典
    jieba.load_userdict("userdict.txt")
    
    # 加载词典后
    print("【加载词典后】:" + '/ '.join(jieba.cut(sample_text)))
    
    jieba.add_word('石墨烯') #增加自定义词语
    jieba.add_word('凱特琳', freq=42, tag='nz') #设置词频和词性 
    jieba.del_word('自定义词') #删除自定义词语 
    
    # 调节词频前
    print("【调节词频前】:" + '/'.join(jieba.cut('如果放到post中将出错。', HMM=False)))
    
    # 调节词频
    jieba.suggest_freq(('', ''), True)
    
    # 调节词频后
    print("【调节词频后】:" + '/'.join(jieba.cut('如果放到post中将出错。', HMM=False)))
    
    s = "此外,公司拟对全资子公司吉林欧亚置业有限公司增资4.3亿元,增资后,吉林欧亚置业注册资本由7000万元增加到5亿元。吉林欧亚置业主要经营范围为房地产开发及百货零售等业务。目前在建吉林欧亚城市商业综合体项目。2013年,实现营业收入0万元,实现净利润-139.13万元。"
    
    for x, w in anls.extract_tags(s, topK=20, withWeight=True):
        print('%s %s' % (x, w))
    
    for x, w in anls.textrank(s, withWeight=True):
        print('%s %s' % (x, w))
    
    # jieba.analyse.set_stop_words("stop_words.txt")
    # jieba.analyse.set_idf_path("idf.txt.big");
    
    
    # for x, w in anls.extract_tags(s, topK=20, withWeight=True):
    #     print('%s %s' % (x, w))
    
    words = pseg.cut("他改变了中国")
    
    for word, flag in words:
        print("{0} {1}".format(word, flag))
    
    # jieba.enable_parallel(4):开启并行分词模式,参数为并行进程数
    # jieba.disable_parallel() :关闭并行分词模式
    
    result = jieba.tokenize(u'上海益民食品一厂有限公司')
    print("【普通模式】")
    for tk in result:
        print("word: {0} 		 start: {1} 		 end: {2}".format(tk[0],tk[1],tk[2]))
    
    result = jieba.tokenize(u'上海益民食品一厂有限公司', mode='search')
    print("【搜索模式】")
    for tk in result:
        print("word: {0} 		 start: {1} 		 end: {2}".format(tk[0],tk[1],tk[2]))
    
    # 网址: https://www.jianshu.com/p/883c2171cdb5
    '''
    进行分词使用 :
    jieba.cut
    jieba.cut_for_search
    
    jieba.lcut
    jieba.lcut_for_search
    
    jieba.cut 和 jieba.lcut 参数
    需要分词的字符串
    cut_all 参数:是否使用全模式,默认值为 False
    HMM 参数:用来控制是否使用 HMM 模型,默认值为 True
    
    HMM 模型,即隐马尔可夫模型(Hidden Markov Model, HMM),
    是一种基于概率的统计分析模型,用来描述一个系统隐性状态的转移和隐性状态的表现概率。
    
    
    其大致原理是:
    
    采用四个隐含状态,分别表示为单字成词,词组的开头,词组的中间,词组的结尾。
    通过标注好的分词训练集,可以得到 HMM 的各个参数,
    然后使用 Viterbi 算法来解释测试集,得到分词结果。
    
    
    开发者可以指定自定义词典,以便包含 jieba 词库里没有的词
    词语 词频(可省略) 词性(可省略)
    
    使用 jieba.load_userdict(file_name) 载入词典。
    使用 add_word(word, freq=None, tag=None) 和 del_word(word) 可在程序中动态修改词典。
    
    使用 suggest_freq(segment, tune=True) 可调节单个词语的词频,使其能(或不能)被分出来。
    
    通过 jieba.analyse.extract_tags 方法可以基于 TF-IDF 算法进行关键词提取,
    该方法共有 4 个参数:
    
        sentence:为待提取的文本
        topK:为返回几个 TF/IDF 权重最大的关键词,默认值为 20
        withWeight:是否一并返回关键词权重值,默认值为 False
        allowPOS:仅包括指定词性的词,默认值为空
    
    使用 jieba.analyse.TFIDF(idf_path=None) 可以新建 TFIDF 实例,
    其中 idf_path 为 IDF 频率文件
    
    通过 jieba.analyse.textrank 方法可以使用基于 TextRank 算法的关键词提取,
    
    使用 jieba.analyse.TextRank() 可以新建自定义 TextRank 实例
    
    jieba.posseg.POSTokenizer(tokenizer=None) 新建自定义分词器,
    tokenizer 参数可指定内部使用的 jieba.Tokenizer 分词器。
    jieba.posseg.dt 为默认词性标注分词器。
    
    jieba.enable_parallel(4):开启并行分词模式,参数为并行进程数
    jieba.disable_parallel() :关闭并行分词模式
    
    使用 jieba.tokenize 方法可以返回词语在原文的起止位置。
        mode='search' 表示搜索模式
    '''
    网址: 'https://www.jianshu.com/p/883c2171cdb5'

    import lxml
    
    lxml_roles = '''
     标签名   选取此节点的所有子节点
     
     /       从当前节点选取直接子节点
     
     //      从当前节点选取子孙节点
     
     .      选取当前节点
     
     ..     选取当前节点的父节点
     
     @      选取属性
     
     *      通配符,选择所有元素节点与元素名
     
     @*     选取所有属性
    
    [@attrib] 选取具有给定属性的所有元素
    
    [@attrib='value'] 选取给定属性具有给定值的所有元素
    
    [tag] 选取所有具有指定元素的直接子节点
    
    [tag='text'] 选取所有具有指定元素并且文本内容是 text 节点
    
    '''
    
    from lxml import etree
    
    text='''
    <div>
        <ul>
             <li class="item-0"><a href="link1.html">第一个</a></li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0"><a href="link5.html">a属性</a>
         </ul>
     </div>
    '''
    html = etree.HTML(text)
    # html -> <Element html at 0x207bc230e08>
    etree.tostring(html,encoding='utf-8').decode('utf-8')
    # etree.tostring 解析成字节
    
    etree.tostringlist(html)
    # 解析成列表
    
    html.xpath('//li/a') 
    # li 标签下的 a 标签
    
    html.xpath('//li/a') [0].text
    
    html.xpath('//li[@class="item-1"]')
    # li 标签下 class 属性为 item-1 的
    
    # 使用 text 获取节点的文本
    html.xpath('//li[@class="item-1"]/a/text()')
    # 获取a节点下的内容
    
    from lxml import etree
    from lxml.etree import HTMLParser
    
    text='''
    <div>
        <ul>
             <li class="item-0"><a href="link1.html">第一个</a></li>
             <li class="item-1"><a href="link2.html">second item</a></li>
         </ul>
     </div>
    '''
    html = etree.HTML(text,etree.HTMLParser())
    html.xpath('//a[@href="link2.html"]/../@class')
    # .. 父节点 , @ 取属性
    
    html.xpath('//a[@href="link2.html"]/parent::*/@class')
    # 使用 parent::* 来获取父节点
    
    html.xpath('//li//text()') 
    #获取li下所有子孙节点的内容
    
    # 使用 @ 符号即可获取节点的属性
    html.xpath('//li/a/@href')
    
    text1='''
    <div>
        <ul>
             <li class="aaa item-0"><a href="link1.html">第一个</a></li>
             <li class="bbb item-1"><a href="link2.html">second item</a></li>
         </ul>
     </div>
    '''
    html=etree.HTML(text1,etree.HTMLParser())
    # 使用 contains(属性,值) 进行获取
    html.xpath('//li[contains(@class,"aaa")]/a/text()')
    
    text1='''
    <div>
        <ul>
             <li class="aaa" name="item"><a href="link1.html">第一个</a></li>
             <li class="aaa" name="fore"><a href="link2.html">second item</a></li>
         </ul>
     </div>
    '''
    html = etree.HTML(text1,etree.HTMLParser())
    
    html.xpath('//li[@class="aaa" and @name="fore"]/a/text()')
    
    html.xpath('//li[contains(@class,"aaa") and contains(@name,"fore")]/a/text()')
    
    html.xpath('//li[contains(@class,"aaa") and @name="fore"]/a/text()')
    
    lxml_operators = '''
    
    or 或
    
    and 与
    
    mod 取余
    
    | 取两个节点的集合
    
    + 加 , - 减 , * 乘 , div 除
    
    = 等于 , != 不等于 , < 小于 
    
    <= 小于或等于 , > 大于 , >= 大于或等于
    
    '''
    
    # 利用中括号引入索引的方法获取特定次序的节点
    text1='''
    <div>
        <ul>
             <li class="aaa" name="item"><a href="link1.html">第一个</a></li>
             <li class="aaa" name="item"><a href="link1.html">第二个</a></li>
             <li class="aaa" name="item"><a href="link1.html">第三个</a></li>
             <li class="aaa" name="item"><a href="link1.html">第四个</a></li> 
         </ul>
     </div>
    '''
    html = etree.HTML(text1,etree.HTMLParser())
    
    
    #获取所有 li 节点下 a 节点的内容
    html.xpath('//li[contains(@class,"aaa")]/a/text()')
    
    #获取第一个
    html.xpath('//li[1][contains(@class,"aaa")]/a/text()')
    
    #获取最后一个
    html.xpath('//li[last()][contains(@class,"aaa")]/a/text()')
    
    #获取第三个
    html.xpath('//li[position()>2 and position()<4][contains(@class,"aaa")]/a/text()') 
    
    #获取倒数第三个
    html.xpath('//li[last()-2][contains(@class,"aaa")]/a/text()') 
    
    #获取所有祖先节点
    html.xpath('//li[1]/ancestor::*')
    
    # 获取 div 祖先节点
    html.xpath('//li[1]/ancestor::div')
    
    # 获取所有属性值
    html.xpath('//li[1]/attribute::*')
    
    # 获取所有直接子节点
    html.xpath('//li[1]/child::*')
    
    # 获取所有子孙节点的 a 节点
    html.xpath('//li[1]/descendant::a')
    
    # 获取当前子节点之后的所有节点
    html.xpath('//li[1]/following::*')
    
    # 获取当前节点的所有同级节点
    html.xpath('//li[1]/following-sibling::*')

    import math
    
    # 返回数字的绝对值
    math.fabs(-10)
    
    # 返回数字的上入整数
    math.ceil(4.1)
    
    math.ceil(-3.2)
    
    # 返回 e 的 x 次幂
    math.exp(1)
    
    # 返回数字的下舍整数
    math.floor(4.9)
    
    math.floor(-5.6)
    
    # 以 e 为基数
    math.log(math.e)
    
    # 以 2 为基数
    math.log(8,2)
    
    # 以 10 为基数
    math.log10(100)
    
    # 返回 x 的 (小数部分,整数部分)
    math.modf(5.75)
    
    math.modf(-5.75)
    
    # x ** y , x 的 y 次幂
    math.pow(2,3)
    
    math.pow(2,-3)
    
    # 返回数字 x 的平方根
    math.sqrt(16)
    
    math.sqrt(0)
    
    # 返回 x 的反余弦弧度值
    math.acos(1)
    
    # 返回 x 的反正切弧度值
    math.atan(1)
    
    # math.atan2(y,x) 
    # 返回给定的 X 及 Y 坐标值的反正切值
    math.atan2(4,3)
    
    # 返回 x 的弧度的余弦值
    math.cos(0)
    
    # 返回欧几里德范数 sqrt(x*x + y*y)
    math.hypot(3, 4)
    
    # 返回的 x 弧度的正弦值
    math.sin(math.pi/2)
    
    # 返回 x 弧度的正切值
    math.tan(math.pi/2)
    
    # 将弧度转换为角度
    math.degrees(math.pi/2)
    
    # 将角度转换为弧度
    math.radians(90)
    
    math.pi
    
    math.e

    import matplotlib.pyplot as plt
    import pandas as pd
    
    plt.rcParams['font.sans-serif']=['SimHei'] 
    #用来正常显示中文标签
    plt.rcParams['axes.unicode_minus']=False 
    #用来正常显示负号
    
    df = pd.read_excel('超市营业额.xlsx')
    df.head()
    
    # 折线图
    plot_params = '''
    参数      接收值             说明                 默认值
    x,y      array        表示 x 轴与 y 轴对应的数据; 无
    color     string       表示折线的颜色;           None
    marker    string       表示折线上数据点处的类型;  None 
    linestyle string       表示折线的类型;            -
    linewidth 数值         线条粗细:      linewidth=1.=5.=0.3 1
    alpha     0~1之间的小数 表示点的透明度;           None
    label     string       数据图例内容:    label=‘实际数据’ None
    '''
    
    x = df['姓名'].head()
    y = df['交易额'].head()
    # x,y 的值
    plt.title('员工和营业额之间的折线图')
    # 设置标题
    
    
    plt.plot(x, y, color='blue',marker='*',linestyle = '-',
             linewidth = 0.8,alpha = 0.6,label='营业额')
    # 折线图参数
    
    
    plt.legend()
    # 显示图例
    plt.xlabel('员工姓名')
    # 设置 x 轴标题
    plt.xticks(rotation = 45)
    # x 轴的字体倾斜
    plt.ylabel('营业额(元)')
    # 设置 y 轴
    
    # 柱状图
    bar_params = '''
    参数     说明             类型
    x,y      x坐标,y坐标     int,float
    width   宽度 0~1,       默认0.8
    alpha   透明度          0~1之间的小数 
    bottom  条形的起始位置  也是y轴的起始坐标 , 整数
    align   条形的中心位置  "center","lege"边缘
    edgecolor 边框颜色
    linewidth 边框宽度
    color   条形的颜色    "r","b","g","#123465",默认"b"
                        'c', 'r', 'g', 'k', 'y', 'm', 'b'
    '''
    
    x = df['姓名'].head()
    y = df['交易额'].head()
    # x,y 的值
    plt.title('员工和营业额之间的柱状图')
    # 设置标题
    
    plt.bar(x, y,width = 0.3,bottom = 100,align = 'center',
            edgecolor = 'y',linewidth = 3,color = ['c','r','g','k','y'],
           label='营业额')
    # 柱状图参数
    
    plt.legend()
    # 显示图例
    plt.xlabel('员工姓名')
    # 设置 x 轴标题
    plt.xticks(rotation = 45)
    # x 轴的字体倾斜
    plt.ylabel('营业额(元)')
    # 设置 y 轴
    
    scatter_params = '''
    参数       说明
    x,y      x轴 和 y轴对应的数据
    c        散点标记的颜色,为指定的色彩、数值序列或者颜色序列。
            'c', 'r', 'g', 'k', 'y', 'm', 'b'
    marker   散点标记类型,默认为圆圈。
    cmap     仅当c参数为颜色序列的时候使用。
    alpha    透明图设置,取值范围[0,1]。0:透明,1:不透明。
    norm    仅当c为数值序列的时候,通过colors.Normalize将值进行正则化。
    linewidths   散点标记的边界的宽度。
    edgecolors   散点标记的边界的颜色。
    '''
    
    x = range(len(df['交易额']))
    y = df['交易额']
    
    plt.title('员工和营业额之间的散点图')
    # 设置标题
    
    plt.scatter(x, y,s = 20,c = 'g',marker = '*',
            alpha = 0.8,linewidths = 0.5,edgecolors = ['c', 'r', 'g', 'k', 'y', 'm', 'b'])
    # 散点图参数
    
    plt.xlabel('员工姓名')
    # 设置 x 轴标题
    plt.xticks(rotation = 45)
    # x 轴的字体倾斜
    plt.ylabel('营业额(元)')
    # 设置 y 轴
    
    pie_params = '''
    参数                  说明
    x        (每一块)的比例,如果sum(x) > 1会使用sum(x)归一化;
    labels   (每一块)饼图外侧显示的说明文字;
    explode  (每一块)离开中心距离;
    startangle 起始绘制角度,默认图是从x轴正方向逆时针画起,如设定 =90 则从y轴正方向画起;
    shadow   在饼图下面画一个阴影。默认值:False,没有阴影;
    labeldistance  label标记的绘制位置,相对于半径的比例,默认值为1.1, 如<1则绘制在饼图内侧;
    autopct  控制饼图内百分比设置,可以使用format字符串或者format function
               '%1.1f'指小数点前后位数(没有用空格补齐);
    pctdistance 类似于 labeldistance,指定 autopct 的位置刻度,默认值为0.6
    radius         控制饼图半径,默认值为1
    counterclock  指定指针方向;布尔值,可选参数,默认为:True,逆时针
    wedgeprops 字典类型,可选参数,默认值:None。参数字典传递给wedge对象用来画一个饼图。
            例如:wedgeprops={'linewidth':3}设置wedge线宽为3。
    textprops   设置标签(labels)和比例文字的格式;字典类型,可选参数,默认值为:None。
            传递给text对象的字典参数。textprops={'fontsize':20,'color':'black'}
    center     浮点类型的列表,可选参数,默认值:(0,0)。图标中心位置。
    frame      布尔类型,可选参数,默认值:False。如果是True,绘制带有表的轴框架。
    rotatelabels  布尔类型,可选参数,默认为:False。如果为True,旋转每个label到指定的角度。
    '''
    
    x = df.groupby(by = '姓名')['交易额'].sum()
    
    plt.title('员工和营业额之间的饼图')
    # 设置标题
    
    plt.pie(x,labels = x.keys(),explode = [0,0.1,0,0.1,0.3,0.4],startangle = 30,
            shadow = True,labeldistance = 1.3,autopct = '%1.1f',pctdistance = 0.5,
            radius = 0.9,counterclock = True,wedgeprops = {'linewidth':3},
            textprops = {'fontsize':14,'color':'black'},center = (2,2),frame = False,
            rotatelabels = False
            
           )
    # 饼图参数
    
    plt.xlabel('员工姓名')
    # 设置 x 轴标题
    plt.ylabel('营业额所占百分比')
    # 设置 y 轴
    
    legend_params = '''
    参数                         说明
    loc = 'upper right'         位于右上角
    bbox_to_anchor = [0.5, 0.5]  外边距 上边 右边
    ncol = 2                     分两列
    borderaxespad = 0.3         图例的内边距
    '''

    import MySQLdb
    
    # 打开数据库连接
    db = MySQLdb.connect(
        "localhost",
        "root",
        "root",
        "testdb",
        charset = "utf8"
    )
    db
    
    # 使用cursor()方法获取操作游标 
    cursor = db.cursor()
    cursor
    
    # 使用execute方法执行SQL语句
    cursor.execute("SELECT VERSION()")
    
    # 使用 fetchone() 方法获取一条数据
    data = cursor.fetchone()
    
    print("数据库版本:%s" % data)
    
    # 如果数据表已经存在使用 execute() 方法删除表。
    cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")
    
    # 创建数据表SQL语句
    sql = """CREATE TABLE EMPLOYEE (
             FIRST_NAME  CHAR(20) NOT NULL,
             LAST_NAME  CHAR(20),
             AGE INT,  
             SEX CHAR(1),
             INCOME FLOAT )"""
    
    cursor.execute(sql)
    
    # SQL 插入语句
    sql = """INSERT INTO EMPLOYEE(FIRST_NAME,
             LAST_NAME, AGE, SEX, INCOME)
             VALUES ('Hany', 'Liu', 22, 'M', 9999)"""
    
    
    cursor.execute(sql)
    
    try:
       # 执行sql语句
       cursor.execute(sql)
        
       # 提交到数据库执行
       db.commit()
    except:
       # 发生错误回滚
       db.rollback()
    
    # SQL 插入语句
    sql = "INSERT INTO EMPLOYEE(FIRST_NAME, 
           LAST_NAME, AGE, SEX, INCOME) 
           VALUES (%s, %s, %s, %s, %s )" % 
           ('XiuW', 'Yin', 21, 'F', 7777)
    
    try:
       # 执行sql语句
       cursor.execute(sql)
       # 提交到数据库执行
       db.commit()
    except:
       # 发生错误时回滚
       db.rollback()
    
    select_operators = '''
    fetchone(): 该方法获取下一个查询结果集。结果集是一个对象
    
    fetchall():接收全部的返回结果行.
    
    rowcount: 这是一个只读属性,并返回执行execute()方法后影响的行数。
    '''
    
    # SQL 查询语句
    sql = "SELECT * FROM EMPLOYEE 
           WHERE INCOME > %s" % (8000)
    
    
    try:
       # 执行SQL语句
       cursor.execute(sql)
       # 获取所有记录列表
       results = cursor.fetchall()
       for row in results:
          fname = row[0]
          lname = row[1]
          age = row[2]
          sex = row[3]
          income = row[4]
          # 打印结果
          print("fname=%s,lname=%s,age=%s,sex=%s,income=%s" % (fname, lname, age, sex, income))
    except:
       print("Error: unable to fecth data")
    
    
    # SQL 更新语句
    sql = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = '%c'" % ('M')
    
    try:
       # 执行SQL语句
       cursor.execute(sql)
        
       # 提交到数据库执行
       db.commit()
    except:
        
       # 发生错误时回滚
       db.rollback()
    
    # SQL 删除语句
    sql = "DELETE FROM EMPLOYEE WHERE AGE < %s" % (22)
    
    try:
       # 执行SQL语句
       cursor.execute(sql)
       # 提交修改
       db.commit()
    except:
       # 发生错误时回滚
       db.rollback()
    
    db.close()

    # 导入numpy 并赋予别名 np
    import numpy as np
    
    # 列表方式
    np.array([1,2,3,4])
    
    # 元组方式
    np.array((1,2,3,4))
    
    # range 方式
    np.array(range(4)) # 不包含终止数字
    
    # 使用 arange(初始位置=0,末尾,步长=1)
    np.arange(1,8,2)
    
    np.arange(8)
    
    # 生成等差数组,endpoint 为 True 则包含末尾数字
    np.linspace(1,3,4,endpoint=False)
    
    np.linspace(1,3,4,endpoint=True)
    
    # 创建全为零的一维数组
    np.zeros(3)
    
    # 创建全为一的一维数组
    np.ones(4)
    
    # np.logspace(起始数字,终止数字,数字个数,base = 10) 对数数组
    np.logspace(1,3,4)
    
    np.logspace(1,3,4,base = 2)
    # 2 的 linspace(1,3,4) 次方
    
    # 创建二维数组(列表嵌套列表)
    np.array([[1,2,3],[4,5,6]])
    
    # 创建全为零的二维数组
    # 两行两列
    np.zeros((2,2))
    
    # 三行两列
    np.zeros((3,2))
    
    # 创建一个单位数组
    np.identity(3)
    
    # 创建一个对角矩阵,(参数为对角线上的数字)
    np.diag((1,2,3))
    
    n = np.array(([1,2,3],[4,5,6],[7,8,9]))
    n
    
    # 第一行元素
    n[0]
    
    # 第一行第三列元素
    # [行,列]
    n[0,2]
    
    # 第一行和第二行的元素
    n[[0,1],]
    
    # 第一行第三列,第三行第二列,第二行第一列
    n[[0,2,1],[2,1,0]]
    
    a = np.arange(8)
    a
    
    # 将数组倒序
    a[::-1]
    
    # 步长为 2
    a[::2]
    
    # 从 0 到 4 的元素
    a[:5]
    
    c = np.arange(16)
    c.shape = 4,4
    c
    
    # 第一行,第三个元素到第五个元素(如果没有则输出到末尾截止)
    c[0,2:5]
    
    # 第二行元素
    c[1]
    
    # 第三行到第六行,第三列到第六列
    c[2:5,2:5]
    
    # 第二行第三列元素和第三行第四列元素
    c[[1,2],[2,3]]
    
    # 第一行和第三行的第二列到第三列的元素
    c[[0,2],1:3]
    
    # 第一列和第三列的所有横行元素
    c[:,[0,2]]
    
    # 第三列所有元素
    c[:,2]
    
    # 第二行和第四行的所有元素
    c[[1,3],]
    
    # 第一行和第三行
    c[[0,3]]
    
    # 第一行和第三行 的 第二列和第四列
    c[[0,3]][:,[1,3]]
    
    # 生成一个随机数组
    np.random.randint(0,6,3)
    
    # 生成一个随机数组(二维数组)
    # randint 的 第三个参数为二元组
    np.random.randint(0,6,(3,3))
    
    # 生成四个随机数在[0,1)之间
    np.random.rand(4)
    
    # 从标准正态分布中随机抽选出3个数
    np.random.standard_normal(3)
    
    # 返回三页四行两列的标准正态分布数
    np.random.standard_normal((3,4,2))
    
    x = np.arange(8)
    x
    
    np.append(x,10)
    
    # 在数组尾部追加多个元素,不修改 x 的值
    np.append(x,[15,16,17])
    
    # 使用 数组下标修改元素的值
    x[0] = 99
    x
    
    # 在指定位置插入数据
    np.insert(x,0,54)
    
    # 创建一个多维数组
    x = np.array([[1,2,3],[11,22,33],[111,222,333]])
    x
    
    # 修改第 0 行第 2 列的元素值
    x[0,2] = 9
    x
    
    # 行数大于等于 1 的,列数大于等于 1 的置为 0
    x[1:,1:] = 0
    x
    
    # 同时修改多个元素值
    x[1:,1:] = [7,8]
    x
    
    x[1:,1:] = [[7,8],[9,10]]
    x
    
    # 对元素使用函数
    def func(i,j):
        return (i+1) * (j+1)
    
    np.fromfunction(func,(9,9))
    
    n = np.arange(10)
    n
    
    # 查看数组的大小
    n.size
    
    # 将数组分为两行五列
    n.shape = 2,5
    n
    
    # 显示数组的维度
    n.shape
    
    # 设置数组的维度,-1 表示自动计算
    n.shape = 5,-1
    n
    
    # 将新数组设置为调用数组的两行五列并返回
    x = n.reshape(2,5)
    x
    
    x = np.arange(5)
    # 将数组设置为两行,没有数的设置为 0
    x.resize((2,10))
    x
    
    # 将 x 数组的两行五列形式显示,不改变 x 的值
    np.resize(x,(2,5))
    
    x = np.array([1,2,4,3])
    x
    
    # 返回排序后元素的原下标
    np.argsort(x)
    
    # 对数组进行排序
    x.sort()
    x
    
    # 输出最大值的下标
    x.argmax()
    
    # 输出最小值的下标
    x.argmin()
    
    # 将 0~100 10等分
    x = np.arange(0,100,10)
    x
    
    # 每个数组元素对应的正弦值
    np.sin(x)
    
    # 每个数组元素对应的余弦值
    np.cos(x)
    
    # 对参数进行四舍五入
    np.round(np.cos(x))
    
    # 对参数进行上入整数 3.3->4
    x/3
    
    np.ceil(x/3)
    
    # 随机生成 2行10列 的随机数
    x = np.random.randint(0,10,size=(2,10))
    x
    
    # 大于 4 的置为 0 , 小于等于 4 的置为 1
    np.where(x > 4,0,1)
    
    # 小于 5 的乘 2 ,大于等于 5 的除 2
    np.piecewise(x,[x < 5,x >= 5],[lambda x:x * 2,lambda x:x / 2])
    
    x = np.array((1,2,3,4,5))
    x
    
    # 使用 * 进行相乘
    x*2
    
    # 使用 / 进行相除
    x / 2
    
    2 / x
    
    # 使用 // 进行整除
    x//2
    
    10//x
    
    # 使用 ** 进行幂运算
    x**3
    
    2 ** x
    
    # 使用 + 进行相加
    x + 2
    
    # 使用 % 进行取模
    x % 3
    
    # 使用 + 进行相加
    np.array([1,2,3,4]) + np.array([11,22,33,44])
    
    # 整体都加 3 
    np.array([1,2,3,4]) + np.array([3])
    
    n = np.array((1,2,3))
    n * n
    
    # 二维数组相乘
    n * np.array([[1],[2],[3]])
    
    n * np.array(([1,2,3],[4,5,6],[7,8,9]))
    
    # / 除法
    n / n
    
    # ** 幂运算
    n ** n
    
    x = np.array((1,2,3))
    y = np.array((4,5,6))
    # 数组的内积运算(对应位置上元素相乘)
    # 4 + 10 + 18
    np.dot(x,y)
    
    sum(x*y)
    
    # 布尔运算
    n = np.random.rand(4)
    n
    
    n > 0.5
    
    n[n > 0.5]
    
    # 找到数组中 0.05 ~ 0.4 的元素总数
    sum((n > 0.05)&(n < 0.4))
    
    # 是否都大于 0.2
    np.all(n > 0.2)
    
    # 是否有元素小于 0.1
    np.any(n < 0.1)
    
    a = np.array([1,4,7])
    # array([1, 4, 7])
    b = np.array([4,3,7])
    # array([4, 3, 7])
    
    # 在 a 中是否有大于等于 b 的元素
    a >= b
    
    # 在 a 中是否有等于 b 的元素
    a == b
    
    # 显示 a 中 a 的元素等于 b 的元素
    a[a == b]
    
    # 显示 a 中的偶数且小于 5 的元素
    a[(a % 2 == 0) & (a < 5)]
    
    x = np.matrix([[1,2,3],[4,5,6]])
    x
    
    y = np.matrix([1,2,3,4,5,6])
    y
    
    # x 的第二行第二列元素
    x[1,1]
    
    y[:,:3]
    
    x = np.matrix([[1,2,3],[4,5,6]])
    x
    
    y = np.matrix([[1,2],[4,5],[7,8]])
    y
    
    # 矩阵的乘法
    x*y
    
    # 相关系数矩阵,可使用在列表元素数组矩阵
    # 负相关
    np.corrcoef([1,2,3],[8,5,4])
    
    # 正相关
    np.corrcoef([1,2,3],[4,5,7])
    
    # 矩阵的方差
    np.cov([1,1,1,1,1])
    
    # 矩阵的标准差
    np.std([1,1,1,1,1])
    
    x = [-2.1 , -1 , 4.3]
    y = [3 , 1.1 , 0.12]
    
    # 垂直堆叠矩阵
    np.vstack((x,y))
    
    # 水平堆叠矩阵
    np.hstack((x,y))
    
    # 矩阵的协方差
    z = np.vstack((x,y))
    np.cov(z)
    
    np.cov(x,y)
    
    # 标准差
    np.std(z)
    
    # 列向标准差
    np.std(z,axis = 1)
    
    # 方差
    np.cov(x)
    
    # 特征值和特征向量
    A = np.array([[1,-3,3],[3,-5,3],[6,-6,4]])
    A
    
    e,v = np.linalg.eig(A)
    # e 为特征值, v 为特征向量
    e
    
    v
    
    # 矩阵与特征向量的乘积
    np.dot(A,v)
    
    # 特征值与特征向量的乘积
    e * v
    
    # 验证两个乘积是否相等
    np.isclose(np.dot(A,v),(e * v))
    
    # 行列式 |A - λE| 的值应为 0
    np.linalg.det(A-np.eye(3,3)*e)
    
    x = np.matrix([[1,2,3],[4,5,6],[7,8,0]])
    x
    
    # 逆矩阵
    y = np.linalg.inv(x)
    y
    
    # 矩阵的乘法
    x * y
    
    y * x
    
    # 求解线性方程组
    a = np.array([[3,1],[1,2]])
    b = np.array([9,8])
    # 求解
    x = np.linalg.solve(a,b)
    x
    
    # 验证
    np.dot(a,x)
    
    # 最小二乘解:返回解,余项,a 的秩,a 的奇异值
    np.linalg.lstsq(a,b)
    
    # 计算向量和矩阵的范数
    x = np.matrix([[1,2],[3,-4]])
    x
    
    np.linalg.norm(x)
    
    np.linalg.norm(x,-2)
    
    np.linalg.norm(x,-1)
    
    np.linalg.norm(x,1)
    
    np.linalg.norm([1,2,0,3,4,0],0)
    
    np.linalg.norm([1,2,0,3,4,0],2)
    
    # 奇异值分解
    a = np.matrix([[1,2,3],[4,5,6],[7,8,9]])
    u,s,v = np.linalg.svd(a)
    
    u
    
    s
    
    v
    
    # 验证
    u * np.diag(s) * v
    
    x = np.matrix([[1,2,3],[4,5,6]])
    x
    
    # 实现矩阵的转置
    x.T
    
    y = np.matrix([1,2,3,4,5,6])
    y
    
    y.T
    
    # 元素平均值
    x.mean()
    
    # 纵向平均值
    x.mean(axis = 0)
    
    # 横向平均值
    x.mean(axis = 1)
    
    # 所有元素之和
    x.sum()
    
    # 横向最大值
    x.max(axis = 1)
    
    # 横向最大值的索引下标
    x.argmax(axis = 1)
    
    # 对角线元素
    x.diagonal()
    
    # 非零元素下标
    x.nonzero()

    import pandas as pd
    import numpy as np
    import copy
    import matplotlib.pyplot as plt
    
    # 设置输出结果列对齐
    pd.set_option('display.unicode.ambiguous_as_wide',True)
    pd.set_option('display.unicode.east_asian_width',True)
    
    # 创建 从 0 开始的非负整数索引
    pd.Series(range(1,20,5))
    
    # 使用字典创建 Series 字典的键作为索引
    pd.Series({'语文':95,'数学':98,'Python':100,'物理':97,'化学':99})
    
    # 使用索引下标进行修改 Series 对象的值
    s1 = pd.Series(range(0,20,8))
    s1[0] = -17
    s1
    
    # 查看 s1 的绝对值
    abs(s1)
    
    # 将 s1 所有的值都加 5、使用加法时,对所有元素都进行运算
    s1 + 5
    
    # 在 s1 的索引下标前加入参数值
    s1.add_prefix('hany_')
    
    # s1 数据的直方图
    s1.hist()
    
    # 每行索引后面加上 _hany
    s1.add_suffix('_hany')
    
    # 查看 s2 中最大值的索引
    s1.argmax()
    
    # 查看 s1 的值是否在指定区间内
    s1.between(0,10,inclusive = True)
    
    # 查看 s1 中 10以上的数据
    s1[s1 > 10]
    
    # 查看 s1 中大于中值的数据
    s1[s1 > s1.median()]
    
    # s1 与数字之间的运算,开平方 * 10 保留一位小数
    # 16 -> 4 -> 40 -> 40.0
    round((s1**0.5)*10,1)
    
    # s1 的中值
    s1.median()
    
    # s1 中最小的两个数
    s1.nsmallest(2)
    
    # s1 中最大的两个数
    s1.nlargest(2)
    
    # Series 对象之间的运算,对相同索引进行计算
    # 不是相同索引的使用 NaN , 0 + 5 , 1 + 6
    pd.Series(range(5)) + pd.Series(range(5,10))
    
    # 对 Series 对象使用匿名函数
    s = pd.Series(range(5))
    s
    
    # x -> 0 1 2 3 4
    # y -> 2
    # z -> 5
    # 0 ** 2 % 5 -> 0
    # 3 ** 2 % 5 -> 4
    s.pipe(lambda x,y,z:(x ** y) % z,2,5)
    
    pd.Series(range(5)).pipe(lambda x:x*3)
    
    # 使用两次 pipe 应用匿名函数
    pd.Series(range(5)).pipe(lambda x:x*3).pipe(lambda x:x+3)
    
    # 对 Series 对象使用匿名函数
    pd.Series(range(5)).apply(lambda x:x+3)
    
    # 查看标准差
    pd.Series(range(0,5)).std()
    
    # 查看无偏方差
    pd.Series(range(0,5)).var()
    
    # 查看无偏标准差
    pd.Series(range(0,5)).sem()
    
    # 查看是否存在等价于 True 的值
    any(pd.Series([3,0,True]))
    
    # 查看是否所有的值都等价于 True
    all(pd.Series([3,0,True]))
    
    # 创建一个 DataFrame 对象
    pd.DataFrame(np.random.randint(1,20,(5,3)),
                             # 五行三列
                             index = range(5),
                             # 索引值
                             columns = ['A','B','C'])
                             # 列名
    
    
    # 索引为时间序列
    pd.DataFrame(np.random.randint(5,15,(9,3)),
                              index = pd.date_range(start = '202011081943',
                                                    end = '202011090400',
                                                    freq = 'H'),
                              columns = ['Pandas','爬虫','比赛'])
    
    
    # 使用字典进行创建
    pd.DataFrame({'语文':[87,79,67,92],
                               '数学':[93,89,80,77],
                               '英语':[88,95,76,77]},
                              index = ['张三','李四','王五','赵六'])
    
    # 创建时自动扩充
    pd.DataFrame({'A':range(5,10),'B':3})
    
    data = pd.read_excel('超市营业额.xlsx',usecols = ['日期','交易额'])
    data.head()
    
    dff = copy.deepcopy(data)
    # 查看周几
    dff['日期'] = pd.to_datetime(data['日期']).dt.day_name()
    dff.head()
    
    # 按照周几进行分组,查看交易的平均值
    dff = dff.groupby('日期').mean().apply(round)
    dff.index.name = '周几'
    dff.head()
    
    dff = copy.deepcopy(data)
    # 使用正则规则查看月份日期
    dff['日期'] = dff.日期.str.extract(r'(d{4}-d{2})')
    dff.head()
    
    # 按照日 进行分组查看交易的平均值 -1 表示倒数第一个
    data.groupby(data.日期.str.__getitem__(-1)).mean().apply(round)
    
    # 查看日期尾数为 1 的数据
    data[data.日期.str.endswith('1')][:12]
    
    # 查看日期尾数为 12 的交易数据,slice 为切片 (-2) 表示倒数两个
    data[data.日期.str.slice(-2) == '12']
    
    # 查看日期中月份或天数包含 2  的交易数据
    data[data.日期.str.slice(-5).str.contains('2')][1:9]
    
    # 对姓名和日期进行分组,并进行求和
    dataframe = pd.read_excel('超市营业额.xlsx')
    dff = dataframe.groupby(by = ['姓名','日期'],as_index = False).sum()
    dff.head()
    
    # 将 dff 的索引,列 设置成透视表形式
    dff = dff.pivot(index = '姓名',columns = '日期',values = '交易额')
    dff.head()
    
    # 查看前一天的数据
    dff.iloc[:,:1]
    
    # 交易总额小于 80000 的人的前三天业绩
    dff[dff.sum(axis = 1) < 80000].iloc[:,:3]
    
    # 工资总额大于 2900 元的员工的姓名
    dff[dff.sum(axis = 1) > 2900].index.values
    
    # 显示前两天每一天的交易总额以及每个人的交易金额
    dataframe.pivot_table(values = '交易额',index = '姓名',
                          columns = '日期',aggfunc = 'sum',margins = True).iloc[:,:2]
    
    # 显示每个人在每个柜台的交易总额
    dff = dataframe.groupby(by = ['姓名','柜台'],as_index = False).sum()
    dff.pivot(index = '姓名',columns = '柜台',values = '交易额')
    
    # 查看每人每天的上班次数
    dataframe.pivot_table(values = '交易额',index = '姓名',columns = '日期',aggfunc = 'count',margins = True).iloc[:,:1]
    
    # 查看每个人每天购买的次数
    dataframe.pivot_table(values = '交易额',index = '姓名',columns = '日期',aggfunc = 'count',margins = True)
    
    # 每个人每天上过几次班
    pd.crosstab(dataframe.姓名,dataframe.日期,margins = True).iloc[:,:2]
    
    # 每个人每天去过几次柜台
    pd.crosstab(dataframe.姓名,dataframe.柜台)
    
    # 将每一个人在每一个柜台的交易总额显示出来
    pd.crosstab(dataframe.姓名,dataframe.柜台,dataframe.交易额,aggfunc='sum')
    
    # 每个人在每个柜台交易额的平均值,金额/天数
    pd.crosstab(dataframe.姓名,dataframe.柜台,dataframe.交易额,aggfunc = 'mean').apply(lambda  num:round(num,2))
    
    # 读取工号姓名时段交易额,使用默认索引
    dataframe = pd.read_excel('超市营业额.xlsx',
                              usecols = ['工号','姓名','时段','交易额','柜台'])
    dataframe.head()
    
    # 对 5 的余数进行分组
    dataframe.groupby(by = lambda num:num % 5)['交易额'].sum()
    
    # 查看索引为 7 15 的交易额
    dataframe.groupby(by = {7:'索引为7的行',15:'索引为15的行'})['交易额'].sum()
    
    # 查看不同时段的交易总额
    dataframe.groupby(by = '时段')['交易额'].sum()
    
    # 各柜台的销售总额
    dataframe.groupby(by = '柜台')['交易额'].sum()
    
    # 查看每个人在每个时段购买的次数
    con = dataframe.groupby(by = '姓名')['时段'].count()
    con
    
    con.name = '交易人和次数'
    con
    
    # 每个人的交易额平均值并排序
    dataframe.groupby(by = '姓名')['交易额'].mean().round(2).sort_values()
    
    # 每个人的交易额,apply(int) 转换为整数
    dataframe.groupby(by = '姓名').sum()['交易额'].apply(int)
    
    # 每一个员工交易额的中值
    data = dataframe.groupby(by = '姓名').median()
    data.head()
    
    data['交易额']
    
    # 查看交易额对应的排名
    data['排名'] = data['交易额'].rank(ascending = False)
    data[['交易额','排名']]
    
    # 每个人不同时段的交易额
    dataframe.groupby(by = ['姓名','时段'])['交易额'].sum()
    
    # 设置各时段累计
    dataframe.groupby(by = ['姓名'])['时段','交易额'].aggregate({'交易额':np.sum,'时段':lambda x:'各时段累计'})
    
    # 对指定列进行聚合,查看最大,最小,和,平均值,中值
    dataframe.groupby(by = '姓名').agg(['max','min','sum','mean','median'])
    
    # 查看部分聚合后的结果
    dataframe.groupby(by = '姓名').agg(['max','min','sum','mean','median'])['交易额']
    
    # 查看交易额低于 2000 的前五条数据
    dataframe[dataframe.交易额 < 2000].head()
    
    # 查看上浮了 50% 之后依旧低于 1500 的交易额,查看 5 条数据
    dataframe.loc[dataframe.交易额 < 1500,'交易额'] = dataframe[dataframe.交易额 < 1500]['交易额'].map(lambda num:num*1.5)
    dataframe[dataframe.交易额 < 1500].head()
    
    # 查看交易额大于 2500 的数据
    dataframe[dataframe.交易额 > 2500]
    
    # 查看交易额低于 900 或 高于 1800 的数据
    dataframe[(dataframe.交易额 < 900)|(dataframe.交易额 > 1800)]
    
    #  将所有低于 200 的交易额都替换成 200
    dataframe.loc[dataframe.交易额 < 200,'交易额'] = 200
    
    # 查看低于 1500 的交易额个数
    dataframe.loc[dataframe.交易额 < 1500,'交易额'].count()
    
    # 将大于 3000 元的都替换为 3000 元
    dataframe.loc[dataframe.交易额 > 3000,'交易额'] = 3000
    
    # 查看有多少行数据
    len(dataframe)
    
    # 丢弃缺失值之后的行数
    len(dataframe.dropna())
    
    # 包含缺失值的行
    dataframe[dataframe['交易额'].isnull()]
    
    # 使用固定值替换缺失值
    dff = copy.deepcopy(dataframe)
    dff.loc[dff.交易额.isnull(),'交易额'] = 999
    # 将缺失值设定为 999
    dff.iloc[[110,124,168],:]
    
    # 使用交易额的均值替换缺失值
    dff = copy.deepcopy(dataframe)
    for i in dff[dff.交易额.isnull()].index:
        dff.loc[i,'交易额'] = round(dff.loc[dff.姓名 == dff.loc[i,'姓名'],'交易额'].mean())
    dff.iloc[[110,124,168],:]
    
    # 使用整体均值的 80% 填充缺失值
    dataframe.fillna({
        '交易额':round(dataframe['交易额'].mean() * 0.8)
    },inplace = True)
    dataframe.iloc[[110,124,168],:]
    
    # 重复值
    dataframe[dataframe.duplicated()]
    
    # 丢弃重复行
    dataframe = dataframe.drop_duplicates()
    dataframe.head()
    
    # 重复值
    dataframe = pd.read_excel('超市营业额.xlsx')
    df = dataframe[['工号','姓名','日期','交易额']]
    dff = df[df.duplicated()]
    for row in dff.values:
        print(df[(df.工号 == row[0]) & (df.日期 == row[2]) &(df.交易额 == row[3])])
    
    # 查看是否有录入错误的工号和姓名
    dff = dataframe[['工号','姓名']]
    dff.drop_duplicates()
    
    # 数据差分
    # 查看员工业绩波动情况(每一天和昨天的数据作比较)
    dff = dataframe.groupby(by = '日期').sum()['交易额'].diff()
    dff.head()
    
    dff.map(lambda num:'%.2f'%(num)).head()
    
    # 数据差分
    # 查看张三的波动情况
    dataframe[dataframe.姓名 == '张三'].groupby(by = '日期').sum()['交易额'].diff().head()
    
    # 读取全部数据,使用默认索引
    data = pd.read_excel('超市营业额.xlsx')
    data.head()
    
    # 修改异常值
    data.loc[data.交易额 > 3000,'交易额'] = 3000
    data.loc[data.交易额 < 200,'交易额'] = 200
    
    # 删除重复值,inplace 表示对源数据也进行修改
    data.drop_duplicates(inplace = True)
    
    # 填充缺失值为交易额的平均值
    data['交易额'].fillna(data['交易额'].mean(),inplace = True)
    
    # 使用交叉表得到每人在各柜台交易额的平均值
    data_group = pd.crosstab(data.姓名,data.柜台,data.交易额,aggfunc = 'mean').apply(round)
    
    plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
    plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
    # 绘制柱状图
    data_group.plot(kind = 'bar')
    
    #  数据的合并
    data1 = pd.read_excel('超市营业额.xlsx')
    data2 = pd.read_excel('超市营业额.xlsx',sheet_name = 'Sheet2')
    df1 = data1.head()
    df2 = data2.head()
    
    df1
    
    df2
    
    # 使用 concat 连接两个相同结构的 DataFrame 对象
    df3 = pd.concat([df1,df2])
    df3
    
    # 合并,忽略原来的索引 ignore_index
    df4 = df3.append([df1,df2],ignore_index = True)
    df4
    
    # 按照列进行拆分
    df5 = df4.loc[:,['姓名','柜台','交易额']]
    # 查看前五条数据
    df5.head()
    
    # 合并 merge 、 join
    # 按照工号进行合并,随机查看 3 条数据
    rows = np.random.randint(0,len(df5),3)
    pd.merge(df4,df5).iloc[rows,:]
    
    # 按照工号进行合并,指定其他同名列的后缀
    pd.merge(df1,df2,on = '工号',suffixes = ['_x','_y']).iloc[:,:]
    
    # 两个表都设置工号为索引 set_index
    df2.set_index('工号').join(df3.set_index('工号'),lsuffix = '_x',rsuffix = '_y').iloc[:]
    
    dataframe = pd.read_excel('超市营业额.xlsx',
                              usecols = ['工号','姓名','时段','交易额','柜台'])
    dataframe.head()
    
    # 按照交易额和工号降序排序,查看五条数据
    dataframe.sort_values(by = ['交易额','工号'],ascending = False).head()
    
    # 按照交易额和工号升序排序,查看五条数据
    dataframe.sort_values(by = ['交易额','工号']).head()
    
    # 按照交易额降序和工号升序排序,查看五条数据
    dataframe.sort_values(by = ['交易额','工号'],ascending = [False,True]).head()
    
    # 按工号升序排序
    dataframe.sort_values(by = ['工号']).head()
    
    dataframe.sort_values(by = ['工号'],na_position = 'last').head()
    # na_position -> nan排序的位置
    
    # 按列名升序排序
    dataframe.sort_index(axis = 1).head()
    
    dataframe.sort_index(axis = 1,ascending = False).head()
    
    # 时间序列
    # 每隔五天--5D
    pd.date_range(start = '20201109',end = '20201130',freq = '5D')
    
    # 每隔一周--W
    pd.date_range(start = '20201109',end = '20201201',freq = 'W')
    
    # 间隔两天,五个数据
    pd.date_range(start = '20201109',periods = 5,freq = '2D')
    # periods 几个数据 ,freq 间隔时期,两天
    
    # 间隔三小时,八个数据
    pd.date_range(start = '20201109',periods = 8,freq = '3H')
    
    # 三点开始,十二个数据,间隔一分钟
    pd.date_range(start = '202011091227',periods = 12,freq = 'T')
    
    # 每个月的最后一天
    pd.date_range(start = '20201109',end = '20210103',freq = 'M')
    
    # 间隔一年,六个数据,年末最后一天
    pd.date_range(start = '20201109',periods = 6,freq = 'A')
    
    # 间隔一年,六个数据,年初最后一天
    pd.date_range(start = '20201109',periods = 6,freq = 'AS')
    
    # 使用 Series 对象包含时间序列对象,使用特定索引
    data = pd.Series(index = pd.date_range(start = '20200321',periods = 24,freq = 'H'),data = range(24))
    data.head()
    
    # 三小时重采样,计算均值
    data.resample('3H').mean()
    
    # 五小时重采样,求和
    data.resample('5H').sum()
    
    # 计算OHLC open,high,low,close
    data.resample('5H').ohlc()
    
    # 将日期替换为第二天
    data.index = data.index + pd.Timedelta('1D')
    data.head()
    
    pd.Timestamp('20201109').day_name()
    
    # 查看指定日期的年份是否是闰年
    pd.Timestamp('20201109').is_leap_year
    
    # 查看指定日期所在的季度和月份
    day = pd.Timestamp('20201109')
    
    # 查看日期的季度
    day.quarter
    
    # 查看日期所在的月份
    day.month
    
    # 转换为 python 的日期时间对象
    day.to_pydatetime()
    
    dataframe = pd.read_excel('超市营业额.xlsx')
    dataframe.head()
    
    # 查看所有的交易额信息
    dataframe['交易额'].describe()
    
    # 查看四分位数
    dataframe['交易额'].quantile([0,0.25,0.5,0.75,1.0])
    
    # 交易额中值
    dataframe['交易额'].median()
    
    # 交易额最小的三个数据
    dataframe['交易额'].nsmallest(3)
    
    dataframe.nsmallest(3,'交易额')
    
    # 交易额最大的两个数据
    dataframe['交易额'].nlargest(2)
    
    # 查看最大的两个交易额数据
    dataframe.nlargest(2,'交易额')
    
    # 查看最后一个日期
    dataframe['日期'].max()
    
    # 查看最小的工号
    dataframe['工号'].min()
    
    # 第一个最小交易额的行下标
    min_index = dataframe['交易额'].idxmin()
    min_index
    
    # 第一个最小交易额
    dataframe.loc[min_index,'交易额']
    
    # 最大交易额的行下标
    max_index = dataframe['交易额'].idxmax()
    max_index
    
    dataframe.loc[max_index,'交易额']
    
    # 读取工号姓名时段交易额,使用默认索引
    dataframe = pd.read_excel('超市营业额.xlsx',
                              usecols = ['工号','姓名','时段','交易额'])
    dataframe.head()
    
    # 查看第 1 3 4 行的第 1 2 列
    dataframe.iloc[[0,2,3],[0,1]]
    
    # 跳过 1 2 4 行,以第一列姓名为索引
    dataframe = pd.read_excel('超市营业额.xlsx',
                               skiprows = [1,2,4],
                               index_col = 1,
                              # header = 1,
                             )
    dataframe.head()
    
    dataframe = pd.read_excel('超市营业额.xlsx')
    dataframe.head()
    
    # 查看第 1 3 4 行的第 1 2 列
    dataframe.iloc[[0,2,3],[0,1]]
    
    # 查看前五行指定,姓名、时段和交易额的数据
    dataframe[['姓名','时段','交易额']].head()
    
    dataframe.head()[['姓名','时段','交易额']]
    
    # 查看第 2 4 5 行 姓名,交易额 数据 loc 函数
    dataframe.loc[[1,3,4],['姓名','交易额']]
    
    # 查看第四行的姓名数据
    dataframe.at[3,'姓名']
    
    # 查看交易额大于 1700 的数据
    dataframe[dataframe['交易额'] > 1700].head()
    
    # 查看交易额总和
    dataframe['交易额'].sum()
    
    # 某一时段的交易总和
    dataframe[dataframe['时段'] == '9:00-14:00']['交易额'].sum()
    
    # 查看张三在9:00-14:00之间的交易情况
    dataframe[(dataframe.姓名 == '张三') & (dataframe.时段 == '9:00-14:00')].head()
    
    # 查看日用品的销售总额
    dataframe[dataframe['柜台'] == '日用品']['交易额'].sum()
    
    # 查看张三总共的交易额
    dataframe[dataframe['姓名'].isin(['张三'])]['交易额'].sum()
    
    # 查看交易额在 1500~1600 之间的记录
    dataframe[dataframe['交易额'].between(1500,1600)].head()
    
    data = pd.read_excel('超市营业额.xlsx')
    data.head()
    
    # 将日期设置为 python 中的日期类型
    data.日期 = pd.to_datetime(data.日期)
    data.head()
    
    # 每七天营业的总额
    data.resample('7D',on = '日期')['交易额'].sum()
    
    # 每七天营业总额
    data.resample('7D',on = '日期',label = 'right')['交易额'].sum()
    
    # 删除工号这一列
    data.drop('工号',axis = 1,inplace = True)
    data.head()
    
    # 按照姓名和柜台进行分组汇总
    data = data.groupby(by = ['姓名','柜台']).sum()
    data.head(4)
    
    # 查看张三的汇总数据
    data.loc['张三',:]
    
    # 查看张三在蔬菜水果的交易数据
    data.loc['张三','蔬菜水果']
    
    # 多索引
    # 重新读取,使用第二列和第六列作为索引,排在前面
    data = pd.read_excel('超市营业额.xlsx',index_col = [1,5])
    data.head()
    
    
    
    # 按照柜台进行排序
    dff = data.sort_index(level = '柜台',axis = 0)
    dff
    
    # 按照柜台进行分组求和
    dff = data.groupby(level = '柜台').sum()['交易额']
    dff.head()
    
    data = pd.DataFrame({'A':[3,3,3,3,3],'B':[1,2,3,4,5],
                         'C':[-5,-4,1,4,5],'D':[-45,15,63,40,50]
                         })
    data
    
    #标准差
    data.std()
    
    # 平均值
    data.mean()
    
    # 标准差的平方
    data.std()**2
    
    # 协方差
    data.cov()
    
    # 指定索引为 姓名,日期,时段,柜台,交易额
    data = pd.read_excel('超市营业额.xlsx',
                         usecols = ['姓名','日期','时段','柜台','交易额']
                        )
    data.head()
    
    # 删除缺失值和重复值,inplace = True 直接丢弃
    data.dropna(inplace = True)
    data.drop_duplicates(inplace = True)
    
    # 处理异常值
    data.loc[data.交易额 < 200,'交易额'] = 200
    data.loc[data.交易额 > 3000,'交易额'] = 3000
    
    # 使用交叉表得到不同员工在不同柜台的交易额平均值
    pd.crosstab(data.姓名,data.柜台,data.交易额,aggfunc = 'mean')
    
    # 查看数据的标准差
    dff.std()

    import random
    
    # choice(seq)
    # 从序列的元素中随机挑选一个元素
    random.choice('Hany')
    
    random.choice(['H','a','n','y'])
    
    # randrange ([start,] stop [,step])
    # 在指定范围内,从步长递增的集合中获取一个随机数,步长默认为 1
    random.randrange(5)
    
    random.randrange(1,5)
    
    random.randrange(1,6,2)
    
    # 随机生成一个实数,在 [0,1) 范围内
    random.random()
    
    # seed([x])
    # 改变随机数生成器的种子seed,种子不同生成的随机数不同
    random.seed(5)
    
    numbers = [7,8,4,5,1,2,3,6,9]
    
    # 将序列内的所有元素顺序打乱
    random.shuffle(numbers)
    numbers
    
    # uniform(x, y)
    # 随机生成一个实数,在[x,y]范围内
    random.uniform(5,10)
    
    # random.randint(x,y)
    # 随机生成一个整数,在[x,y]范围内
    random.randint(3,10)
    
    # random.sample(seq,num)
    # 从 seq 中随机选取 num 个数
    random.sample(numbers,3)

    import re
    
    match_params = '''
    参数         说明
    pattern   匹配的正则表达式
    string    匹配的字符串。
    flags    标志位,用于控制正则表达式的匹配方式
                如:是否区分大小写,多行匹配等
    匹配成功 re.match方法返回一个匹配的对象,否则返回 None
    '''
    
    # 在起始位置匹配
    re.match('abcd', 'abcdefg')
    
    re.match('abcd', 'abcdefg').span()
    
    re.match('efg', 'abcdefg') == None
    
    line = "Cats are smarter than dogs"
    matchObj = re.match( r'(.*) are (.*?) .*',line,re.M|re.I)
    
    group_methods = '''
    group(num=0)  匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
    groups()      返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
    '''
    
    matchObj.group()
    
    matchObj.group(1)
    
    matchObj.group(2)
    
    matchObj.groups()
    
    search_params = '''
    参数         说明
    pattern   匹配的正则表达式
    string    匹配的字符串。
    flags    标志位,用于控制正则表达式的匹配方式
                如:是否区分大小写,多行匹配等
    匹配成功 re.search 方法返回一个匹配的对象,否则返回 None
    '''
    
    print(re.search('www', 'www.runoob.com')) # 在起始位置匹配
    print(re.search('www', 'www.runoob.com').span()) # 在起始位置匹配
    
    print(re.search('com', 'www.runoob.com'))
    print(re.search('com', 'www.runoob.com').span()) # 不在起始位置匹配
    
    searchObj = re.search( r'(.*) are (.*?) .*', "Cats are smarter than dogs", re.M|re.I)
    
    searchObj.group()
    
    searchObj.group(1)
    
    searchObj.group(2)
    
    searchObj.groups()

    import requests
    
    requests.get('https://httpbin.org/get')
    # 发送 get 请求
    
    # 带有参数 , 使用 params 参数
    data = {
        'key':'value'
    }
    requests.get('https://httpbin.org/get',params = data)
    
    # 发送 post 请求
    data = {
        'key':'value'
    }
    requests.post('https://httpbin.org/get',data = data)
    # 405 表示请求的方式不对
    
    # 定义请求头
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36 Edg/86.0.622.58'
    }
    
    response = requests.get('https://httpbin.org/get',headers = headers)
    
    # .content 响应内容的字节码,一般处理二进制文件
    response.content
    
    # 自动选择适当的编码,对 .content解码
    response.text
    
    eval(response.text)['origin']
    # 使用 eval 将字符串转换为字典 , 提取数据
    
    response.json()
    # 解析json格式的数据,如果无法解析,则抛出异常
    
    response.json()['url']
    
    request_params = '''
    requests 方法 请求参数
    
    • url 请求的URL地址
    • params GET请求参数
    • data POST请求参数
    • json 同样是POST请求参数,要求服务端接收json格式的数据
    • headers 请求头字典
    • cookies cookies信息(字典或CookieJar)
    • files 上传文件
    • auth HTTP鉴权信息
    • timeout 等待响应时间,单位秒
    • allow_redirects 是否允许重定向
    • proxies 代理信息
    • verify 是否校验证书
    • stream 如果为False,则响应内容将直接全部下载
    • cert 客户端证书地址
    
    '''
    
    
    Session = '''
    Session可以持久化请求过程中的参数,以及cookie
    需要登录的网页,使用session可以避免每次的登录操作
    '''
    s = requests.Session()
    s.cookies
    
    s.cookies = requests.cookies.cookiejar_from_dict({'key': 'value'})
    # 修改 cookie 的信息
    s.cookies
    
    r = s.get('https://httpbin.org/cookies')
    r.text
    
    '''
    Session 提供默认值
    
    '''
    s = requests.Session()
    s.headers.update(
        {'h1':'val1',
        'h2':'val2'}
    )
    
    r = s.get('https://httpbin.org/headers', headers={'h2': 'val2_modify'})
    r.text
    
    Response = '''
    
    字段
    
    • cookies 返回CookieJar对象
    • encoding 报文的编码
    • headers 响应头
    • history 重定向的历史记录
    • status_code 响应状态码,如200
    • elaspsed 发送请求到接收响应耗时
    • text 解码后的报文主体
    • content 字节码,可能在raw的基础上解压
    
    方法
    
    • json() 解析json格式的响应
    • iter_content() 需配置stream=True,指定chunk_size大小
    • iter_lines() 需配置stream=True,每次返回一行
    • raise_for_status() 400-500之间将抛出异常
    • close()
    
    '''

    import urllib.request
    import urllib.parse
    import urllib.error
    import socket
    
    response = urllib.request.urlopen('https://www.python.org')
    response
    
    # 返回网页内容
    response.read().decode('utf-8')
    
    #返回响应头中的server值
    response.getheader('server')
    
    #以列表元组对的形式返回响应头信息
    response.getheaders()
    
    response.version
    # #返回版本信息
    
    response.status
    # #返回状态码200,404代表网页未找到
    
    response.debuglevel
    # 返回调试等级
    
    response.closed
    # 返回对象是否关闭
    
    response.geturl()
    # 返回当前 url
    
    response.info()
    # 返回网页的头信息
    
    response.getcode()
    # 返回响应的HTTP状态码
    
    response.msg
    # 访问成功返回 OK
    
    response.reason
    # 返回状态信息
    
    urlopen_params = '''
    urlopen()方法可传递参数
    
    url:网站地址,str类型,也可以是一个request对象
    
    data:data参数是可选的,内容为字节流编码格式的即bytes类
    
    如果传递data参数,urlopen将使用Post方式请求
    '''
    
    
    data = bytes(
        urllib.parse.urlencode(
            {'word':'hello'}
        ),encoding = "utf-8"
    )
    
    response = urllib.request.urlopen('http://httpbin.org/post',data=data)
    response.read()
    
    other_params = '''
    timeout参数:用于设置超时时间,单位为秒,
    
    如果请求超出了设置时间 还未得到响应则抛出异常,
    
    支持HTTP,HTTPS,FTP请求
    
    context参数:必须是ssl.SSLContext类型,用来指定SSL设置
    
    cafile和capath这两个参数分别指定CA证书和它的路径,会在https链接时用到
    
    '''
    
    Requset_params = '''
    url:请求的URL,必须传递的参数
    
    data:上传的数据,必须传bytes字节流类型的数据
        如果是字典,可以先用 urllib.parse 模块里的 urlencode() 编码
    
    headers:字典,传递请求头数据,可以通过它构造请求头,也可以通过调用请求实例的方法 add_header() 添加
    
    origin_req_host:指请求方的 host名称 或者 IP地址
    
    unverifiable:表示这个请求是否是无法验证的,默认为False,
        例如请求一张图片如果没有权限获取图片,则值为 True
        
    method:是一个字符串,用来指示请求使用的方法,如:GET,POST,PUT 等
    
    '''
    
    url = 'http://httpbin.org/post'
    # url
    headers = {
        'User-Agent':'Mozilla/5.0 (compatible; MSIE 5.5; Windows NT)',
        'Host':'httpbin.org'
    }  #定义头信息
    
    name_dict = {'name':'Hany'}
    # 字典
    data = bytes(urllib.parse.urlencode(name_dict),encoding='utf-8')
    # 转化为 bytes 数据
    req = urllib.request.Request(url=url,data=data,headers=headers,method='POST')
    # 发送请求
    response = urllib.request.urlopen(req) 
    # 打开请求
    response.read()
    # 获取内容
    
    Base_Handler = '''
    是所有其他 Handler 的父类
    处理登录验证,处理cookies,代理设置,重定向等
    
    提供了方法:
    add_parent(director):添加director作为父类
    
    close():关闭它的父类
    
    parent():打开使用不同的协议或处理错误
    
    defautl_open(req):捕获所有的URL及子类,在协议打开之前调用
    
    Handler的子类包括:
    
    HTTPDefaultErrorHandler:
    用来处理http响应错误,错误会抛出HTTPError类的异常
    
    HTTPRedirectHandler:
    用于处理重定向
    
    HTTPCookieProcessor:
    用于处理cookies
    
    ProxyHandler:
    用于设置代理,默认代理为空
    
    HTTPPasswordMgr:
    永远管理密码,它维护用户名和密码表
    
    HTTPBasicAuthHandler:
    用户管理认证,如果一个链接打开时需要认证,可以使用它来实现验证功能
    
    '''
    
    Opener_Director = '''
    它分三个阶段来打开URL:
    调用方法的顺序是通过对处理程序实例 进行排序来确定的
    
    每个使用此类方法的程序都会
    1.调用 protocol_request()方法来预处理请求
    2.然后调用 protocol_open() 来处理请求
    3.最后调用 protocol_response() 方法来处理响应。
    
    之前的 urlopen() 方法就是 urllib 提供的一个Opener
    通过 Handler 处理器来构建 Opener 实现 Cookies 处理,代理设置,密码设置等
    
    '''
    
    Opener_method = '''
    add_handler(handler):添加处理程序到链接中
    
    open(url,data=None[,timeout]):打开给定的URL与urlopen()方法相同
    
    error(proto,*args):处理给定协议的错误
    '''

    import wordcloud
    import jieba
    import pandas as pd
    import numpy as np
    from PIL import Image
    import matplotlib.pyplot as plt
    
    WordCloud_params = '''
    参数                   说明
    background_color     背景颜色
    max_words            最大词数
    mask                 以某种形状进行绘制词云
    stopwords            添加屏蔽词
    font_path            更改字体
    random_state         为每一个词返回一个 PIL 颜色
    width                图片的宽
    height               图片的高
    '''   
    
    df = pd.read_csv('GDP数据.csv')
    # 删除空值
    df.dropna(inplace=True)
    # 清理重复值
    df.duplicated()
    df.describe()
    
    city_name = ''
    # 国家的名称
    city_lst = list(df['国家'])
    # 国家的集合
    for i in range(len(df)):
        city_name += city_lst[i]
    ls = jieba.lcut(city_name)
    txt = " ".join(ls)
    w = wordcloud.WordCloud(
        font_path=r'C:WindowsFontsSTXINWEI.TTF',
        width = 1000,height = 700,background_color = "white",
        )
    
    w.generate(txt)
    w.to_file("国家的词云图.png")
    plt.imshow(w)
    
    
    color_mask = np.array(Image.open("beijing.png"))
    f = open('bookComments.txt','r',encoding ='gbk')
    txt = f.read()
    w =  wordcloud.WordCloud(
        font_path=" C:\Windows\Fonts\STXINGKA.TTF",
                           background_color="white",
                           width=800,
                           height=600,
                           max_words=200,
                           max_font_size=80,
                           mask=color_mask,
                           ).generate(txt)
    w.to_file('京东词云.png')
    plt.imshow(w)

    2021-03-10

    如果觉得文章不错,可以分享给其他人哟~
  • 相关阅读:
    GOF23设计模式之建造者模式
    GOF23设计模式之工厂模式
    GOF23设计模式之单例模式
    服务端字节流输出图片
    小记常见的会话跟踪技术
    Java生成随机数的三种方式
    因为new Date(),我给IE跪了
    ionic初体验
    cordova开发环境搭建
    gradle环境搭建
  • 原文地址:https://www.cnblogs.com/hany-postq473111315/p/14510404.html
Copyright © 2020-2023  润新知