<?xml version="1.0" encoding="utf-8"?>
<search> 
  
  
    
    <entry>
      <title>SM.MS图片资源下载</title>
      <link href="posts/43947/"/>
      <url>posts/43947/</url>
      
        <content type="html"><![CDATA[<p>SM.MS是个不错的图床工具，上传的图片资源虽然不能批量一键下载，但官方还是提供了一个获取图片列表的API：<code>https://sm.ms/api/v2/upload_history</code>，header中只需要提供一个<code>Authorization</code>认证码即可，好长时间没写python了，想练练手，就不用API了</p><p>之前爬取需要登陆的网站我都是通过Selenium完成，尝试换个姿势，通过<code>requests.Session</code>实现？首先分析下SM.MS网站的登陆流程：<br><img src="https://s2.loli.net/2023/12/28/1W3fAQjaXLrcwOy.png" alt=""></p><p>使用<a href="https://www.telerik.com/fiddler/fiddler-classic">fiddler</a>抓包查看表单请求内容：<br><img src="https://s2.loli.net/2023/12/28/mq29skrT3BRALaJ.png" alt=""></p><p>唯一的障碍点其实就是g-recaptcha-response字段值的获取（我本想通过<code>execjs</code>模块执行JS代码），sm.ms通过<code>&lt;script src=&quot;https://recaptcha.google.cn/recaptcha/api.js?render=6LdArYchAAAAADs9BJEP0Ud-MpC54mNN90Bp0BvK&quot;&gt;&lt;/script&gt;</code>获得了一个grecaptcha对象，然后调用<code>grecaptcha.execute()</code>得到了g-recaptcha-response字段值，然而execjs主要是一个在非浏览器环境中执行JS代码的工具，因此涉及到浏览器特有对象（如window、document）的代码在这个环境下通常是无法正常工作的<br><img src="https://s2.loli.net/2023/12/28/b9o4jydHQ5CcPVs.png" alt=""></p><p>好吧，姿势更换失败，还是只能通过selenium(+chrome)爬取SM.MS图片数据了，但是为了尽量寻求较优的实现方案，我只会用selenium完成登陆操作，之后就可以拿到网站cookie，再用requests库携cookie请求个人图片资源列表、下载图片数据，毕竟如果是做大规模图片爬取的话，使用selenium速度实在太慢了，肯定得用并发URL请求下载资源，而且很多境外服务器一次网络请求都有可能是以秒为单位，单线程下载不得等到地老天荒啊，对于python来说，爬虫属于网络IO密集型任务，因此直接用线程模块即可或者上线程池<br><img src="https://s2.loli.net/2023/12/28/mYcfxrsvuzGEetp.png" alt=""></p><p>其实要确定请求头参数有个更好的办法，直接F12找到网络请求链接右键Copy as cURL（还可以顺便cmd执行一下看看能否成功）：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">curl &quot;https://sm.ms/home/picture&quot; ^</span><br><span class="line">  -v ^</span><br><span class="line">  -H &quot;authority: sm.ms&quot; ^</span><br><span class="line">  -H &quot;accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7&quot; ^</span><br><span class="line">  -H &quot;accept-language: zh-CN,zh;q=0.9&quot; ^</span><br><span class="line">  -H &quot;cookie: PHPSESSID=xxx; smms=yyy&quot; ^</span><br><span class="line">  -H &quot;sec-ch-ua: ^\^&quot;Not_A Brand^\^&quot;;v=^\^&quot;8^\^&quot;, ^\^&quot;Chromium^\^&quot;;v=^\^&quot;120^\^&quot;, ^\^&quot;Google Chrome^\^&quot;;v=^\^&quot;120^\^&quot;&quot; ^</span><br><span class="line">  -H &quot;sec-ch-ua-mobile: ?0&quot; ^</span><br><span class="line">  -H &quot;sec-ch-ua-platform: ^\^&quot;Windows^\^&quot;&quot; ^</span><br><span class="line">  -H &quot;sec-fetch-dest: document&quot; ^</span><br><span class="line">  -H &quot;sec-fetch-mode: navigate&quot; ^</span><br><span class="line">  -H &quot;sec-fetch-site: none&quot; ^</span><br><span class="line">  -H &quot;sec-fetch-user: ?1&quot; ^</span><br><span class="line">  -H &quot;upgrade-insecure-requests: 1&quot; ^</span><br><span class="line">  -H &quot;user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36&quot; ^</span><br><span class="line">  --compressed</span><br></pre></td></tr></table></figure><p>执行<code>request.get(url, cookie)</code>报错：OpenSSL.SSL.Error: [(‘SSL routines’, ‘ssl3_get_server_certificate’, ‘certificate verify failed’)]，意思是对于sm.ms服务器发过来的证书验证失败了，解决办法就是在get方法中传递<code>verify</code>参数以指定用于验证的CA根证书，从sm.ms网站下载用于验证的根证书（链），crt格式，然后用XCA转换为单个pem格式证书：<br><img src="https://s2.loli.net/2023/12/28/s5femCpoaSUh7DA.png" alt=""></p><p>获取到所有图片资源的URL列表，就可以通过get请求下载二进制图片了，经过一系列操作，我得到了一个用字典构建的图片数据库<code>db</code>，其键值对定义如下：<code>&lt;img_unique_key : [img_name, url, size, upload_date, download_flag, local_path]&gt;</code>，其中<code>download_flag</code>指示其是否已被下载到本地，只有为否的图片url才需要提交给线程池通过<code>request</code>执行下载，<code>local_path</code>是图片的本地下载路径。通过线程池下载实现：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">urls = &#123;k:v[<span class="number">1</span>] <span class="keyword">for</span> k,v <span class="keyword">in</span> db.items() <span class="keyword">if</span> v[-<span class="number">2</span>]==<span class="literal">False</span>&#125; <span class="comment">#find all pictures not downloaded</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">download_url</span>(<span class="params">url, timeout</span>):</span><br><span class="line">    r = requests.get(url, timeout=timeout)</span><br><span class="line">    <span class="keyword">if</span> r.ok:</span><br><span class="line">        <span class="keyword">return</span> r.content</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">None</span></span><br><span class="line"><span class="keyword">with</span> concurrent.futures.ThreadPoolExecutor(max_workers=<span class="number">36</span>) <span class="keyword">as</span> workers:</span><br><span class="line">    future_download = &#123;workers.submit(download_url, url, timeout=<span class="number">6</span>):key <span class="keyword">for</span> key,url <span class="keyword">in</span> urls.items()&#125;</span><br><span class="line">    <span class="keyword">for</span> task <span class="keyword">in</span> as_completed(future_download):</span><br><span class="line">        img_key = future_download(task)</span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            img_byte = task.result()</span><br><span class="line">        <span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">f&#x27;Error: download <span class="subst">&#123;db[img_key][<span class="number">1</span>]&#125;</span> failed for <span class="subst">&#123;e&#125;</span>&#x27;</span>)</span><br><span class="line">            <span class="keyword">continue</span></span><br><span class="line">        <span class="keyword">if</span> img_byte <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line">            <span class="keyword">continue</span></span><br><span class="line">        db[img_key][-<span class="number">2</span>] = <span class="literal">True</span></span><br><span class="line">        save_img_to_local(img_byte, local_path)</span><br><span class="line">        db[img_key][-<span class="number">1</span>] = local_path</span><br><span class="line">save_db_to_local(db)</span><br></pre></td></tr></table></figure><p>最后我又将图片数据库<code>db</code>导出为一个简易html页面：<br><img src="https://cdn.statically.io/gh/muggledy/smms_download/master/images_summary_demo.png" alt=""></p><p>完整代码见github仓库<a class='hassan' href='https://github.com/muggledy/smms_download'>smms_download</a>，支持增量更新</p>]]></content>
      
      
      
        <tags>
            
            <tag> Python </tag>
            
            <tag> 爬虫 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>Pytorch入门教程</title>
      <link href="posts/35908/"/>
      <url>posts/35908/</url>
      
        <content type="html"><![CDATA[<h2 id="反向传播">反向传播</h2><p>简单介绍一下BP算法：</p><ul><li>给定一个输入<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">x</span></span></span></span>（列向量），前向传播得到预测值<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>h</mi><mrow><mi>W</mi><mo separator="true">,</mo><mi>b</mi></mrow></msub><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">h_{W,b}(x)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.036108em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span>，其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>W</mi><mo separator="true">,</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">W,b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span></span></span></span>是网络参数</li><li>根据标签值<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span></span>与预测值的误差（此处以均方误差为例）对网络参数进行更新，该过程是从后向前的，称为反向传播<br><img src="https://cdn.statically.io/gh/celestezj/ImageHosting/v3.4/img/20210608095528.png" alt="图1. 反向传播示例（黑色箭头代表前向传播，红色箭头代表反向传播" style="width:100%"></li></ul><div class="notdisplayonphone"><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>详细推导</span></div>    <div class="hide-content"><p>相关符号定义：</p><ul><li>网络的总层数设为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>n</mi><mi>l</mi></msub></mrow><annotation encoding="application/x-tex">n_l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>，那么倒数第二层就是第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">n_l-1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>层，网络层数<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi></mrow><annotation encoding="application/x-tex">l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span>取值范围为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mn>1</mn><mo separator="true">,</mo><msub><mi>n</mi><mi>l</mi></msub><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[1,n_l]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">]</span></span></span></span>，特别的，第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>层为输入层，第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>n</mi><mi>l</mi></msub></mrow><annotation encoding="application/x-tex">n_l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>层为输出层</li><li>网络权重和偏置<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>W</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo><mo>:</mo><mo>=</mo><mo stretchy="false">(</mo><msup><mi>W</mi><mn>1</mn></msup><mo separator="true">,</mo><msup><mi>b</mi><mn>1</mn></msup><mo separator="true">,</mo><msup><mi>W</mi><mn>2</mn></msup><mo separator="true">,</mo><msup><mi>b</mi><mn>2</mn></msup><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msup><mi>W</mi><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msup><mo separator="true">,</mo><msup><mi>b</mi><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(W,b):=(W^1,b^1,W^2,b^2,...,W^{n_l-1},b^{n_l-1})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span></span><span class="base"><span class="strut" style="height:0.36687em;vertical-align:0em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>，设<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi>W</mi><mrow><mi>i</mi><mo separator="true">,</mo><mi>j</mi></mrow><mi>l</mi></msubsup></mrow><annotation encoding="application/x-tex">W_{i,j}^l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.2438799999999999em;vertical-align:-0.394772em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.441336em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.394772em;"><span></span></span></span></span></span></span></span></span></span>表示第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi></mrow><annotation encoding="application/x-tex">l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span>层的第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>j</mi></mrow><annotation encoding="application/x-tex">j</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.85396em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span></span></span></span>个节点与第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">l+1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>层的第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathnormal">i</span></span></span></span>个节点之间的连接权重值，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi>b</mi><mi>i</mi><mi>l</mi></msubsup></mrow><annotation encoding="application/x-tex">b_i^l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.107772em;vertical-align:-0.258664em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.441336em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.258664em;"><span></span></span></span></span></span></span></span></span></span>表示第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">l+1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>层的第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathnormal">i</span></span></span></span>个节点的偏置项</li><li>记<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi>z</mi><mi>i</mi><mi>l</mi></msubsup></mrow><annotation encoding="application/x-tex">z_i^l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.107772em;vertical-align:-0.258664em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.441336em;margin-left:-0.04398em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.258664em;"><span></span></span></span></span></span></span></span></span></span>为第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi></mrow><annotation encoding="application/x-tex">l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span>层的第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathnormal">i</span></span></span></span>个节点的输入加权和（<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi>z</mi><mi>i</mi><mi>l</mi></msubsup><mo>=</mo><msubsup><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>1</mn></mrow><msub><mi>S</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msub></msubsup><mo stretchy="false">(</mo><msubsup><mi>W</mi><mrow><mi>i</mi><mi>j</mi></mrow><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msubsup><msubsup><mi>a</mi><mi>j</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msubsup><mo stretchy="false">)</mo><mo>+</mo><msubsup><mi>b</mi><mi>i</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msubsup></mrow><annotation encoding="application/x-tex">z_i^{l}=\sum\limits_{j=1}^{S_{l-1}}(W_{ij}^{l-1}a_j^{l-1})+b_i^{l-1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.107772em;vertical-align:-0.258664em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.441336em;margin-left:-0.04398em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.258664em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.700638em;vertical-align:-1.113777em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.586861em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-4.00853em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.34480000000000005em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.21074999999999994em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.113777em;"><span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8892389999999999em;"><span style="top:-2.4231360000000004em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span><span style="top:-3.1031310000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.412972em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8892389999999999em;"><span style="top:-2.4231360000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.1031310000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.412972em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.166103em;vertical-align:-0.276864em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8892389999999999em;"><span style="top:-2.4231360000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.1031310000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.276864em;"><span></span></span></span></span></span></span></span></span></span>），记<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi>a</mi><mi>i</mi><mi>l</mi></msubsup></mrow><annotation encoding="application/x-tex">a_i^l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.107772em;vertical-align:-0.258664em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.441336em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.258664em;"><span></span></span></span></span></span></span></span></span></span>为第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi></mrow><annotation encoding="application/x-tex">l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span>层的第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathnormal">i</span></span></span></span>个节点的激活输出</li><li>记<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>S</mi><mi>l</mi></msub></mrow><annotation encoding="application/x-tex">S_l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>为第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi></mrow><annotation encoding="application/x-tex">l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span>层的节点数</li></ul><p>以第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi></mrow><annotation encoding="application/x-tex">l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span>层为例，其输入是<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>a</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msup><mo>∈</mo><msup><mi>R</mi><mrow><msub><mi>S</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">a^{l-1}\in R^{S_{l-1}\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8882079999999999em;vertical-align:-0.0391em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.34480000000000005em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.21074999999999994em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>，该层的权重矩阵为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>W</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msup><mo>=</mo><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msubsup><mi>W</mi><mn>11</mn><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msubsup></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><msubsup><mi>W</mi><mn>21</mn><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msubsup></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mo lspace="0em" rspace="0em">⋯</mo></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><msubsup><mi>W</mi><mrow><msub><mi>S</mi><mi>l</mi></msub><mo separator="true">,</mo><mn>1</mn></mrow><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msubsup></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msubsup><mi>W</mi><mn>12</mn><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msubsup></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><msubsup><mi>W</mi><mn>22</mn><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msubsup></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mo lspace="0em" rspace="0em">⋯</mo></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><msubsup><mi>W</mi><mrow><msub><mi>S</mi><mi>l</mi></msub><mo separator="true">,</mo><mn>2</mn></mrow><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msubsup></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi><mi mathvariant="normal">⋮</mi><mpadded height="+0em" voffset="0em"><mspace mathbackground="black" width="0em" height="1.5em"></mspace></mpadded></mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi><mi mathvariant="normal">⋮</mi><mpadded height="+0em" voffset="0em"><mspace mathbackground="black" width="0em" height="1.5em"></mspace></mpadded></mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mo lspace="0em" rspace="0em">⋱</mo></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi><mi mathvariant="normal">⋮</mi><mpadded height="+0em" voffset="0em"><mspace mathbackground="black" width="0em" height="1.5em"></mspace></mpadded></mi></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msubsup><mi>W</mi><mrow><mn>1</mn><mo separator="true">,</mo><msub><mi>S</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msub></mrow><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msubsup></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><msubsup><mi>W</mi><mrow><mn>2</mn><mo separator="true">,</mo><msub><mi>S</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msub></mrow><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msubsup></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mo lspace="0em" rspace="0em">⋯</mo></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><msubsup><mi>W</mi><mrow><msub><mi>S</mi><mi>l</mi></msub><mo separator="true">,</mo><msub><mi>S</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msub></mrow><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msubsup></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow><mo>∈</mo><msup><mi>R</mi><mrow><msub><mi>S</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>×</mo><msub><mi>S</mi><mi>l</mi></msub></mrow></msup></mrow><annotation encoding="application/x-tex">W^{l-1}=\begin{bmatrix}W_{11}^{l-1}&amp;W_{21}^{l-1}&amp;\cdots&amp;W_{S_l,1}^{l-1}\\W_{12}^{l-1}&amp;W_{22}^{l-1}&amp;\cdots&amp;W_{S_l,2}^{l-1}\\\vdots&amp;\vdots&amp;\ddots&amp;\vdots\\W_{1,S_{l-1}}^{l-1}&amp;W_{2,S_{l-1}}^{l-1}&amp;\cdots&amp;W_{S_l,S_{l-1}}^{l-1}\end{bmatrix}\in R^{S_{l-1}\times S_l}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8491079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:5.828051em;vertical-align:-2.6640255em;"></span><span class="minner"><span class="mopen"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.953995em;"><span style="top:-1.3499850000000007em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎣</span></span></span><span style="top:-2.4999850000000006em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.0959850000000007em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.6919850000000003em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.712975em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-4.953995em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎡</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.4500349999999997em;"><span></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.1640254999999997em;"><span style="top:-5.962286499999999em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8892389999999999em;"><span style="top:-2.433692em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.1031310000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.266308em;"><span></span></span></span></span></span></span></span></span><span style="top:-4.6434085em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8892389999999999em;"><span style="top:-2.433692em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mord mtight">2</span></span></span></span><span style="top:-3.1031310000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.266308em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.7137694999999997em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord">⋮</span><span class="mord rule" style="border-right-width:0em;border-top-width:1.5em;bottom:0em;"></span></span></span></span><span style="top:-1.4645304999999997em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8892389999999999em;"><span style="top:-2.4064690000000004em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.34480000000000005em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.21074999999999994em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.1031310000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4410559999999999em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.6640255em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.1640254999999997em;"><span style="top:-5.962286499999999em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8892389999999999em;"><span style="top:-2.433692em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.1031310000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.266308em;"><span></span></span></span></span></span></span></span></span><span style="top:-4.6434085em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8892389999999999em;"><span style="top:-2.433692em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">2</span></span></span></span><span style="top:-3.1031310000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.266308em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.7137694999999997em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord">⋮</span><span class="mord rule" style="border-right-width:0em;border-top-width:1.5em;bottom:0em;"></span></span></span></span><span style="top:-1.4645304999999997em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8892389999999999em;"><span style="top:-2.4064690000000004em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.34480000000000005em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.21074999999999994em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.1031310000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4410559999999999em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.6640255em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.1640254999999997em;"><span style="top:-5.774786499999999em;"><span class="pstrut" style="height:3.5em;"></span><span class="mord"><span class="minner">⋯</span></span></span><span style="top:-4.4559085em;"><span class="pstrut" style="height:3.5em;"></span><span class="mord"><span class="minner">⋯</span></span></span><span style="top:-2.5262694999999997em;"><span class="pstrut" style="height:3.5em;"></span><span class="mord"><span class="minner">⋱</span></span></span><span style="top:-1.2770304999999997em;"><span class="pstrut" style="height:3.5em;"></span><span class="mord"><span class="minner">⋯</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.6640255em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.1640254999999997em;"><span style="top:-5.962286499999999em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8892389999999999em;"><span style="top:-2.4064690000000004em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mpunct mtight">,</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.1031310000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.429639em;"><span></span></span></span></span></span></span></span></span><span style="top:-4.6434085em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8892389999999999em;"><span style="top:-2.4064690000000004em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mpunct mtight">,</span><span class="mord mtight">2</span></span></span></span><span style="top:-3.1031310000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.429639em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.7137694999999997em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord">⋮</span><span class="mord rule" style="border-right-width:0em;border-top-width:1.5em;bottom:0em;"></span></span></span></span><span style="top:-1.4645304999999997em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8892389999999999em;"><span style="top:-2.4064690000000004em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.34480000000000005em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.21074999999999994em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.1031310000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4410559999999999em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.6640255em;"><span></span></span></span></span></span></span></span><span class="mclose"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.953995em;"><span style="top:-1.3499850000000007em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎦</span></span></span><span style="top:-2.4999850000000006em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.0959850000000007em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.6919850000000003em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.712975em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-4.953995em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎤</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.4500349999999997em;"><span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.34480000000000005em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.21074999999999994em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>，偏置项为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>b</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msup><mo>∈</mo><msup><mi>R</mi><mrow><msub><mi>S</mi><mi>l</mi></msub><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">b^{l-1}\in R^{S_l\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8882079999999999em;vertical-align:-0.0391em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>，于是第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi></mrow><annotation encoding="application/x-tex">l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span>层的输出为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>a</mi><mi>l</mi></msup><mo>=</mo><mi>σ</mi><mo stretchy="false">(</mo><msup><mi>z</mi><mi>l</mi></msup><mo stretchy="false">)</mo><mo>=</mo><mi>σ</mi><mo stretchy="false">(</mo><mo stretchy="false">(</mo><msup><mi>W</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msup><msup><mo stretchy="false">)</mo><mi>T</mi></msup><msup><mi>a</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msup><mo>+</mo><msup><mi>b</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msup><mo stretchy="false">)</mo><mo>∈</mo><msup><mi>R</mi><mrow><msub><mi>S</mi><mi>l</mi></msub><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">a^l=\sigma(z^l)=\sigma((W^{l-1})^Ta^{l-1}+b^{l-1})\in R^{S_l\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.849108em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.099108em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.0991079999999998em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0991079999999998em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>，其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>σ</mi><mo stretchy="false">(</mo><mo separator="true">⋅</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\sigma(·)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mpunct">⋅</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mclose">)</span></span></span></span>为激活函数。事实上，要求损失函数<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>L</mi><mo>=</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mi mathvariant="normal">∥</mi><msub><mi>h</mi><mrow><mi>W</mi><mo separator="true">,</mo><mi>b</mi></mrow></msub><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>−</mo><mi>y</mi><msup><mi mathvariant="normal">∥</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">L=\frac{1}{2}\|h_{W,b}(x)-y\|^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">L</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">∥</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord"><span class="mord">∥</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span>对权重的偏导，核心是计算其对<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>z</mi></mrow><annotation encoding="application/x-tex">z</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span></span></span></span>（任意节点的输入加权和）的偏导，这又分为两种情况，一是输出层，二是非输出层，就是简单的链式求导：</p><ul><li>输出层<br><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>i</mi><msub><mi>n</mi><mi>l</mi></msub></msubsup></mrow></mfrac><mo>=</mo><mfrac><mi mathvariant="normal">∂</mi><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>i</mi><msub><mi>n</mi><mi>l</mi></msub></msubsup></mrow></mfrac><mo stretchy="false">(</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><msubsup><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>1</mn></mrow><msub><mi>S</mi><msub><mi>n</mi><mi>l</mi></msub></msub></msubsup><mo stretchy="false">(</mo><msubsup><mi>a</mi><mi>j</mi><msub><mi>n</mi><mi>l</mi></msub></msubsup><mo>−</mo><msub><mi>y</mi><mi>j</mi></msub><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><msubsup><mi>a</mi><mi>i</mi><msub><mi>n</mi><mi>l</mi></msub></msubsup><mo>−</mo><msub><mi>y</mi><mi>i</mi></msub><mo stretchy="false">)</mo><mfrac><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>a</mi><mi>i</mi><msub><mi>n</mi><mi>l</mi></msub></msubsup></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>i</mi><msub><mi>n</mi><mi>l</mi></msub></msubsup></mrow></mfrac><mo>=</mo><mo stretchy="false">(</mo><msubsup><mi>a</mi><mi>i</mi><msub><mi>n</mi><mi>l</mi></msub></msubsup><mo>−</mo><msub><mi>y</mi><mi>i</mi></msub><mo stretchy="false">)</mo><msup><mi>σ</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><msubsup><mi>z</mi><mi>i</mi><msub><mi>n</mi><mi>l</mi></msub></msubsup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\frac{\partial L}{\partial z_i^{n_l}}=\frac{\partial}{\partial z_i^{n_l}}(\frac{1}{2}\sum\limits_{j=1}^{S_{n_l}}(a_j^{n_l}-y_j)^2)=(a_i^{n_l}-y_i)\frac{\partial a_i^{n_l}}{\partial z_i^{n_l}}=(a_i^{n_l}-y_i)\sigma^{\prime}(z_i^{n_l})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.5471679999999997em;vertical-align:-0.6670599999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.5585400000000003em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9020857142857143em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.0945428571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6670599999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.8280330000000005em;vertical-align:-1.113777em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.5585400000000003em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9020857142857143em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.0945428571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6670599999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mopen">(</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7142560000000002em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-4.135925em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1645428571428572em;"><span style="top:-2.3569999999999998em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.39274285714285706em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.113777em;"><span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7520519999999999em;"><span style="top:-2.4231360000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.1506600000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.412972em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1002159999999999em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.028916em;vertical-align:-0.276864em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7520519999999999em;"><span style="top:-2.4231360000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.1506600000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.276864em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.83412em;vertical-align:-0.6670599999999999em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.16706em;"><span style="top:-2.5585400000000003em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9020857142857143em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.0945428571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.5356em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9020857142857143em;"><span style="top:-2.177714285714286em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.0945428571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6670599999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.028916em;vertical-align:-0.276864em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7520519999999999em;"><span style="top:-2.4231360000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.1506600000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.276864em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.028916em;vertical-align:-0.276864em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7520519999999999em;"><span style="top:-2.4231360000000004em;margin-left:-0.04398em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.1506600000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.276864em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span></li><li>非输出层<br>以倒数第二层为例，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>i</mi><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><mo>=</mo><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mn>1</mn><msub><mi>n</mi><mi>l</mi></msub></msubsup></mrow></mfrac><mfrac><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mn>1</mn><msub><mi>n</mi><mi>l</mi></msub></msubsup></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>i</mi><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><mo>+</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo>+</mo><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><msub><mi>S</mi><msub><mi>n</mi><mi>l</mi></msub></msub><msub><mi>n</mi><mi>l</mi></msub></msubsup></mrow></mfrac><mfrac><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><msub><mi>S</mi><msub><mi>n</mi><mi>l</mi></msub></msub><msub><mi>n</mi><mi>l</mi></msub></msubsup></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>i</mi><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><mo>=</mo><msubsup><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>1</mn></mrow><msub><mi>S</mi><msub><mi>n</mi><mi>l</mi></msub></msub></msubsup><mo stretchy="false">(</mo><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>j</mi><msub><mi>n</mi><mi>l</mi></msub></msubsup></mrow></mfrac><mfrac><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>j</mi><msub><mi>n</mi><mi>l</mi></msub></msubsup></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>i</mi><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><mo stretchy="false">)</mo><mo>=</mo><msubsup><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>1</mn></mrow><msub><mi>S</mi><msub><mi>n</mi><mi>l</mi></msub></msub></msubsup><mo stretchy="false">(</mo><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>j</mi><msub><mi>n</mi><mi>l</mi></msub></msubsup></mrow></mfrac><msubsup><mi>W</mi><mrow><mi>j</mi><mi>i</mi></mrow><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msubsup><msup><mi>σ</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><msubsup><mi>z</mi><mi>i</mi><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msubsup><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\frac{\partial L}{\partial z_i^{n_l-1}}=\frac{\partial L}{\partial z_1^{n_l}}\frac{\partial z_1^{n_l}}{\partial z_i^{n_l-1}}+...+\frac{\partial L}{\partial z_{S_{n_l}}^{n_l}}\frac{\partial z_{S_{n_l}}^{n_l}}{\partial z_i^{n_l-1}}=\sum\limits_{j=1}^{S_{n_l}}(\frac{\partial L}{\partial z_j^{n_l}}\frac{\partial z_j^{n_l}}{\partial z_i^{n_l-1}})=\sum\limits_{j=1}^{S_{n_l}}(\frac{\partial L}{\partial z_j^{n_l}}W_{ji}^{n_l-1}\sigma^{\prime}(z_i^{n_l-1}))</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.6541079999999997em;vertical-align:-0.7739999999999998em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.4516em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0548571428571427em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.0945428571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7739999999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.9335199999999997em;vertical-align:-0.7739999999999998em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.5585400000000003em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9020857142857142em;"><span style="top:-2.188485714285714em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">1</span></span></span><span style="top:-3.094542857142857em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.31151428571428574em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6595199999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.1595199999999999em;"><span style="top:-2.4516em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0548571428571427em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.0945428571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.52806em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9020857142857142em;"><span style="top:-2.188485714285714em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">1</span></span></span><span style="top:-3.094542857142857em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.31151428571428574em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7739999999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.4075699999999998em;vertical-align:-0.9537849999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.55854em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9020857142857143em;"><span style="top:-2.160707142857143em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.2305600000000001em;"><span style="top:-2.3em;margin-left:-0.05764em;margin-right:0.1em;"><span class="pstrut" style="height:2.5em;"></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5496399999999999em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.0945428571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7318928571428571em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9537849999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.4537849999999999em;"><span style="top:-2.4516em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0548571428571427em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.0945428571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.822325em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9020857142857143em;"><span style="top:-2.160707142857143em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.2305600000000001em;"><span style="top:-2.3em;margin-left:-0.05764em;margin-right:0.1em;"><span class="pstrut" style="height:2.5em;"></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5496399999999999em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.0945428571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7318928571428571em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7739999999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.8280330000000005em;vertical-align:-1.113777em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7142560000000002em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-4.135925em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1645428571428572em;"><span style="top:-2.3569999999999998em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.39274285714285706em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.113777em;"><span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.5585400000000003em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9020857142857143em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.0945428571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.46117142857142857em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7642799999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.2642799999999998em;"><span style="top:-2.4516em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0548571428571427em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.0945428571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.63282em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9020857142857143em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.0945428571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.46117142857142857em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7739999999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.8280330000000005em;vertical-align:-1.113777em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7142560000000002em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-4.135925em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1645428571428572em;"><span style="top:-2.3569999999999998em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.39274285714285706em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.113777em;"><span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.5585400000000003em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9020857142857143em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.0945428571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.46117142857142857em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7642799999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9017679999999999em;"><span style="top:-2.4231360000000004em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mord mathnormal mtight">i</span></span></span></span><span style="top:-3.1506600000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.412972em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9017679999999999em;"><span style="top:-2.4231360000000004em;margin-left:-0.04398em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.1506600000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.276864em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mclose">)</span></span></span></span>，其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi>z</mi><mi>j</mi><msub><mi>n</mi><mi>l</mi></msub></msubsup><mo>=</mo><msubsup><mi>W</mi><mrow><mi>j</mi><mn>1</mn></mrow><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msubsup><mi>σ</mi><mo stretchy="false">(</mo><msubsup><mi>z</mi><mn>1</mn><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msubsup><mo stretchy="false">)</mo><mo>+</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo>+</mo><msubsup><mi>W</mi><mrow><mi>j</mi><mo separator="true">,</mo><msub><mi>S</mi><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msub></mrow><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msubsup><mi>σ</mi><mo stretchy="false">(</mo><msubsup><mi>z</mi><msub><mi>S</mi><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msub><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msubsup><mo stretchy="false">)</mo><mo>+</mo><msubsup><mi>b</mi><mi>j</mi><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msubsup></mrow><annotation encoding="application/x-tex">z_j^{n_l}=W_{j1}^{n_l-1}\sigma(z_1^{n_l-1})+...+W_{j,S_{n_l-1}}^{n_l-1}\sigma(z_{S_{n_l-1}}^{n_l-1})+b_j^{n_l-1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.1650239999999998em;vertical-align:-0.412972em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7520519999999999em;"><span style="top:-2.4231360000000004em;margin-left:-0.04398em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.1506600000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.412972em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.31474em;vertical-align:-0.412972em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9017679999999999em;"><span style="top:-2.4231360000000004em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.1506600000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.412972em;"><span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9017679999999999em;"><span style="top:-2.433692em;margin-left:-0.04398em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span><span style="top:-3.1506600000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.266308em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.4702189999999997em;vertical-align:-0.5684509999999999em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9017679999999999em;"><span style="top:-2.406469em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.3569999999999998em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.39274285714285706em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.1506600000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5684509999999999em;"><span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9017679999999999em;"><span style="top:-2.406469em;margin-left:-0.04398em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.3569999999999998em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.39274285714285706em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.1506600000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5684509999999999em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.31474em;vertical-align:-0.412972em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9017679999999999em;"><span style="top:-2.4231360000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.1506600000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.412972em;"><span></span></span></span></span></span></span></span></span></span>。一般的，对任意非输出层<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi></mrow><annotation encoding="application/x-tex">l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span>（<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi><mo>∈</mo><mo stretchy="false">{</mo><mn>2</mn><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">l\in \{2,...,n_l-1\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">}</span></span></span></span>），有<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>i</mi><mi>l</mi></msubsup></mrow></mfrac><mo>=</mo><msubsup><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>1</mn></mrow><msub><mi>S</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msub></msubsup><mo stretchy="false">(</mo><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>j</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><msubsup><mi>W</mi><mrow><mi>j</mi><mi>i</mi></mrow><mi>l</mi></msubsup><mo stretchy="false">)</mo><msup><mi>σ</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><msubsup><mi>z</mi><mi>i</mi><mi>l</mi></msubsup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\frac{\partial L}{\partial z_i^l}=\sum\limits_{j=1}^{S_{l+1}}(\frac{\partial L}{\partial z_j^{l+1}}W_{ji}^{l})\sigma^{\prime}(z_i^l)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.5042879999999998em;vertical-align:-0.6241799999999998em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.60142em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8408285714285714em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-2.8448em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6241799999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.700638em;vertical-align:-1.113777em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.586861em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-4.00853em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.34480000000000005em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.21074999999999994em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.113777em;"><span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.559755em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9003499999999999em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-2.9043214285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.46117142857142857em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7630649999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.441336em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mord mathnormal mtight">i</span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.394772em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.441336em;margin-left:-0.04398em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.258664em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>（这就是图1反向传播的原理）</li></ul><p>现在可以轻松求解<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>W</mi><mrow><mi>i</mi><mi>j</mi></mrow><mi>l</mi></msubsup></mrow></mfrac><mo>=</mo><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>i</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><mfrac><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>i</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>W</mi><mrow><mi>i</mi><mi>j</mi></mrow><mi>l</mi></msubsup></mrow></mfrac><mo>=</mo><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>i</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><msubsup><mi>a</mi><mi>j</mi><mi>l</mi></msubsup></mrow><annotation encoding="application/x-tex">\frac{\partial L}{\partial W_{ij}^l}=\frac{\partial L}{\partial z_i^{l+1}}\frac{\partial z_i^{l+1}}{\partial W_{ij}^l}=\frac{\partial L}{\partial z_i^{l+1}}a_j^l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.6015079999999997em;vertical-align:-0.7213999999999998em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.60142em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8408285714285714em;"><span style="top:-2.177714285714286em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span><span style="top:-2.8448em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.46117142857142857em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7213999999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.8872449999999996em;vertical-align:-0.7213999999999998em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.559755em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9003499999999999em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-2.9043214285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6658449999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.1658449999999998em;"><span style="top:-2.60142em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8408285714285714em;"><span style="top:-2.177714285714286em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span><span style="top:-2.8448em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.46117142857142857em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.516925em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9270285714285713em;"><span style="top:-2.204392857142857em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.29560714285714285em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7213999999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.5459529999999997em;vertical-align:-0.6658449999999998em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.559755em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9003499999999999em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-2.9043214285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6658449999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.441336em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.394772em;"><span></span></span></span></span></span></span></span></span></span>，以及<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>b</mi><mi>i</mi><mi>l</mi></msubsup></mrow></mfrac><mo>=</mo><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>i</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><mfrac><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>i</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>b</mi><mi>i</mi><mi>l</mi></msubsup></mrow></mfrac><mo>=</mo><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mi>i</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><mn>1</mn></mrow><annotation encoding="application/x-tex">\frac{\partial L}{\partial b_i^l}=\frac{\partial L}{\partial z_i^{l+1}}\frac{\partial z_i^{l+1}}{\partial b_i^l}=\frac{\partial L}{\partial z_i^{l+1}}1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.5042879999999998em;vertical-align:-0.6241799999999998em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.60142em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight">b</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8408285714285714em;"><span style="top:-2.177714285714286em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-2.8448em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6241799999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.8316899999999996em;vertical-align:-0.6658449999999998em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.559755em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9003499999999999em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-2.9043214285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6658449999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.1658449999999998em;"><span style="top:-2.60142em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight">b</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8408285714285714em;"><span style="top:-2.177714285714286em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-2.8448em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.516925em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9270285714285713em;"><span style="top:-2.204392857142857em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.29560714285714285em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6241799999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.5459529999999997em;vertical-align:-0.6658449999999998em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.559755em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9003499999999999em;"><span style="top:-2.177714285714286em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-2.9043214285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3222857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6658449999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">1</span></span></span></span></p><p>以上全部改写为矩阵形式，有：<br><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msup><mi>z</mi><msub><mi>n</mi><mi>l</mi></msub></msup></mrow></mfrac><mo>=</mo><mo stretchy="false">(</mo><msup><mi>a</mi><msub><mi>n</mi><mi>l</mi></msub></msup><mo>−</mo><mi>y</mi><mo stretchy="false">)</mo><mo>⊙</mo><msup><mi>σ</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><msup><mi>z</mi><msub><mi>n</mi><mi>l</mi></msub></msup><mo stretchy="false">)</mo><mo>∈</mo><msup><mi>R</mi><mrow><msub><mi>S</mi><msub><mi>n</mi><mi>l</mi></msub></msub><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\frac{\partial L}{\partial z^{n_l}}=(a^{n_l}-y)\odot\sigma^{\prime}(z^{n_l})\in R^{S_{n_l}\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.2251079999999999em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6650357142857143em;"><span style="top:-2.8574928571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.664392em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊙</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.664392em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8610009999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8610009999999999em;"><span style="top:-3.0826700000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1645428571428572em;"><span style="top:-2.3569999999999998em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.39274285714285706em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>（<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>⊙</mo></mrow><annotation encoding="application/x-tex">\odot</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord">⊙</span></span></span></span>表示逐元素乘法），<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msup><mi>z</mi><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msup></mrow></mfrac><mo>=</mo><mo stretchy="false">(</mo><msup><mi>W</mi><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msup><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msup><mi>z</mi><msub><mi>n</mi><mi>l</mi></msub></msup></mrow></mfrac><mo stretchy="false">)</mo><mo>⊙</mo><msup><mi>σ</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><msup><mi>z</mi><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msup><mo stretchy="false">)</mo><mo>∈</mo><msup><mi>R</mi><mrow><msub><mi>S</mi><mrow><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow></msub><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\frac{\partial L}{\partial z^{n_l-1}}=(W^{n_l-1}\frac{\partial L}{\partial z^{n_l}})\odot\sigma^{\prime}(z^{n_l-1})\in R^{S_{n_l-1}\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.262573em;vertical-align:-0.382465em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.617535em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8178071428571428em;"><span style="top:-2.8574928571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.382465em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.2251079999999999em;vertical-align:-0.345em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6650357142857143em;"><span style="top:-2.8574928571428573em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊙</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8610009999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8610009999999999em;"><span style="top:-3.0826700000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.3569999999999998em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.39274285714285706em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>，…，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msup><mi>z</mi><mi>l</mi></msup></mrow></mfrac><mo>=</mo><mo stretchy="false">(</mo><msup><mi>W</mi><mi>l</mi></msup><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msup><mi>z</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msup></mrow></mfrac><mo stretchy="false">)</mo><mo>⊙</mo><msup><mi>σ</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><msup><mi>z</mi><mi>l</mi></msup><mo stretchy="false">)</mo><mo>∈</mo><msup><mi>R</mi><mrow><msub><mi>S</mi><mi>l</mi></msub><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\frac{\partial L}{\partial z^l}=(W^l\frac{\partial L}{\partial z^{l+1}})\odot\sigma^{\prime}(z^l)\in R^{S_l\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.2375279999999997em;vertical-align:-0.3574199999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.64258em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7820285714285713em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3574199999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.2375279999999997em;vertical-align:-0.3574199999999999em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.64258em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7820285714285714em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3574199999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊙</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.099108em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>（<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi><mo>=</mo><mn>1</mn><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msub><mi>n</mi><mi>l</mi></msub><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">l=1,...,n_l-1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>）</p><p>进一步，有：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msup><mi>W</mi><mi>l</mi></msup></mrow></mfrac><mo>=</mo><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>W</mi><mn>11</mn><mi>l</mi></msubsup></mrow></mfrac></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>W</mi><mn>21</mn><mi>l</mi></msubsup></mrow></mfrac></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mo lspace="0em" rspace="0em">⋯</mo></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>W</mi><mrow><msub><mi>S</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msub><mo separator="true">,</mo><mn>1</mn></mrow><mi>l</mi></msubsup></mrow></mfrac></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>W</mi><mn>12</mn><mi>l</mi></msubsup></mrow></mfrac></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>W</mi><mn>22</mn><mi>l</mi></msubsup></mrow></mfrac></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mo lspace="0em" rspace="0em">⋯</mo></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>W</mi><mrow><msub><mi>S</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msub><mo separator="true">,</mo><mn>2</mn></mrow><mi>l</mi></msubsup></mrow></mfrac></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi><mi mathvariant="normal">⋮</mi><mpadded height="+0em" voffset="0em"><mspace mathbackground="black" width="0em" height="1.5em"></mspace></mpadded></mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi><mi mathvariant="normal">⋮</mi><mpadded height="+0em" voffset="0em"><mspace mathbackground="black" width="0em" height="1.5em"></mspace></mpadded></mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mo lspace="0em" rspace="0em">⋱</mo></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi><mi mathvariant="normal">⋮</mi><mpadded height="+0em" voffset="0em"><mspace mathbackground="black" width="0em" height="1.5em"></mspace></mpadded></mi></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>W</mi><mrow><mn>1</mn><mo separator="true">,</mo><msub><mi>S</mi><mi>l</mi></msub></mrow><mi>l</mi></msubsup></mrow></mfrac></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>W</mi><mrow><mn>2</mn><mo separator="true">,</mo><msub><mi>S</mi><mi>l</mi></msub></mrow><mi>l</mi></msubsup></mrow></mfrac></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mo lspace="0em" rspace="0em">⋯</mo></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>W</mi><mrow><msub><mi>S</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msub><mo separator="true">,</mo><msub><mi>S</mi><mi>l</mi></msub></mrow><mi>l</mi></msubsup></mrow></mfrac></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow><mo>=</mo><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mn>1</mn><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><msubsup><mi>a</mi><mn>1</mn><mi>l</mi></msubsup></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mn>2</mn><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><msubsup><mi>a</mi><mn>1</mn><mi>l</mi></msubsup></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mo lspace="0em" rspace="0em">⋯</mo></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><msub><mi>S</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msub><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><msubsup><mi>a</mi><mn>1</mn><mi>l</mi></msubsup></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mn>1</mn><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><msubsup><mi>a</mi><mn>2</mn><mi>l</mi></msubsup></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mn>2</mn><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><msubsup><mi>a</mi><mn>2</mn><mi>l</mi></msubsup></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mo lspace="0em" rspace="0em">⋯</mo></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><msub><mi>S</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msub><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><msubsup><mi>a</mi><mn>2</mn><mi>l</mi></msubsup></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi><mi mathvariant="normal">⋮</mi><mpadded height="+0em" voffset="0em"><mspace mathbackground="black" width="0em" height="1.5em"></mspace></mpadded></mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi><mi mathvariant="normal">⋮</mi><mpadded height="+0em" voffset="0em"><mspace mathbackground="black" width="0em" height="1.5em"></mspace></mpadded></mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mo lspace="0em" rspace="0em">⋱</mo></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi><mi mathvariant="normal">⋮</mi><mpadded height="+0em" voffset="0em"><mspace mathbackground="black" width="0em" height="1.5em"></mspace></mpadded></mi></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mn>1</mn><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><msubsup><mi>a</mi><msub><mi>S</mi><mi>l</mi></msub><mi>l</mi></msubsup></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><mn>2</mn><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><msubsup><mi>a</mi><msub><mi>S</mi><mi>l</mi></msub><mi>l</mi></msubsup></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mo lspace="0em" rspace="0em">⋯</mo></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msubsup><mi>z</mi><msub><mi>S</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msub><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msubsup></mrow></mfrac><msubsup><mi>a</mi><msub><mi>S</mi><mi>l</mi></msub><mi>l</mi></msubsup></mrow></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow><mo>=</mo><msup><mi>a</mi><mi>l</mi></msup><mo stretchy="false">(</mo><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msup><mi>z</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msup></mrow></mfrac><msup><mo stretchy="false">)</mo><mi>T</mi></msup><mo>∈</mo><msup><mi>R</mi><mrow><msub><mi>S</mi><mi>l</mi></msub><mo>×</mo><msub><mi>S</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow></msup></mrow><annotation encoding="application/x-tex">\frac{\partial L}{\partial W^l}=\begin{bmatrix}\frac{\partial L}{\partial W_{11}^{l}}&amp;\frac{\partial L}{\partial W_{21}^{l}}&amp;\cdots&amp;\frac{\partial L}{\partial W_{S_{l+1},1}^{l}}\\\frac{\partial L}{\partial W_{12}^{l}}&amp;\frac{\partial L}{\partial W_{22}^{l}}&amp;\cdots&amp;\frac{\partial L}{\partial W_{S_{l+1},2}^{l}}\\\vdots&amp;\vdots&amp;\ddots&amp;\vdots\\\frac{\partial L}{\partial W_{1,S_{l}}^{l}}&amp;\frac{\partial L}{\partial W_{2,S_{l}}^{l}}&amp;\cdots&amp;\frac{\partial L}{\partial W_{S_{l+1},S_{l}}^{l}}\end{bmatrix}=\begin{bmatrix}\frac{\partial L}{\partial z_{1}^{l+1}}a_{1}^l&amp;\frac{\partial L}{\partial z_{2}^{l+1}}a_{1}^l&amp;\cdots&amp;\frac{\partial L}{\partial z_{S_{l+1}}^{l+1}}a_{1}^l\\\frac{\partial L}{\partial z_{1}^{l+1}}a_{2}^l&amp;\frac{\partial L}{\partial z_{2}^{l+1}}a_{2}^l&amp;\cdots&amp;\frac{\partial L}{\partial z_{S_{l+1}}^{l+1}}a_{2}^l\\\vdots&amp;\vdots&amp;\ddots&amp;\vdots\\\frac{\partial L}{\partial z_{1}^{l+1}}a_{S_l}^l&amp;\frac{\partial L}{\partial z_{2}^{l+1}}a_{S_l}^l&amp;\cdots&amp;\frac{\partial L}{\partial z_{S_{l+1}}^{l+1}}a_{S_l}^l\end{bmatrix}=a^l(\frac{\partial L}{\partial z^{l+1}})^T\in R^{S_l\times S_{l+1}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.2375279999999997em;vertical-align:-0.3574199999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.64258em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7820285714285713em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3574199999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:7.058034em;vertical-align:-3.2790169999999996em;"></span><span class="minner"><span class="mopen"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.555985em;"><span style="top:-0.7499750000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎣</span></span></span><span style="top:-1.8999750000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-2.4959750000000005em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.0919750000000006em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.6879750000000002em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-4.283975em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-4.314965000000001em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-5.555985000000001em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎡</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.050045em;"><span></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.7790170000000005em;"><span style="top:-6.586409000000001em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.60142em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8408285714285714em;"><span style="top:-2.188485714285714em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mord mtight">1</span></span></span></span><span style="top:-2.8448em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.31151428571428574em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6166399999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-4.853731000000001em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.60142em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8408285714285714em;"><span style="top:-2.188485714285714em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mord mtight">2</span></span></span></span><span style="top:-2.8448em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.31151428571428574em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6166399999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-2.501161em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord">⋮</span><span class="mord rule" style="border-right-width:0em;border-top-width:1.5em;bottom:0em;"></span></span></span></span><span style="top:-1.2610530000000002em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.60142em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8408285714285714em;"><span style="top:-2.160707142857143em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:-0.05764em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-2.8448em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5890357142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8109049999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.2790169999999996em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.7790170000000005em;"><span style="top:-6.586409000000001em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.60142em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8408285714285714em;"><span style="top:-2.188485714285714em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">1</span></span></span></span><span style="top:-2.8448em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.31151428571428574em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6166399999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-4.853731000000001em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.60142em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8408285714285714em;"><span style="top:-2.188485714285714em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mtight">2</span></span></span></span><span style="top:-2.8448em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.31151428571428574em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6166399999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-2.501161em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord">⋮</span><span class="mord rule" style="border-right-width:0em;border-top-width:1.5em;bottom:0em;"></span></span></span></span><span style="top:-1.2610530000000002em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.60142em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8408285714285714em;"><span style="top:-2.160707142857143em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:-0.05764em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-2.8448em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5890357142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8109049999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.2790169999999996em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.7790170000000005em;"><span style="top:-6.398909000000001em;"><span class="pstrut" style="height:3.5em;"></span><span class="mord"><span class="minner">⋯</span></span></span><span style="top:-4.666231000000001em;"><span class="pstrut" style="height:3.5em;"></span><span class="mord"><span class="minner">⋯</span></span></span><span style="top:-2.313661em;"><span class="pstrut" style="height:3.5em;"></span><span class="mord"><span class="minner">⋱</span></span></span><span style="top:-1.0735530000000002em;"><span class="pstrut" style="height:3.5em;"></span><span class="mord"><span class="minner">⋯</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.2790169999999996em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.7790170000000005em;"><span style="top:-6.586409000000001em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.60142em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8408285714285714em;"><span style="top:-2.160707142857143em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:-0.05764em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.43296999999999997em;"><span></span></span></span></span></span></span><span class="mpunct mtight">,</span><span class="mord mtight">1</span></span></span></span><span style="top:-2.8448em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6485571428571428em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8525699999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-4.853731000000001em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.60142em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8408285714285714em;"><span style="top:-2.160707142857143em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:-0.05764em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.43296999999999997em;"><span></span></span></span></span></span></span><span class="mpunct mtight">,</span><span class="mord mtight">2</span></span></span></span><span style="top:-2.8448em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6485571428571428em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8525699999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-2.501161em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord">⋮</span><span class="mord rule" style="border-right-width:0em;border-top-width:1.5em;bottom:0em;"></span></span></span></span><span style="top:-1.2610530000000002em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.60142em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8408285714285714em;"><span style="top:-2.160707142857143em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:-0.05764em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.43296999999999997em;"><span></span></span></span></span></span></span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:-0.05764em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-2.8448em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6485571428571428em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8525699999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.2790169999999996em;"><span></span></span></span></span></span></span></span><span class="mclose"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.555985em;"><span style="top:-0.7499750000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎦</span></span></span><span style="top:-1.8999750000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-2.4959750000000005em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.0919750000000006em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.6879750000000002em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-4.283975em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-4.314965000000001em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-5.555985000000001em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎤</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.050045em;"><span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:7.20703em;vertical-align:-3.3500499999999995em;"></span><span class="minner"><span class="mopen"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.8569800000000005em;"><span style="top:-0.44997000000000076em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎣</span></span></span><span style="top:-1.5999700000000008em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-2.195970000000001em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-2.791970000000001em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.3879700000000006em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.9839700000000007em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-4.579970000000001em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-4.615960000000001em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-5.856980000000001em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎡</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.3500499999999995em;"><span></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.8415144999999997em;"><span style="top:-6.648906500000001em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.559755em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90035em;"><span style="top:-2.188485714285714em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span><span style="top:-2.904321428571429em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.31151428571428574em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6583049999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.4518920000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.24810799999999997em;"><span></span></span></span></span></span></span></span></span><span style="top:-4.874563500000001em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.559755em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90035em;"><span style="top:-2.188485714285714em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span><span style="top:-2.904321428571429em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.31151428571428574em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6583049999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.4518920000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.24810799999999997em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.4803285000000006em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord">⋮</span><span class="mord rule" style="border-right-width:0em;border-top-width:1.5em;bottom:0em;"></span></span></span></span><span style="top:-1.2402205em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.559755em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90035em;"><span style="top:-2.188485714285714em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span><span style="top:-2.904321428571429em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.31151428571428574em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6583049999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.424669em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.38119099999999995em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.3415144999999997em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.8415144999999997em;"><span style="top:-6.648906500000001em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.559755em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90035em;"><span style="top:-2.188485714285714em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-2.904321428571429em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.31151428571428574em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6583049999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.4518920000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.24810799999999997em;"><span></span></span></span></span></span></span></span></span><span style="top:-4.874563500000001em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.559755em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90035em;"><span style="top:-2.188485714285714em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-2.904321428571429em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.31151428571428574em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6583049999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.4518920000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.24810799999999997em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.4803285000000006em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord">⋮</span><span class="mord rule" style="border-right-width:0em;border-top-width:1.5em;bottom:0em;"></span></span></span></span><span style="top:-1.2402205em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.559755em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90035em;"><span style="top:-2.188485714285714em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-2.904321428571429em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.31151428571428574em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6583049999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.424669em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.38119099999999995em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.3415144999999997em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.8415144999999997em;"><span style="top:-6.461406500000001em;"><span class="pstrut" style="height:3.5em;"></span><span class="mord"><span class="minner">⋯</span></span></span><span style="top:-4.687063500000001em;"><span class="pstrut" style="height:3.5em;"></span><span class="mord"><span class="minner">⋯</span></span></span><span style="top:-2.2928285000000006em;"><span class="pstrut" style="height:3.5em;"></span><span class="mord"><span class="minner">⋱</span></span></span><span style="top:-1.0527205em;"><span class="pstrut" style="height:3.5em;"></span><span class="mord"><span class="minner">⋯</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.3415144999999997em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.8415144999999997em;"><span style="top:-6.648906500000001em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.5597550000000004em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9003499999999999em;"><span style="top:-2.160707142857143em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:-0.05764em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.43296999999999997em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-2.9043214285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6485571428571428em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8942349999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.4518920000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.24810799999999997em;"><span></span></span></span></span></span></span></span></span><span style="top:-4.874563500000001em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.5597550000000004em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9003499999999999em;"><span style="top:-2.160707142857143em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:-0.05764em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.43296999999999997em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-2.9043214285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6485571428571428em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8942349999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.4518920000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.24810799999999997em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.4803285000000006em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord">⋮</span><span class="mord rule" style="border-right-width:0em;border-top-width:1.5em;bottom:0em;"></span></span></span></span><span style="top:-1.2402205em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.5597550000000004em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9003499999999999em;"><span style="top:-2.160707142857143em;margin-left:-0.04398em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:-0.05764em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.43296999999999997em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-2.9043214285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6485571428571428em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8942349999999998em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-2.424669em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.38119099999999995em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.3415144999999997em;"><span></span></span></span></span></span></span></span><span class="mclose"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.8569800000000005em;"><span style="top:-0.44997000000000076em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎦</span></span></span><span style="top:-1.5999700000000008em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-2.195970000000001em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-2.791970000000001em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.3879700000000006em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.9839700000000007em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-4.579970000000001em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-4.615960000000001em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-5.856980000000001em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎤</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.3500499999999995em;"><span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.2375279999999997em;vertical-align:-0.3574199999999999em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.64258em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7820285714285714em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3574199999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.34480000000000005em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.21074999999999994em;"><span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msup><mi>b</mi><mi>l</mi></msup></mrow></mfrac><mo>=</mo><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>L</mi></mrow><mrow><mi mathvariant="normal">∂</mi><msup><mi>z</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msup></mrow></mfrac><mo>∈</mo><msup><mi>R</mi><mrow><msub><mi>S</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\frac{\partial L}{\partial b^l}=\frac{\partial L}{\partial z^{l+1}}\in R^{S_{l+1}\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.2375279999999997em;vertical-align:-0.3574199999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.64258em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7820285714285713em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3574199999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.2375279999999997em;vertical-align:-0.3574199999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.64258em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7820285714285714em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">L</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3574199999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.34480000000000005em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.21074999999999994em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span></p></div></div></div><h2 id="Pytorch标量对矩阵求导">Pytorch标量对矩阵求导</h2><p>举个例子，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><mi>t</mi><mi>r</mi><mo stretchy="false">(</mo><mi>A</mi><mi>X</mi><mi>B</mi><mi>X</mi><mo stretchy="false">)</mo></mrow><mrow><mi mathvariant="normal">∂</mi><mi>X</mi></mrow></mfrac><mo>=</mo><msup><mi>A</mi><mi>T</mi></msup><msup><mi>X</mi><mi>T</mi></msup><msup><mi>B</mi><mi>T</mi></msup><mo>+</mo><msup><mi>B</mi><mi>T</mi></msup><msup><mi>X</mi><mi>T</mi></msup><msup><mi>A</mi><mi>T</mi></msup></mrow><annotation encoding="application/x-tex">\frac{\partial tr(AXBX)}{\partial X}=A^TX^TB^T+B^TX^TA^T</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.355em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.01em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight" style="margin-right:0.07847em;">X</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.485em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">t</span><span class="mord mathnormal mtight" style="margin-right:0.02778em;">r</span><span class="mopen mtight">(</span><span class="mord mathnormal mtight">A</span><span class="mord mathnormal mtight" style="margin-right:0.07847em;">X</span><span class="mord mathnormal mtight" style="margin-right:0.05017em;">B</span><span class="mord mathnormal mtight" style="margin-right:0.07847em;">X</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.924661em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span></span></span></span>（该解析解可根据“<a href="https://zhuanlan.zhihu.com/p/24709748">矩阵求导术</a>”得出）</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">import</span> torch <span class="keyword">as</span> pt</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>X=pt.arange(<span class="number">12</span>,dtype=pt.float32).view(<span class="number">3</span>,<span class="number">4</span>) <span class="comment">#要使X支持求导，必须为浮点类型</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_=X.requires_grad_(<span class="literal">True</span>) <span class="comment">#置requires_grad为True（表示可导），于是X上的梯度更新将累积到grad属性中</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>A=pt.rand(<span class="number">4</span>,<span class="number">3</span>) <span class="comment">#rand()的默认类型就是float32</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>B=pt.rand(<span class="number">4</span>,<span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>out=pt.trace(A.mm(X).mm(B).mm(X)) <span class="comment">#out是一个复合函数，默认只会计算对叶子节点的导数，中间节点需要手动定义，譬如AX=A.mm(X)</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>out.backward() <span class="comment">#只要任意叶子节点（此处就是X,A,B）的requires_grad为True，则out也为True，执行一遍反向传播后，将可以得出out对X的偏导（存放在X.grad属性中）</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>X.grad <span class="comment">#由于梯度会累加，可以执行X.grad.data.zero_()对梯度清零</span></span><br><span class="line">tensor([[<span class="number">35.3752</span>, <span class="number">34.2365</span>,  <span class="number">9.8990</span>, <span class="number">22.8047</span>],</span><br><span class="line">        [<span class="number">31.8588</span>, <span class="number">32.2588</span>,  <span class="number">8.7556</span>, <span class="number">17.3359</span>],</span><br><span class="line">        [<span class="number">24.6398</span>, <span class="number">21.3645</span>,  <span class="number">6.5890</span>, <span class="number">17.4973</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>pt.t(A).mm(pt.t(X)).mm(pt.t(B))+pt.t(B).mm(pt.t(X)).mm(pt.t(A)) <span class="comment">#验证偏导是否计算正确（AᵀXᵀBᵀ+BᵀXᵀAᵀ），正确</span></span><br><span class="line">tensor([[<span class="number">35.3752</span>, <span class="number">34.2365</span>,  <span class="number">9.8990</span>, <span class="number">22.8047</span>],</span><br><span class="line">        [<span class="number">31.8587</span>, <span class="number">32.2588</span>,  <span class="number">8.7556</span>, <span class="number">17.3359</span>],</span><br><span class="line">        [<span class="number">24.6398</span>, <span class="number">21.3645</span>,  <span class="number">6.5890</span>, <span class="number">17.4973</span>]], grad_fn=&lt;AddBackward0&gt;)</span><br></pre></td></tr></table></figure><h2 id="线性回归模型">线性回归模型</h2><p>简要回顾：</p><p>线性回归预测模型定义为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi>y</mi><mo>^</mo></mover><mo>=</mo><msub><mi>w</mi><mn>1</mn></msub><msub><mi>x</mi><mn>1</mn></msub><mo>+</mo><msub><mi>w</mi><mn>2</mn></msub><msub><mi>x</mi><mn>2</mn></msub><mo>+</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo>+</mo><msub><mi>w</mi><mi>n</mi></msub><msub><mi>x</mi><mi>n</mi></msub><mo>+</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">\hat{y}=w_1x_1+w_2x_2+...+w_nx_n+b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span></span></span>，其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>w</mi><mo>=</mo><mo stretchy="false">[</mo><msub><mi>w</mi><mn>1</mn></msub><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msub><mi>w</mi><mi>n</mi></msub><msup><mo stretchy="false">]</mo><mi>T</mi></msup><mo separator="true">,</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">w=[w_1,...,w_n]^T,b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.0913309999999998em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose"><span class="mclose">]</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span></span></span></span>为模型参数，分别称为权重和偏置项，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mo>=</mo><mo stretchy="false">[</mo><msub><mi>x</mi><mn>1</mn></msub><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msub><mi>x</mi><mi>n</mi></msub><msup><mo stretchy="false">]</mo><mi>T</mi></msup></mrow><annotation encoding="application/x-tex">x=[x_1,...,x_n]^T</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.0913309999999998em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose"><span class="mclose">]</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span></span></span></span>为单个样本数据。对于有<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span>个样本的批量数据，其（预测模型）矩阵表示形式为：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi>Y</mi><mo>^</mo></mover><mo>=</mo><msup><mi>w</mi><mi>T</mi></msup><mi>X</mi><mo>+</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">\hat{Y}=w^TX+b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9467699999999999em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9467699999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span></span></span><span style="top:-3.25233em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.25em;"><span class="mord">^</span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.924661em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span></span></span>（注意这边我们直接对一个向量和一个标量相加，发生广播），其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi><mo>=</mo><mo stretchy="false">[</mo><msup><mi>x</mi><mrow><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></msup><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msup><mi>x</mi><mrow><mo stretchy="false">(</mo><mi>m</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">X=[x^{(1)},...,x^{(m)}]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mtight">1</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">m</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">]</span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi>Y</mi><mo>^</mo></mover><mo>=</mo><mo stretchy="false">[</mo><msup><mover accent="true"><mi>y</mi><mo>^</mo></mover><mrow><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></msup><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msup><mover accent="true"><mi>y</mi><mo>^</mo></mover><mrow><mo stretchy="false">(</mo><mi>m</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">\hat{Y}=[\hat{y}^{(1)},...,\hat{y}^{(m)}]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9467699999999999em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9467699999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span></span></span><span style="top:-3.25233em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.25em;"><span class="mord">^</span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord"><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mtight">1</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">m</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">]</span></span></span></span>，相应的，记真实值<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Y</mi><mo>=</mo><mo stretchy="false">[</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></msup><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>m</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">Y=[y^{(1)},...,y^{(m)}]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mtight">1</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">m</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">]</span></span></span></span>。假设我们使用均方误差（预测值与真实值差的平方）作为单样本（第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathnormal">i</span></span></span></span>个样本）损失函数：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi>l</mi><mrow><mo stretchy="false">(</mo><mi>w</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo></mrow><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msubsup><mo>=</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mo stretchy="false">(</mo><msup><mover accent="true"><mi>y</mi><mo>^</mo></mover><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo>−</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">l_{(w,b)}^{(i)}=\frac{1}{2}(\hat{y}^{(i)}-y^{(i)})^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.5599999999999998em;vertical-align:-0.5151999999999999em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0448em;"><span style="top:-2.3598em;margin-left:-0.01968em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight" style="margin-right:0.02691em;">w</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span><span class="mclose mtight">)</span></span></span></span><span style="top:-3.2198em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5151999999999999em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.2329999999999999em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mopen">(</span><span class="mord"><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span>，而对<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span>个批量数据，我们用所有这些样本的平方误差和的均值作为总体损失：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>L</mi><mrow><mo stretchy="false">(</mo><mi>w</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo></mrow></msub><mo>=</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><msubsup><mi>l</mi><mrow><mo stretchy="false">(</mo><mi>w</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo></mrow><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msubsup></mrow><annotation encoding="application/x-tex">L_{(w,b)}=\frac{1}{m}\sum\limits_{i=1}^ml_{(w,b)}^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.03853em;vertical-align:-0.3551999999999999em;"></span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.34480000000000005em;"><span style="top:-2.5198em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight" style="margin-right:0.02691em;">w</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3551999999999999em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.329066em;vertical-align:-0.9776689999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0448em;"><span style="top:-2.3598em;margin-left:-0.01968em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight" style="margin-right:0.02691em;">w</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span><span class="mclose mtight">)</span></span></span></span><span style="top:-3.2198em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5151999999999999em;"><span></span></span></span></span></span></span></span></span></span>，接下来要做的就是学习一组模型参数以最小化总体损失：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>w</mi><mo>∗</mo></msup><mo separator="true">,</mo><msup><mi>b</mi><mo>∗</mo></msup><mo>=</mo><mi>arg</mi><mo>⁡</mo><munder><mo><mi>min</mi><mo>⁡</mo></mo><mrow><mi>w</mi><mo separator="true">,</mo><mi>b</mi></mrow></munder><msub><mi>L</mi><mrow><mo stretchy="false">(</mo><mi>w</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo></mrow></msub><mo>=</mo><mi>arg</mi><mo>⁡</mo><munder><mo><mi>min</mi><mo>⁡</mo></mo><mrow><mi>w</mi><mo separator="true">,</mo><mi>b</mi></mrow></munder><mfrac><mn>1</mn><mrow><mn>2</mn><mi>m</mi></mrow></mfrac><mi mathvariant="normal">∥</mi><mover accent="true"><mi>Y</mi><mo>^</mo></mover><mo>−</mo><mi>Y</mi><msubsup><mi mathvariant="normal">∥</mi><mn>2</mn><mn>2</mn></msubsup></mrow><annotation encoding="application/x-tex">w^*,b^*=\arg\min\limits_{w,b}L_{(w,b)}=\arg\min\limits_{w,b}\frac{1}{2m}\|\hat{Y}-Y\|_2^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mbin mtight">∗</span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mbin mtight">∗</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.5715459999999999em;vertical-align:-0.8882159999999999em;"></span><span class="mop">ar<span style="margin-right:0.01389em;">g</span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.66786em;"><span style="top:-2.3478920000000003em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.02691em;">w</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop">min</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8882159999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.34480000000000005em;"><span style="top:-2.5198em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight" style="margin-right:0.02691em;">w</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3551999999999999em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.8349859999999998em;vertical-align:-0.8882159999999999em;"></span><span class="mop">ar<span style="margin-right:0.01389em;">g</span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.66786em;"><span style="top:-2.3478920000000003em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.02691em;">w</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop">min</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8882159999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">∥</span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9467699999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span></span></span><span style="top:-3.25233em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.25em;"><span class="mord">^</span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mord"><span class="mord">∥</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.4518920000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.24810799999999997em;"><span></span></span></span></span></span></span></span></span></span>，具体的，使用梯度下降算法更新参数以最小化损失：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">{</mo><mtable rowspacing="0.3599999999999999em" columnalign="left left" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>w</mi><mo>←</mo><mi>w</mi><mo>−</mo><mi>r</mi><mfrac><mrow><mi mathvariant="normal">∂</mi><msub><mi>L</mi><mrow><mo stretchy="false">(</mo><mi>w</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo></mrow></msub></mrow><mrow><mi mathvariant="normal">∂</mi><mi>w</mi></mrow></mfrac></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>b</mi><mo>←</mo><mi>b</mi><mo>−</mo><mi>r</mi><mfrac><mrow><mi mathvariant="normal">∂</mi><msub><mi>L</mi><mrow><mo stretchy="false">(</mo><mi>w</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo></mrow></msub></mrow><mrow><mi mathvariant="normal">∂</mi><mi>b</mi></mrow></mfrac></mrow></mstyle></mtd></mtr></mtable></mrow><annotation encoding="application/x-tex">\begin{cases}w\leftarrow w-r\frac{\partial L_{(w,b)}}{\partial w} \\ b\leftarrow b-r\frac{\partial L_{(w,b)}}{\partial b}\end{cases}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.0000299999999998em;vertical-align:-1.25003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size4">{</span></span><span class="mord"><span class="mtable"><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.736748em;"><span style="top:-3.736748em;"><span class="pstrut" style="height:3.054748em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">←</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.054748em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight" style="margin-right:0.02691em;">w</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.5686400000000003em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3447999999999998em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5357142857142856em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight" style="margin-right:0.02691em;">w</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3694857142857143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-2.25em;"><span class="pstrut" style="height:3.054748em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">←</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.054748em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mathnormal mtight">b</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.5686400000000003em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3447999999999998em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5357142857142856em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight" style="margin-right:0.02691em;">w</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3694857142857143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.236748em;"><span></span></span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>（其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>r</mi></mrow><annotation encoding="application/x-tex">r</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span></span></span></span>是学习率）</p><div class="img-wrap"><div class="img-bg"><img class="img" src="https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210608151347.png" alt="图2.&nbsp;线性回归是一个单层（感知器）神经网络[3]" onerror="this.onerror=null,this.src='https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210328224519.jpg'" /></div></div><p>编程实现（核心步骤）：</p><ol><li>定义网络模型<br>定义网络的前向传播过程，并返回模型预测值，此处就是<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>w</mi><mi>T</mi></msup><mi>X</mi><mo>+</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">w^TX+b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.924661em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span></span></span></li><li>定义损失函数<br>损失函数用于衡量预测值与真实值的误差，此处使用的是均方误差，即<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>1</mn><mrow><mn>2</mn><mi>m</mi></mrow></mfrac><mi mathvariant="normal">∥</mi><mo stretchy="false">(</mo><msup><mi>w</mi><mi>T</mi></msup><mi>X</mi><mo>+</mo><mi>b</mi><mo stretchy="false">)</mo><mo>−</mo><mi>Y</mi><msup><mi mathvariant="normal">∥</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">\frac{1}{2m}\|(w^TX+b)-Y\|^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">∥</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mord"><span class="mord">∥</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></li><li>定义优化算法<br>最常用且最简单的就是梯度下降算法，其他还有改进的Adam等，我们知道偏导数保存在张量对象的<code>grad</code>属性中（记得反向传播前清零），梯度下降要做的就是用模型参数减去这些导数值，然后将结果作为参数的新值</li></ol><div class="tabs" id="xxhgbcsx"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#xxhgbcsx-1">准备数据</button></li><li class="tab"><button type="button" data-href="#xxhgbcsx-2">定义模型、损失和优化算法</button></li><li class="tab"><button type="button" data-href="#xxhgbcsx-3">训练</button></li><li class="tab"><button type="button" data-href="#xxhgbcsx-4">附（简洁实现）</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="xxhgbcsx-1"><p>假设真实权重为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>w</mi><mo>=</mo><mo stretchy="false">[</mo><mn>2</mn><mo separator="true">,</mo><mn>3.4</mn><msup><mo stretchy="false">]</mo><mi>T</mi></msup></mrow><annotation encoding="application/x-tex">w=[2,3.4]^T</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.0913309999999998em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">3</span><span class="mord">.</span><span class="mord">4</span><span class="mclose"><span class="mclose">]</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span></span></span></span>，偏置为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi><mo>=</mo><mn>4.2</mn></mrow><annotation encoding="application/x-tex">b=4.2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span><span class="mord">.</span><span class="mord">2</span></span></span></span>，生成一组数据：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Y</mi><mo>=</mo><msup><mi>w</mi><mi>T</mi></msup><mi>X</mi><mo>+</mo><mi>b</mi><mo>+</mo><mi>ϵ</mi></mrow><annotation encoding="application/x-tex">Y=w^TX+b+\epsilon</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.924661em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">ϵ</span></span></span></span>，其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>ϵ</mi></mrow><annotation encoding="application/x-tex">\epsilon</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">ϵ</span></span></span></span>为服从均值0、标准差0.01的正态分布的随机误差项：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### 生成数据</span></span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">true_w=np.array([[<span class="number">2</span>],[<span class="number">3.4</span>]])</span><br><span class="line">true_b=np.array([<span class="number">4.2</span>])</span><br><span class="line">samples_num=<span class="number">1000</span> <span class="comment">#自定义样本数量</span></span><br><span class="line">X=np.random.randn(<span class="built_in">len</span>(true_w),samples_num)</span><br><span class="line">Y=true_w.T@X+true_b</span><br><span class="line">Y+=np.random.normal(<span class="number">0</span>,<span class="number">0.01</span>,size=Y.shape)</span><br></pre></td></tr></table></figure><p>（三维）可视化数据：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">from</span> mpl_toolkits.mplot3d <span class="keyword">import</span> Axes3D</span><br><span class="line">ax=Axes3D(plt.gcf())</span><br><span class="line">data=np.vstack((X,Y))</span><br><span class="line">ax.scatter(*data)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><div class="img-wrap"><div class="img-bg"><img class="img" src="https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210608155310.png" alt="图3.&nbsp;准备的训练数据" onerror="this.onerror=null,this.src='https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210328224519.jpg'" /></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="xxhgbcsx-2"><p>在上述“核心步骤”中已经解释过了，直接看代码：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### 定义线性回归模型</span></span><br><span class="line"><span class="keyword">import</span> torch <span class="keyword">as</span> pt</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">linear_regress</span>(<span class="params">X,w,b</span>):</span><br><span class="line">    <span class="keyword">return</span> pt.t(w).mm(X)+b <span class="comment">#其实就是前向传播计算式</span></span><br><span class="line"></span><br><span class="line"><span class="comment">### 定义损失函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">square_loss</span>(<span class="params">Y_hat,Y</span>):</span><br><span class="line">    <span class="keyword">return</span> pt.<span class="built_in">sum</span>((Y_hat-Y)**<span class="number">2</span>/<span class="number">2</span>) <span class="comment">#注意我们没有在这里除以m（批量尺寸），而会在梯度下降时做，方便写代码</span></span><br><span class="line"></span><br><span class="line"><span class="comment">### 定义梯度下降算法</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sgd</span>(<span class="params">params,learn_rate,batch_size</span>):</span><br><span class="line">    <span class="keyword">for</span> param <span class="keyword">in</span> params:</span><br><span class="line">        param.data-=(learn_rate*param.grad/batch_size)</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="xxhgbcsx-3"><p>在开始训练前还要准备一些东西：训练数据的批量（batch）数据生成器、模型参数的初始化：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### 将ndarray对象转换为Tensor对象以供后续使用</span></span><br><span class="line">X=pt.from_numpy(X).to(pt.float32) <span class="comment">#注意from_numpy是共享内存的</span></span><br><span class="line">Y=pt.from_numpy(Y).to(pt.float32)</span><br><span class="line"></span><br><span class="line"><span class="comment">### 批量读取数据的函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">data_iter</span>(<span class="params">X,Y,batch_size</span>):</span><br><span class="line">    n=X.shape[<span class="number">1</span>]</span><br><span class="line">    ind=np.arange(n)</span><br><span class="line">    np.random.shuffle(ind)</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>,n,batch_size):</span><br><span class="line">        j=pt.LongTensor(ind[i:<span class="built_in">min</span>(i+batch_size,n)]) <span class="comment">#最后一次可能不足一个batch</span></span><br><span class="line">        <span class="keyword">yield</span>  X.index_select(<span class="number">1</span>,j),Y.index_select(<span class="number">1</span>,j) <span class="comment">#tensor.index_select(1,索引序列)表示沿张量的1轴索引元素</span></span><br><span class="line"></span><br><span class="line"><span class="comment">### 初始化模型参数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">init_params</span>():</span><br><span class="line">    w=pt.tensor(np.random.normal(<span class="number">0</span>,<span class="number">0.01</span>,(X.shape[<span class="number">0</span>],<span class="number">1</span>)),dtype=pt.float32)</span><br><span class="line">    b=pt.zeros(<span class="number">1</span>,dtype=pt.float32)</span><br><span class="line">    w.requires_grad_(requires_grad=<span class="literal">True</span>)</span><br><span class="line">    b.requires_grad_(requires_grad=<span class="literal">True</span>)</span><br><span class="line">    <span class="keyword">return</span> w,b</span><br></pre></td></tr></table></figure><p>开始训练：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">num_epoches=<span class="number">5</span> <span class="comment">#自定义迭代周期</span></span><br><span class="line">learn_rate=<span class="number">0.03</span> <span class="comment">#自定义学习率</span></span><br><span class="line">batch_size=<span class="number">10</span> <span class="comment">#自定义批量大小</span></span><br><span class="line">w,b=init_params()</span><br><span class="line"><span class="keyword">for</span> epoch <span class="keyword">in</span> <span class="built_in">range</span>(num_epoches):</span><br><span class="line">    <span class="keyword">for</span> mini_X,mini_Y <span class="keyword">in</span> data_iter(X,Y,batch_size): <span class="comment">#小批量随机梯度下降算法</span></span><br><span class="line">        mini_Y_hat=linear_regress(mini_X,w,b) <span class="comment">#前向传播计算预测值</span></span><br><span class="line">        loss=square_loss(mini_Y_hat,mini_Y) <span class="comment">#计算损失值</span></span><br><span class="line">        loss.backward() <span class="comment">#计算损失对参数的偏导数</span></span><br><span class="line">        sgd((w,b),learn_rate,batch_size) <span class="comment">#根据梯度下降算法更新网络参数</span></span><br><span class="line">        _=w.grad.data.zero_() <span class="comment">#梯度清零，防止累加</span></span><br><span class="line">        _=b.grad.data.zero_()</span><br><span class="line">    <span class="comment">#计算当前epoch的损失（损失应该是递减的），理论上，当参数接近正确值时，损失也将接近0</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;epoch=%d,loss=%f&#x27;</span>%(epoch+<span class="number">1</span>,square_loss(linear_regress(X,w,b),Y))) <span class="comment">#这里直接输出loss拉倒了</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;-&#x27;</span>*<span class="number">22</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;w:&#x27;</span>,w.data) <span class="comment">#观察神经网络拟合出的参数</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;b:&#x27;</span>,b.data)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">epoch=1,loss=32.869465</span></span><br><span class="line"><span class="string">epoch=2,loss=0.122995</span></span><br><span class="line"><span class="string">epoch=3,loss=0.054227</span></span><br><span class="line"><span class="string">epoch=4,loss=0.054130</span></span><br><span class="line"><span class="string">epoch=5,loss=0.054148</span></span><br><span class="line"><span class="string">----------------------</span></span><br><span class="line"><span class="string">w: tensor([[2.0000],</span></span><br><span class="line"><span class="string">        [3.3990]])</span></span><br><span class="line"><span class="string">b: tensor([4.1995])</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="xxhgbcsx-4"><p>比较简单，直接看代码：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> torch <span class="keyword">as</span> pt</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="comment">### 生成训练数据</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">gen_data</span>(<span class="params">true_w,true_b,samples_num</span>):</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;参数：真实的权重（列向量），偏置（标量），训练数据个数（列代表样本）。Ndarray对象</span></span><br><span class="line"><span class="string">       返回：训练数据（dxn），值（标签，1xn）。Tensor/float32对象&#x27;&#x27;&#x27;</span></span><br><span class="line">    X=np.random.randn(<span class="built_in">len</span>(true_w),samples_num)</span><br><span class="line">    Y=true_w.T@X+true_b</span><br><span class="line">    Y+=np.random.normal(<span class="number">0</span>,<span class="number">0.01</span>,size=Y.shape)</span><br><span class="line">    <span class="keyword">return</span> pt.from_numpy(X).to(pt.float32),pt.from_numpy(Y).to(pt.float32)</span><br><span class="line">    </span><br><span class="line"><span class="comment">### 利用torch.utils.data工具包迭代产生小批量数据</span></span><br><span class="line"><span class="keyword">import</span> torch.utils.data <span class="keyword">as</span> Data</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">data_iter</span>(<span class="params">features,labels,batch_size</span>): <span class="comment">#需要注意的是，features的形状为(n,d)，labels的形状为(n,k)，其中d为输入层节点数</span></span><br><span class="line">    <span class="comment">#（样本维数），k为输出层节点数</span></span><br><span class="line">    <span class="comment">#将训练数据的特征和标签组合</span></span><br><span class="line">    dataset = Data.TensorDataset(features, labels)</span><br><span class="line">    <span class="comment">#随机小批量迭代生成器</span></span><br><span class="line">    iteration=Data.DataLoader(dataset, batch_size, shuffle=<span class="literal">True</span>)</span><br><span class="line">    <span class="keyword">return</span> iteration</span><br><span class="line">    </span><br><span class="line"><span class="comment">### 定义线性回归模型</span></span><br><span class="line"><span class="keyword">import</span> torch.nn <span class="keyword">as</span> nn</span><br><span class="line">linearNet=<span class="keyword">lambda</span> input_num: nn.Sequential(nn.Linear(input_num,<span class="number">1</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment">### 定义损失函数，均方差损失</span></span><br><span class="line">loss=nn.MSELoss()</span><br><span class="line"></span><br><span class="line"><span class="comment">### 定义优化算法，使用随机梯度下降</span></span><br><span class="line"><span class="keyword">import</span> torch.optim <span class="keyword">as</span> optim</span><br><span class="line">optimize=<span class="keyword">lambda</span> params,lr:optim.SGD(params,lr=lr)</span><br><span class="line"></span><br><span class="line"><span class="comment">### 训练模型</span></span><br><span class="line"><span class="keyword">from</span> torch.nn <span class="keyword">import</span> init</span><br><span class="line">epoches=<span class="number">10</span></span><br><span class="line">true_w=np.array([[<span class="number">2</span>],[<span class="number">3.4</span>]])</span><br><span class="line">true_b=<span class="number">4.2</span></span><br><span class="line">samples_num=<span class="number">1000</span></span><br><span class="line">batch_size=<span class="number">10</span></span><br><span class="line">train_X,train_Y=gen_data(true_w,true_b,samples_num)</span><br><span class="line">net=linearNet(<span class="built_in">len</span>(true_w))</span><br><span class="line">_=init.normal_(net[<span class="number">0</span>].weight, mean=<span class="number">0</span>, std=<span class="number">0.01</span>) <span class="comment">#初始化模型参数，权重服从标准正态分布。net[0].weight/net[0].bias表示查看第一层网络的权重和偏置</span></span><br><span class="line">_=init.constant_(net[<span class="number">0</span>].bias, val=<span class="number">0</span>) <span class="comment">#后缀_表示原址修改，偏置设为0</span></span><br><span class="line">opt=optimize(net.parameters(),<span class="number">0.01</span>) <span class="comment">#通过net.parameters()返回的生成器查看所有可学习参数</span></span><br><span class="line"><span class="keyword">for</span> epoch <span class="keyword">in</span> <span class="built_in">range</span>(epoches):</span><br><span class="line">    <span class="keyword">for</span> mini_X,mini_Y <span class="keyword">in</span> data_iter(pt.t(train_X),pt.t(train_Y),batch_size):</span><br><span class="line">        out=net(mini_X) <span class="comment">#前向传播（需要注意的是，nn.Linear计算表达式为Xw^T+b，由于X的行为样本，所以输出结果会是一个列向量，</span></span><br><span class="line">                        <span class="comment">#我通常都是写成w^TX+b，其中X列为样本数据，所以输出结果是一个行向量）</span></span><br><span class="line">        l=loss(out,mini_Y.view(-<span class="number">1</span>,<span class="number">1</span>)) <span class="comment">#计算损失</span></span><br><span class="line">        l.backward() <span class="comment">#反向传播求偏导</span></span><br><span class="line">        opt.step() <span class="comment">#执行优化，更新网络参数</span></span><br><span class="line">        net.zero_grad() <span class="comment">#清空导数</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;epoch=%d,loss=%f&#x27;</span>%(epoch+<span class="number">1</span>,l.item()))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;-&#x27;</span>*<span class="number">21</span>)</span><br><span class="line"><span class="built_in">print</span>(net[<span class="number">0</span>].weight.data)</span><br><span class="line"><span class="built_in">print</span>(net[<span class="number">0</span>].bias.data)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">epoch=1,loss=0.395253</span></span><br><span class="line"><span class="string">epoch=2,loss=0.015482</span></span><br><span class="line"><span class="string">epoch=3,loss=0.000321</span></span><br><span class="line"><span class="string">epoch=4,loss=0.000112</span></span><br><span class="line"><span class="string">epoch=5,loss=0.000151</span></span><br><span class="line"><span class="string">epoch=6,loss=0.000066</span></span><br><span class="line"><span class="string">epoch=7,loss=0.000070</span></span><br><span class="line"><span class="string">epoch=8,loss=0.000097</span></span><br><span class="line"><span class="string">epoch=9,loss=0.000113</span></span><br><span class="line"><span class="string">epoch=10,loss=0.000144</span></span><br><span class="line"><span class="string">---------------------</span></span><br><span class="line"><span class="string">tensor([[2.0000, 3.3993]])</span></span><br><span class="line"><span class="string">tensor([4.2006])</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="Softmax分类模型">Softmax分类模型</h2><p>简要回顾（注意从本段开始，我会稍稍规范化latex公式的书写，会用大写和加粗来区别表示标量<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">x</span></span></span></span>、向量<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">x</mi></mrow><annotation encoding="application/x-tex">\mathbf{x}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.44444em;vertical-align:0em;"></span><span class="mord"><span class="mord mathbf">x</span></span></span></span></span>和矩阵<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">X</mi></mrow><annotation encoding="application/x-tex">\mathbf{X}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68611em;vertical-align:0em;"></span><span class="mord"><span class="mord mathbf">X</span></span></span></span></span>，之前写的就算了，懒得改了）：</p><div class="notdisplayonphone"><p>介绍Softmax（多）分类模型之前先介绍一下Logistic（二）分类模型，Logistic分类模型的目的在于找到一个超平面<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">w</mi><mi mathvariant="bold">x</mi><mo>+</mo><mi>b</mi><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\mathbf{w}\mathbf{x}+b=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>，其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">w</mi><mo>=</mo><mo stretchy="false">[</mo><msub><mi>w</mi><mn>1</mn></msub><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msub><mi>w</mi><mi>n</mi></msub><mo stretchy="false">]</mo><mo>∈</mo><msup><mi>R</mi><mrow><mn>1</mn><mo>×</mo><mi>n</mi></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{w}=[w_1,...,w_n]\in R^{1\times n}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.44444em;vertical-align:0em;"></span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mbin mtight">×</span><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">x</mi><mo>=</mo><mo stretchy="false">[</mo><msub><mi>x</mi><mn>1</mn></msub><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msub><mi>x</mi><mi>n</mi></msub><msup><mo stretchy="false">]</mo><mi>T</mi></msup><mo>∈</mo><msup><mi>R</mi><mrow><mi>n</mi><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{x}=[x_1,...,x_n]^T\in R^{n\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.44444em;vertical-align:0em;"></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.0913309999999998em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose"><span class="mclose">]</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi><mo>∈</mo><mi>R</mi></mrow><annotation encoding="application/x-tex">b\in R</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span></span></span></span>，用于在<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span>维空间中分割两种不同类别（用符号<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span></span>来标记）的数据，分别记为正类（类别1，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">y=1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>）和负类（类别0，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">y=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>）。现给出Logistic分类预测模型：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi>y</mi><mo>^</mo></mover><mo>=</mo><msub><mi>h</mi><mrow><mi mathvariant="bold">w</mi><mo separator="true">,</mo><mi>b</mi></mrow></msub><mo stretchy="false">(</mo><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo><mo>=</mo><mi>σ</mi><mo stretchy="false">(</mo><mi mathvariant="bold">w</mi><mi mathvariant="bold">x</mi><mo>+</mo><mi>b</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\hat{y}=h_{\mathbf{w},b}(\mathbf{x})=\sigma(\mathbf{w}\mathbf{x}+b)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.036108em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight" style="margin-right:0.01597em;">w</span></span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathbf">x</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span></span></span></span>，其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>σ</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mn>1</mn><mrow><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup></mrow></mfrac></mrow><annotation encoding="application/x-tex">\sigma(x)=\frac{1}{1+e^{-x}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.2484389999999999em;vertical-align:-0.403331em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mbin mtight">+</span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7026642857142857em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.403331em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>，有<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>σ</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mi>σ</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo stretchy="false">(</mo><mn>1</mn><mo>−</mo><mi>σ</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\sigma^{\prime}(x)=\sigma(x)(1-\sigma(x))</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mclose">)</span></span></span></span>，由<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>σ</mi><mo stretchy="false">(</mo><mo separator="true">⋅</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\sigma(·)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mpunct">⋅</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mclose">)</span></span></span></span>函数的值域范围（<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[0,1]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose">]</span></span></span></span>区间），我们将模型预测结果<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi>y</mi><mo>^</mo></mover></mrow><annotation encoding="application/x-tex">\hat{y}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span></span></span></span>视为“样本<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">x</mi></mrow><annotation encoding="application/x-tex">\mathbf{x}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.44444em;vertical-align:0em;"></span><span class="mord"><span class="mord mathbf">x</span></span></span></span></span>属于正类的概率值<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi><mo stretchy="false">(</mo><mi>y</mi><mo>=</mo><mn>1</mn><mi mathvariant="normal">∣</mi><mi mathvariant="bold">x</mi><mo separator="true">,</mo><mi mathvariant="bold">w</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">P(y=1|\mathbf{x},\mathbf{w},b)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mord">∣</span><span class="mord"><span class="mord mathbf">x</span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span></span></span></span>”，则<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo>−</mo><mover accent="true"><mi>y</mi><mo>^</mo></mover></mrow><annotation encoding="application/x-tex">1-\hat{y}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span></span></span></span>为样本<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">x</mi></mrow><annotation encoding="application/x-tex">\mathbf{x}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.44444em;vertical-align:0em;"></span><span class="mord"><span class="mord mathbf">x</span></span></span></span></span>属于负类的概率，因此样本<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">x</mi></mrow><annotation encoding="application/x-tex">\mathbf{x}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.44444em;vertical-align:0em;"></span><span class="mord"><span class="mord mathbf">x</span></span></span></span></span>属于类别<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi><mo>=</mo><mo stretchy="false">{</mo><mn>1</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">y=\{1,0\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">0</span><span class="mclose">}</span></span></span></span>的概率为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi><mo stretchy="false">(</mo><mi>y</mi><mi mathvariant="normal">∣</mi><mi mathvariant="bold">x</mi><mo separator="true">,</mo><mi mathvariant="bold">w</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo><mo>=</mo><mi>σ</mi><mo stretchy="false">(</mo><mi mathvariant="bold">w</mi><mi mathvariant="bold">x</mi><mo>+</mo><mi>b</mi><msup><mo stretchy="false">)</mo><mi>y</mi></msup><mo stretchy="false">(</mo><mn>1</mn><mo>−</mo><mi>σ</mi><mo stretchy="false">(</mo><mi mathvariant="bold">w</mi><mi mathvariant="bold">x</mi><mo>+</mo><mi>b</mi><mo stretchy="false">)</mo><msup><mo stretchy="false">)</mo><mrow><mn>1</mn><mo>−</mo><mi>y</mi></mrow></msup></mrow><annotation encoding="application/x-tex">P(y|\mathbf{x},\mathbf{w},b)=\sigma(\mathbf{w}\mathbf{x}+b)^{y}(1-\sigma(\mathbf{w}\mathbf{x}+b))^{1-y}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord">∣</span><span class="mord"><span class="mord mathbf">x</span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">b</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.664392em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">y</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mbin mtight">−</span><span class="mord mathnormal mtight" style="margin-right:0.03588em;">y</span></span></span></span></span></span></span></span></span></span></span></span>（可视作单样本的目标函数，要最大化之），要求该问题中的未知参数<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">w</mi></mrow><annotation encoding="application/x-tex">\mathbf{w}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.44444em;vertical-align:0em;"></span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi></mrow><annotation encoding="application/x-tex">b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span></span></span>，可以采用极大似然法对其进行估计，也就是未知参数取多少时，样本取观测值的概率最大，设训练集总计有<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span>个样本<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">{</mo><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></msup><mo separator="true">,</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mo separator="true">,</mo><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mn>2</mn><mo stretchy="false">)</mo></mrow></msup><mo separator="true">,</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mn>2</mn><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>m</mi><mo stretchy="false">)</mo></mrow></msup><mo separator="true">,</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>m</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">\{(\mathbf{x}^{(1)},y^{(1)}),(\mathbf{x}^{(2)},y^{(2)}),...,(\mathbf{x}^{(m)},y^{(m)})\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathbf">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mtight">1</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mtight">1</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathbf">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mtight">2</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mtight">2</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathbf">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">m</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">m</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mclose">}</span></span></span></span>，则其似然函数为（也就是总体目标函数，仍要最大化之）：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi>L</mi><mrow><mi mathvariant="bold">w</mi><mo separator="true">,</mo><mi>b</mi></mrow><msup><mrow></mrow><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></msubsup><mo>=</mo><msubsup><mo>∏</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><mi>P</mi><mo stretchy="false">(</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mi mathvariant="normal">∣</mi><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi mathvariant="bold">i</mi><mo stretchy="false">)</mo></mrow></msup><mo separator="true">,</mo><mi mathvariant="bold">w</mi><mo separator="true">,</mo><mi>b</mi><mo stretchy="false">)</mo><mo>=</mo><msubsup><mo>∏</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><mo stretchy="false">[</mo><msub><mi>h</mi><mrow><mi mathvariant="bold">w</mi><mo separator="true">,</mo><mi>b</mi></mrow></msub><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><msup><mo stretchy="false">)</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></msup><mo stretchy="false">(</mo><mn>1</mn><mo>−</mo><msub><mi>h</mi><mrow><mi mathvariant="bold">w</mi><mo separator="true">,</mo><mi>b</mi></mrow></msub><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><msup><mo stretchy="false">)</mo><mrow><mn>1</mn><mo>−</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">L_{\mathbf{w},b}^{&#x27;}=\prod\limits_{i=1}^m P(y^{(i)}|\mathbf{x^{(i)}},\mathbf{w},b)=\prod\limits_{i=1}^m[h_{\mathbf{w},b}(\mathbf{x}^{(i)})^{y^{(i)}}(1-h_{\mathbf{w},b}(\mathbf{x}^{(i)}))^{1-y^{(i)}}]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.3616959999999998em;vertical-align:-0.4192159999999999em;"></span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.94248em;"><span style="top:-2.4168920000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight" style="margin-right:0.01597em;">w</span></span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8278285714285715em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4192159999999999em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.329066em;vertical-align:-0.9776689999999999em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∏</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mord">∣</span><span class="mord"><span class="mord"><span class="mord mathbf">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathbf mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.329066em;vertical-align:-0.9776689999999999em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∏</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mopen">[</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight" style="margin-right:0.01597em;">w</span></span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathbf">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.0397em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9667142857142857em;"><span style="top:-2.966714285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5357142857142856em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.325808em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight" style="margin-right:0.01597em;">w</span></span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathbf">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.0397em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mbin mtight">−</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9667142857142857em;"><span style="top:-2.966714285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5357142857142856em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mclose">]</span></span></span></span>，然后再取对数和负数，转换为极小值问题，由此得到我们所熟知的损失函数形式：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>L</mi><mrow><mi mathvariant="bold">w</mi><mo separator="true">,</mo><mi>b</mi></mrow></msub><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><mi>ln</mi><mo>⁡</mo><msubsup><mi>L</mi><mrow><mi mathvariant="bold">w</mi><mo separator="true">,</mo><mi>b</mi></mrow><msup><mrow></mrow><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></msubsup><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><mo stretchy="false">[</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><msub><mi>h</mi><mrow><mi mathvariant="bold">w</mi><mo separator="true">,</mo><mi>b</mi></mrow></msub><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mo stretchy="false">)</mo><mo>+</mo><mo stretchy="false">(</mo><mn>1</mn><mo>−</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><mn>1</mn><mo>−</mo><msub><mi>h</mi><mrow><mi mathvariant="bold">w</mi><mo separator="true">,</mo><mi>b</mi></mrow></msub><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mo stretchy="false">)</mo><mo stretchy="false">]</mo><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><mo stretchy="false">[</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><msup><mover accent="true"><mi>y</mi><mo>^</mo></mover><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mo>+</mo><mo stretchy="false">(</mo><mn>1</mn><mo>−</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><mn>1</mn><mo>−</mo><msup><mover accent="true"><mi>y</mi><mo>^</mo></mover><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">L_{\mathbf{w},b}=-\frac{1}{m}\ln L_{\mathbf{w},b}^{&#x27;}=-\frac{1}{m}\sum\limits_{i=1}^m[y^{(i)}\ln(h_{\mathbf{w},b}(\mathbf{x}^{(i)}))+(1-y^{(i)})\ln(1-h_{\mathbf{w},b}(\mathbf{x}^{(i)}))]=-\frac{1}{m}\sum\limits_{i=1}^m[y^{(i)}\ln(\hat{y}^{(i)})+(1-y^{(i)})\ln(1-\hat{y}^{(i)})]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.969438em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight" style="margin-right:0.01597em;">w</span></span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.3616959999999998em;vertical-align:-0.4192159999999999em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.94248em;"><span style="top:-2.4168920000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight" style="margin-right:0.01597em;">w</span></span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8278285714285715em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4192159999999999em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.329066em;vertical-align:-0.9776689999999999em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mopen">[</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight" style="margin-right:0.01597em;">w</span></span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathbf">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.174108em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight" style="margin-right:0.01597em;">w</span></span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathbf">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mclose">)</span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.329066em;vertical-align:-0.9776689999999999em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mopen">[</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord"><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mclose">]</span></span></span></span><span class="notdisplayonphone">（某些地方还会看到另一种写法，若记<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo><mo>=</mo><mi mathvariant="bold">w</mi><mi mathvariant="bold">x</mi><mo>+</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">f(\mathbf{x})=\mathbf{w}\mathbf{x}+b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathbf">x</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span></span></span>，代入损失函数中可得：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>L</mi><mrow><mi mathvariant="bold">w</mi><mo separator="true">,</mo><mi>b</mi></mrow></msub><mo>=</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><mo stretchy="false">[</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>f</mi><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mo>+</mo><mo stretchy="false">(</mo><mn>1</mn><mo>−</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mi>f</mi><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mo stretchy="false">]</mo><mo>=</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo stretchy="false">(</mo><mo>−</mo><mn>1</mn><msup><mo stretchy="false">)</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></msup><mi>f</mi><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">L_{\mathbf{w},b}=\frac{1}{m}\sum\limits_{i=1}^m[y^{(i)}\ln(1+e^{-f(\mathbf{x}^{(i)})})+(1-y^{(i)})\ln(1+e^{f(\mathbf{x}^{(i)})})]=\frac{1}{m}\sum\limits_{i=1}^m\ln(1+e^{(-1)^{y^{(i)}}f(\mathbf{x}^{(i)})})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.969438em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight" style="margin-right:0.01597em;">w</span></span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.329066em;vertical-align:-0.9776689999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mopen">[</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.2896999999999998em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.0396999999999998em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight" style="margin-right:0.10764em;">f</span><span class="mopen mtight">(</span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9667142857142857em;"><span style="top:-2.966714285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5357142857142856em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.2896999999999998em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.0396999999999998em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.10764em;">f</span><span class="mopen mtight">(</span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9667142857142857em;"><span style="top:-2.966714285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5357142857142856em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.329066em;vertical-align:-0.9776689999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.4916999999999998em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.2416999999999998em;"><span style="top:-3.2417em;margin-right:0.05em;"><span class="pstrut" style="height:2.8787em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mtight">−</span><span class="mord mtight">1</span><span class="mclose mtight"><span class="mclose mtight">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.2552857142857143em;"><span style="top:-3.2552857142857143em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mord mathnormal mtight" style="margin-right:0.10764em;">f</span><span class="mopen mtight">(</span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9667142857142857em;"><span style="top:-2.966714285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5357142857142856em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>，如果正负类别标签你不是记作<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>或<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0</mn></mrow><annotation encoding="application/x-tex">0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>，而是<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>或<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">-1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">−</span><span class="mord">1</span></span></span></span>，那么损失将写为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>L</mi><mrow><mi mathvariant="bold">w</mi><mo separator="true">,</mo><mi>b</mi></mrow></msub><mo>=</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mi>f</mi><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">L_{\mathbf{w},b}=\frac{1}{m}\sum\limits_{i=1}^m\ln(1+e^{-y^{(i)}f(\mathbf{x}^{(i)})})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.969438em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight" style="margin-right:0.01597em;">w</span></span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.329066em;vertical-align:-0.9776689999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.2896999999999998em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.0396999999999998em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9667142857142857em;"><span style="top:-2.966714285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5357142857142856em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mord mathnormal mtight" style="margin-right:0.10764em;">f</span><span class="mopen mtight">(</span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9667142857142857em;"><span style="top:-2.966714285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5357142857142856em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>）</span></p></div><div class="img-wrap"><div class="img-bg"><img class="img" src="https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210609155526.png" alt="图4.&nbsp;Softmax多分类模型是一个单层（感知器）神经网络[3]" onerror="this.onerror=null,this.src='https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210328224519.jpg'" /></div></div><div class="onlydisplayonphone"><p>Softmax（多）分类是Logistic（二）分类的一个推广，或者说后者是前者的一个特例。和线性回归模型相比，Softmax也是一个单层神经网络，只不过输出层有多个节点（等于类别数）并且加了一个sigmoid激活函数。相比于二分类寻找单个超平面，多分类会寻找多个超平面用于分割多种（大于2）不同的类别：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi mathvariant="bold">w</mi><mn>1</mn></msub><mi mathvariant="bold">x</mi><mo>+</mo><msub><mi>b</mi><mn>1</mn></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\mathbf{w}_1\mathbf{x}+b_1=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>、<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi mathvariant="bold">w</mi><mn>2</mn></msub><mi mathvariant="bold">x</mi><mo>+</mo><msub><mi>b</mi><mn>2</mn></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\mathbf{w}_2\mathbf{x}+b_2=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>、…，为了方便推导，我们将超平面<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">w</mi><mi mathvariant="bold">x</mi><mo>+</mo><mi>b</mi><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\mathbf{w}\mathbf{x}+b=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>中的参数部分合起来（本节推导参考[2]），记<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold-italic">θ</mi><mo>=</mo><mo stretchy="false">[</mo><mi>b</mi><mo separator="true">,</mo><mi mathvariant="bold">w</mi><msup><mo stretchy="false">]</mo><mi>T</mi></msup><mo>∈</mo><msup><mi>R</mi><mrow><mo stretchy="false">(</mo><mi>n</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\boldsymbol{\theta}=[b,\mathbf{w}]^T\in R^{(n+1)\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord"><span class="mord"><span class="mord boldsymbol" style="margin-right:0.03194em;">θ</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.0913309999999998em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord mathnormal">b</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="mclose"><span class="mclose">]</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span><span class="mclose mtight">)</span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">x</mi><mo>=</mo><mo stretchy="false">[</mo><mn>1</mn><mo separator="true">,</mo><msub><mi>x</mi><mn>1</mn></msub><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msub><mi>x</mi><mi>n</mi></msub><mo stretchy="false">]</mo><mo>∈</mo><msup><mi>R</mi><mrow><mo stretchy="false">(</mo><mi>n</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{x}=[1,x_1,...,x_n]\in R^{(n+1)\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.44444em;vertical-align:0em;"></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span><span class="mclose mtight">)</span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>，于是超平面变为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant="bold-italic">θ</mi><mi>T</mi></msup><mi mathvariant="bold">x</mi><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\boldsymbol{\theta}^T\mathbf{x}=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9256709999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord"><span class="mord"><span class="mord boldsymbol" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9256709999999999em;"><span style="top:-3.1473400000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>，假设是<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>分类，全部未知参数记作<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">Θ</mi><mo>=</mo><mo stretchy="false">[</mo><msub><mi mathvariant="bold-italic">θ</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi mathvariant="bold-italic">θ</mi><mn>2</mn></msub><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msub><mi mathvariant="bold-italic">θ</mi><mi>k</mi></msub><mo stretchy="false">]</mo><mo>∈</mo><msup><mi>R</mi><mrow><mo stretchy="false">(</mo><mi>n</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo><mo>×</mo><mi>k</mi></mrow></msup></mrow><annotation encoding="application/x-tex">\Theta=[\boldsymbol{\theta}_1,\boldsymbol{\theta}_2,...,\boldsymbol{\theta}_k]\in R^{(n+1)\times k}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord">Θ</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord"><span class="mord"><span class="mord"><span class="mord boldsymbol" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord"><span class="mord"><span class="mord boldsymbol" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord"><span class="mord"><span class="mord boldsymbol" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span><span class="mclose mtight">)</span><span class="mbin mtight">×</span><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span></span></span></span></span></span></span></span></span>，现给出Softmax分类预测模型：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi mathvariant="bold">y</mi><mo>^</mo></mover><mo>=</mo><msub><mi>h</mi><mi mathvariant="normal">Θ</mi></msub><mo stretchy="false">(</mo><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo><mo>=</mo><mtext mathvariant="bold">softmax</mtext><mo stretchy="false">(</mo><msup><mi mathvariant="normal">Θ</mi><mi>T</mi></msup><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo><mo>∈</mo><msup><mi>R</mi><mrow><mi>k</mi><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\hat{\mathbf{y}}=h_\Theta(\mathbf{x})=\textbf{softmax}(\Theta^T\mathbf{x})\in R^{k\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.90232em;vertical-align:-0.19444em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.70788em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span></span></span><span style="top:-3.01344em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">Θ</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathbf">x</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.0913309999999998em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord textbf">softmax</span></span><span class="mopen">(</span><span class="mord"><span class="mord">Θ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8491079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>，其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="bold">softmax</mtext><mo stretchy="false">(</mo><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mrow><mi>exp</mi><mo>⁡</mo><mo stretchy="false">(</mo><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo></mrow><mrow><mo>∑</mo><mi>exp</mi><mo>⁡</mo><mo stretchy="false">(</mo><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo></mrow></mfrac></mrow><annotation encoding="application/x-tex">\textbf{softmax}(\mathbf{x})=\frac{\exp(\mathbf{x})}{\sum\exp(\mathbf{x})}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord textbf">softmax</span></span><span class="mopen">(</span><span class="mord"><span class="mord mathbf">x</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.530007em;vertical-align:-0.520007em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.01em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop op-symbol small-op mtight" style="position:relative;top:-0.0000050000000000050004em;">∑</span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mop mtight"><span class="mtight">e</span><span class="mtight">x</span><span class="mtight">p</span></span><span class="mopen mtight">(</span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="mclose mtight">)</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.485em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop mtight"><span class="mtight">e</span><span class="mtight">x</span><span class="mtight">p</span></span><span class="mopen mtight">(</span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.520007em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>（分母表示向量元素求和），其批量（<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span>个样本）损失函数直接参照二分类，有<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>L</mi><mi mathvariant="normal">Θ</mi></msub><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><msubsup><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msubsup><mi mathvariant="bold">y</mi><mi>j</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msubsup><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><msubsup><mover accent="true"><mi mathvariant="bold">y</mi><mo>^</mo></mover><mi>j</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msubsup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">L_\Theta=-\frac{1}{m}\sum\limits_{i=1}^m\sum\limits_{j=1}^k\mathbf{y}_j^{(i)}\ln(\hat{\mathbf{y}}_j^{(i)})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">Θ</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.64989em;vertical-align:-1.113777em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5361130000000003em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.113777em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0448em;"><span style="top:-2.4231360000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.2198em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4129719999999999em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord"><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.70788em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span></span></span><span style="top:-3.01344em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0448em;"><span style="top:-2.4231360000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.2198em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4129719999999999em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>，其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant="bold">y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{y}^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0824399999999998em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span>是样本<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{x}^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span>所属标量类别<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">y^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0824399999999998em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span>的one-hot编码向量）</p></div><div class="notdisplayonphone"><!--此处的大段latex在手机端取消渲染（display置为none），否则由于手机端渲染太吃力会导致导航栏不能正常工作（有时正常有时不正常）--><p>Softmax（多）分类是Logistic（二）分类的一个推广，或者说后者是前者的一个特例。和线性回归模型相比，Softmax也是一个单层神经网络，只不过输出层有多个节点（等于类别数）并且加了一个sigmoid激活函数。相比于二分类寻找单个超平面，多分类会寻找多个超平面用于分割多种（大于2）不同的类别：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi mathvariant="bold">w</mi><mn>1</mn></msub><mi mathvariant="bold">x</mi><mo>+</mo><msub><mi>b</mi><mn>1</mn></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\mathbf{w}_1\mathbf{x}+b_1=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>、<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi mathvariant="bold">w</mi><mn>2</mn></msub><mi mathvariant="bold">x</mi><mo>+</mo><msub><mi>b</mi><mn>2</mn></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\mathbf{w}_2\mathbf{x}+b_2=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>、…，为了方便推导，我们将超平面<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">w</mi><mi mathvariant="bold">x</mi><mo>+</mo><mi>b</mi><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\mathbf{w}\mathbf{x}+b=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>中的参数部分合起来（本节推导参考[2]，<!--不过该书也是符号林立，-->下面将纠正其中损失函数求偏导部分的一个因符号混乱引发的错误），记<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold-italic">θ</mi><mo>=</mo><mo stretchy="false">[</mo><mi>b</mi><mo separator="true">,</mo><mi mathvariant="bold">w</mi><msup><mo stretchy="false">]</mo><mi>T</mi></msup><mo>∈</mo><msup><mi>R</mi><mrow><mo stretchy="false">(</mo><mi>n</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\boldsymbol{\theta}=[b,\mathbf{w}]^T\in R^{(n+1)\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord"><span class="mord"><span class="mord boldsymbol" style="margin-right:0.03194em;">θ</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.0913309999999998em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord mathnormal">b</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">w</span></span><span class="mclose"><span class="mclose">]</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span><span class="mclose mtight">)</span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">x</mi><mo>=</mo><mo stretchy="false">[</mo><mn>1</mn><mo separator="true">,</mo><msub><mi>x</mi><mn>1</mn></msub><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msub><mi>x</mi><mi>n</mi></msub><mo stretchy="false">]</mo><mo>∈</mo><msup><mi>R</mi><mrow><mo stretchy="false">(</mo><mi>n</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{x}=[1,x_1,...,x_n]\in R^{(n+1)\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.44444em;vertical-align:0em;"></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span><span class="mclose mtight">)</span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>，于是超平面变为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant="bold-italic">θ</mi><mi>T</mi></msup><mi mathvariant="bold">x</mi><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\boldsymbol{\theta}^T\mathbf{x}=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9256709999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord"><span class="mord"><span class="mord boldsymbol" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9256709999999999em;"><span style="top:-3.1473400000000002em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>，假设是<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>分类，全部未知参数记作<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">Θ</mi><mo>=</mo><mo stretchy="false">[</mo><msub><mi mathvariant="bold-italic">θ</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi mathvariant="bold-italic">θ</mi><mn>2</mn></msub><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msub><mi mathvariant="bold-italic">θ</mi><mi>k</mi></msub><mo stretchy="false">]</mo><mo>∈</mo><msup><mi>R</mi><mrow><mo stretchy="false">(</mo><mi>n</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo><mo>×</mo><mi>k</mi></mrow></msup></mrow><annotation encoding="application/x-tex">\Theta=[\boldsymbol{\theta}_1,\boldsymbol{\theta}_2,...,\boldsymbol{\theta}_k]\in R^{(n+1)\times k}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord">Θ</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord"><span class="mord"><span class="mord"><span class="mord boldsymbol" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord"><span class="mord"><span class="mord boldsymbol" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord"><span class="mord"><span class="mord boldsymbol" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span><span class="mclose mtight">)</span><span class="mbin mtight">×</span><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span></span></span></span></span></span></span></span></span>，现给出Softmax分类预测模型：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi mathvariant="bold">y</mi><mo>^</mo></mover><mo>=</mo><msub><mi>h</mi><mi mathvariant="normal">Θ</mi></msub><mo stretchy="false">(</mo><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mn>1</mn><mrow><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>i</mi><mi>T</mi></msubsup><mi mathvariant="bold">x</mi></mrow></msup></mrow></mfrac><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mn>1</mn><mi>T</mi></msubsup><mi mathvariant="bold">x</mi></mrow></msup></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mn>2</mn><mi>T</mi></msubsup><mi mathvariant="bold">x</mi></mrow></msup></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi><mi mathvariant="normal">⋮</mi><mpadded height="+0em" voffset="0em"><mspace mathbackground="black" width="0em" height="1.5em"></mspace></mpadded></mi></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>k</mi><mi>T</mi></msubsup><mi mathvariant="bold">x</mi></mrow></msup></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow><mo>=</mo><mtext mathvariant="bold">softmax</mtext><mo stretchy="false">(</mo><msup><mi mathvariant="normal">Θ</mi><mi>T</mi></msup><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo><mo>≡</mo><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>P</mi><mo stretchy="false">(</mo><mi>y</mi><mo>=</mo><mn>1</mn><mi mathvariant="normal">∣</mi><mi mathvariant="bold">x</mi><mo separator="true">,</mo><mi mathvariant="normal">Θ</mi><mo stretchy="false">)</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>P</mi><mo stretchy="false">(</mo><mi>y</mi><mo>=</mo><mn>2</mn><mi mathvariant="normal">∣</mi><mi mathvariant="bold">x</mi><mo separator="true">,</mo><mi mathvariant="normal">Θ</mi><mo stretchy="false">)</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi><mi mathvariant="normal">⋮</mi><mpadded height="+0em" voffset="0em"><mspace mathbackground="black" width="0em" height="1.5em"></mspace></mpadded></mi></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>P</mi><mo stretchy="false">(</mo><mi>y</mi><mo>=</mo><mi>k</mi><mi mathvariant="normal">∣</mi><mi mathvariant="bold">x</mi><mo separator="true">,</mo><mi mathvariant="normal">Θ</mi><mo stretchy="false">)</mo></mrow></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow><mo>∈</mo><msup><mi>R</mi><mrow><mi>k</mi><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\hat{\mathbf{y}}=h_\Theta(\mathbf{x})=\frac{1}{\sum\limits_{i=1}^ke^{\boldsymbol{\theta}_i^T\mathbf{x}}}\begin{bmatrix}e^{\boldsymbol{\theta}_1^T\mathbf{x}}\\e^{\boldsymbol{\theta}_2^T\mathbf{x}}\\\vdots\\e^{\boldsymbol{\theta}_k^T\mathbf{x}}\end{bmatrix}=\textbf{softmax}(\Theta^T\mathbf{x})\equiv \begin{bmatrix}P(y=1|\mathbf{x},\Theta)\\P(y=2|\mathbf{x},\Theta)\\\vdots\\P(y=k|\mathbf{x},\Theta)\end{bmatrix}\in R^{k\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.90232em;vertical-align:-0.19444em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.70788em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span></span></span><span style="top:-3.01344em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">Θ</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathbf">x</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:6.00503em;vertical-align:-2.75004em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.19em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop op-limits mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5890335714285715em;"><span style="top:-1.8629092857142857em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-2.7500050000000003em;"><span class="pstrut" style="height:2.75em;"></span><span><span class="mop op-symbol small-op mtight">∑</span></span></span><span style="top:-3.700005em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.0300907142857143em;"><span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.2069285714285716em;"><span style="top:-3.206928571428572em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.7343785714285715em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.02813em;"><span style="top:-2.1726099999999997em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight">i</span></span><span style="top:-3.02813em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5107200000000001em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.3423235em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.5063235em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.6433870000000002em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2549900000000003em;"><span style="top:-1.0499800000000006em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎣</span></span></span><span style="top:-2.1999800000000005em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-2.79598em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.39198em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.9879800000000003em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-4.0139700000000005em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-5.25499em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎡</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.75004em;"><span></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2295475em;"><span style="top:-5.9106825em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.006365em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9190928571428572em;"><span style="top:-2.214em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">1</span></span></span><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-4.544317500000001em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.006365em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9190928571428572em;"><span style="top:-2.214em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-2.6843174999999997em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord">⋮</span><span class="mord rule" style="border-right-width:0em;border-top-width:1.5em;bottom:0em;"></span></span></span></span><span style="top:-1.3179524999999994em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.006365em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9190928571428572em;"><span style="top:-2.214em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7295475000000007em;"><span></span></span></span></span></span></span></span><span class="mclose"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2549900000000003em;"><span style="top:-1.0499800000000006em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎦</span></span></span><span style="top:-2.1999800000000005em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-2.79598em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.39198em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.9879800000000003em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-4.0139700000000005em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-5.25499em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎤</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.75004em;"><span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.0913309999999998em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord textbf">softmax</span></span><span class="mopen">(</span><span class="mord"><span class="mord">Θ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:5.459999999999999em;vertical-align:-2.4799999999999995em;"></span><span class="minner"><span class="mopen"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.953995em;"><span style="top:-1.3499850000000007em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎣</span></span></span><span style="top:-2.4999850000000006em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.0959850000000007em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.6919850000000003em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.712975em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-4.953995em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎡</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.4500349999999997em;"><span></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.9799999999999995em;"><span style="top:-5.8275em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">1</span><span class="mord">∣</span><span class="mord"><span class="mord mathbf">x</span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">Θ</span><span class="mclose">)</span></span></span><span style="top:-4.6275em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">2</span><span class="mord">∣</span><span class="mord"><span class="mord mathbf">x</span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">Θ</span><span class="mclose">)</span></span></span><span style="top:-2.7674999999999996em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord">⋮</span><span class="mord rule" style="border-right-width:0em;border-top-width:1.5em;bottom:0em;"></span></span></span></span><span style="top:-1.5675000000000006em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord">∣</span><span class="mord"><span class="mord mathbf">x</span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">Θ</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.4799999999999995em;"><span></span></span></span></span></span></span></span><span class="mclose"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.953995em;"><span style="top:-1.3499850000000007em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎦</span></span></span><span style="top:-2.4999850000000006em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.0959850000000007em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.6919850000000003em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.712975em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-4.953995em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎤</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.4500349999999997em;"><span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8491079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>，其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="bold">softmax</mtext><mo stretchy="false">(</mo><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mrow><mi>exp</mi><mo>⁡</mo><mo stretchy="false">(</mo><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo></mrow><mrow><mo>∑</mo><mi>exp</mi><mo>⁡</mo><mo stretchy="false">(</mo><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo></mrow></mfrac></mrow><annotation encoding="application/x-tex">\textbf{softmax}(\mathbf{x})=\frac{\exp(\mathbf{x})}{\sum\exp(\mathbf{x})}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord textbf">softmax</span></span><span class="mopen">(</span><span class="mord"><span class="mord mathbf">x</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.530007em;vertical-align:-0.520007em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.01em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop op-symbol small-op mtight" style="position:relative;top:-0.0000050000000000050004em;">∑</span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mop mtight"><span class="mtight">e</span><span class="mtight">x</span><span class="mtight">p</span></span><span class="mopen mtight">(</span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="mclose mtight">)</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.485em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop mtight"><span class="mtight">e</span><span class="mtight">x</span><span class="mtight">p</span></span><span class="mopen mtight">(</span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.520007em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>（分母表示向量元素求和）</p><p>和Logistic分类的联系：假设<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">k=2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span>，则<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>h</mi><mi mathvariant="normal">Θ</mi></msub><mo stretchy="false">(</mo><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo><mo>=</mo><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mfrac><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mn>1</mn><mi>T</mi></msubsup><mi mathvariant="bold">x</mi></mrow></msup><mrow><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mn>1</mn><mi>T</mi></msubsup><mi mathvariant="bold">x</mi></mrow></msup><mo>+</mo><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mn>2</mn><mi>T</mi></msubsup><mi mathvariant="bold">x</mi></mrow></msup></mrow></mfrac></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mfrac><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mn>2</mn><mi>T</mi></msubsup><mi mathvariant="bold">x</mi></mrow></msup><mrow><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mn>1</mn><mi>T</mi></msubsup><mi mathvariant="bold">x</mi></mrow></msup><mo>+</mo><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mn>2</mn><mi>T</mi></msubsup><mi mathvariant="bold">x</mi></mrow></msup></mrow></mfrac></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow><mo>=</mo><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mfrac><mn>1</mn><mrow><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo stretchy="false">(</mo><msub><mi mathvariant="bold-italic">θ</mi><mn>2</mn></msub><mo>−</mo><msub><mi mathvariant="bold-italic">θ</mi><mn>1</mn></msub><msup><mo stretchy="false">)</mo><mi>T</mi></msup><mi mathvariant="bold">x</mi></mrow></msup></mrow></mfrac><mo>≡</mo><mi>v</mi></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mn>1</mn><mo>−</mo><mi>v</mi></mrow></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow></mrow><annotation encoding="application/x-tex">h_\Theta(\mathbf{x})=\begin{bmatrix}\frac{e^{\boldsymbol{\theta}_1^T\mathbf{x}}}{e^{\boldsymbol{\theta}_1^T\mathbf{x}}+e^{\boldsymbol{\theta}_2^T\mathbf{x}}}\\\frac{e^{\boldsymbol{\theta}_2^T\mathbf{x}}}{e^{\boldsymbol{\theta}_1^T\mathbf{x}}+e^{\boldsymbol{\theta}_2^T\mathbf{x}}}\end{bmatrix}=\begin{bmatrix}\frac{1}{1+e^{(\boldsymbol{\theta}_2-\boldsymbol{\theta}_1)^T\mathbf{x}}}\equiv v\\1-v\end{bmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">Θ</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathbf">x</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.8900120000000005em;vertical-align:-1.6950060000000002em;"></span><span class="minner"><span class="mopen"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.0510099999999998em;"><span style="top:-2.2500000000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎣</span></span></span><span style="top:-2.8099900000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-4.05101em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎡</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.55002em;"><span></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.1950060000000002em;"><span style="top:-4.195006em;"><span class="pstrut" style="height:3.2393650000000003em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.239365em;"><span style="top:-2.35269em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.196157142857143em;"><span style="top:-3.1961571428571434em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.7343785714285715em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.02813em;"><span style="top:-2.18769em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mtight">1</span></span><span style="top:-3.02813em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.49564em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span></span></span></span></span></span></span></span></span><span class="mbin mtight">+</span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.196157142857143em;"><span style="top:-3.1961571428571434em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.7343785714285715em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.02813em;"><span style="top:-2.18769em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mtight">2</span></span><span style="top:-3.02813em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.49564em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.2076642857142859em;"><span style="top:-3.207664285714286em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.776664285714286em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0873300000000001em;"><span style="top:-2.2468899999999996em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mtight">1</span></span><span style="top:-3.0873299999999997em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.43644em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7056410000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-2.25em;"><span class="pstrut" style="height:3.2393650000000003em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.239365em;"><span style="top:-2.35269em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.196157142857143em;"><span style="top:-3.1961571428571434em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.7343785714285715em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.02813em;"><span style="top:-2.18769em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mtight">1</span></span><span style="top:-3.02813em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.49564em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span></span></span></span></span></span></span></span></span><span class="mbin mtight">+</span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.196157142857143em;"><span style="top:-3.1961571428571434em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.7343785714285715em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.02813em;"><span style="top:-2.18769em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mtight">2</span></span><span style="top:-3.02813em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.49564em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.2076642857142859em;"><span style="top:-3.207664285714286em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.776664285714286em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0873300000000001em;"><span style="top:-2.2468899999999996em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mtight">2</span></span><span style="top:-3.0873299999999997em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.43644em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7056410000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.6950060000000002em;"><span></span></span></span></span></span></span></span><span class="mclose"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.0510099999999998em;"><span style="top:-2.2500000000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎦</span></span></span><span style="top:-2.8099900000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-4.05101em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎤</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.55002em;"><span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.627349em;vertical-align:-1.0636745000000003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">[</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5636744999999999em;"><span style="top:-3.7185665em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.4760899999999997em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mbin mtight">+</span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.0198714285714288em;"><span style="top:-3.0198714285714288em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.698092857142857em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3447999999999998em;margin-right:0.1em;"><span class="pstrut" style="height:2.64444em;"></span><span class="mord mtight">2</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.29964em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3447999999999998em;margin-right:0.1em;"><span class="pstrut" style="height:2.64444em;"></span><span class="mord mtight">1</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.29964em;"><span></span></span></span></span></span></span><span class="mclose mtight"><span class="mclose mtight">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.97733em;"><span style="top:-2.97733em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mathbf mtight">x</span></span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5822410000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span></span></span><span style="top:-2.2963254999999996em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.0636745000000003em;"><span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">]</span></span></span></span></span></span>，其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>v</mi></mrow><annotation encoding="application/x-tex">v</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span></span></span></span>不就是<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>σ</mi><mo stretchy="false">(</mo><mo stretchy="false">(</mo><msub><mi mathvariant="bold-italic">θ</mi><mn>2</mn></msub><mo>−</mo><msub><mi mathvariant="bold-italic">θ</mi><mn>1</mn></msub><msup><mo stretchy="false">)</mo><mi>T</mi></msup><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\sigma((\boldsymbol{\theta}_2-\boldsymbol{\theta}_1)^T\mathbf{x})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord"><span class="mord boldsymbol" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0913309999999998em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord"><span class="mord"><span class="mord boldsymbol" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathbf">x</span></span><span class="mclose">)</span></span></span></span>么，这正是Logistic分类预测模型的表达形式</p><p>至于Softmax分类模型的损失函数，对于<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span>个批量数据，直接仿照Logistic分类，给出总体损失函数：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>L</mi><mi mathvariant="normal">Θ</mi></msub><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><msubsup><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><mo stretchy="false">[</mo><mi>I</mi><mo stretchy="false">{</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo>=</mo><mi>j</mi><mo stretchy="false">}</mo><mi>ln</mi><mo>⁡</mo><mfrac><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>j</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup><mrow><msubsup><mo>∑</mo><mrow><mi>l</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>l</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup></mrow></mfrac><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">L_\Theta=-\frac{1}{m}\sum\limits_{i=1}^m\sum\limits_{j=1}^k[I\{y^{(i)}=j\}\ln\frac{e^{\boldsymbol{\theta}_j^T\mathbf{x}^{(i)}}}{\sum\limits_{l=1}^ke^{\boldsymbol{\theta}_l^T\mathbf{x}^{(i)}}}]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">Θ</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.64989em;vertical-align:-1.113777em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5361130000000003em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.113777em;"><span></span></span></span></span></span><span class="mopen">[</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mopen">{</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.030252em;vertical-align:-1.660847em;"></span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mclose">}</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.369405em;"><span style="top:-2.19em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop op-limits mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5890335714285715em;"><span style="top:-1.8379664285714286em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-2.7500050000000003em;"><span class="pstrut" style="height:2.75em;"></span><span><span class="mop op-symbol small-op mtight">∑</span></span></span><span style="top:-3.700005em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.0550335714285715em;"><span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.288742857142857em;"><span style="top:-3.288742857142857em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.79125em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.02813em;"><span style="top:-2.1488000000000005em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span><span style="top:-3.0392400000000004em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5456399999999999em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.10775em;"><span style="top:-3.1077500000000002em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.3423235em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.5063235em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.3934357142857143em;"><span style="top:-3.393435714285714em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0873300000000001em;"><span style="top:-2.23181em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span><span style="top:-3.0873299999999997em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.64596em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.660847em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose">]</span></span></span></span>，其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>I</mi></mrow><annotation encoding="application/x-tex">I</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span></span></span></span>为指示函数，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>I</mi><mo stretchy="false">{</mo><mtext>condition</mtext><mo stretchy="false">}</mo><mo>=</mo><mrow><mo fence="true">{</mo><mtable rowspacing="0.3599999999999999em" columnalign="left left" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mn>1</mn><mo separator="true">,</mo><mtext>if condition is true</mtext></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mn>0</mn><mo separator="true">,</mo><mtext>if condition is false</mtext></mrow></mstyle></mtd></mtr></mtable></mrow></mrow><annotation encoding="application/x-tex">I\{\text{condition}\}=\begin{cases}1,\text{if condition is true}\\0,\text{if condition is false}\end{cases}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mopen">{</span><span class="mord text"><span class="mord">condition</span></span><span class="mclose">}</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.0000299999999998em;vertical-align:-1.25003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size4">{</span></span><span class="mord"><span class="mtable"><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.69em;"><span style="top:-3.69em;"><span class="pstrut" style="height:3.008em;"></span><span class="mord"><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord text"><span class="mord">if condition is true</span></span></span></span><span style="top:-2.25em;"><span class="pstrut" style="height:3.008em;"></span><span class="mord"><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord text"><span class="mord">if condition is false</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.19em;"><span></span></span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></p><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>参考书[2]错误纠正</span></div>    <div class="hide-content"><p>对书中P29求导部分的更正：<br><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi mathvariant="normal">∇</mi><msub><mi mathvariant="bold-italic">θ</mi><mi>q</mi></msub><msub><mi>L</mi><mi mathvariant="normal">Θ</mi></msub></msubsup><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><msubsup><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><mo stretchy="false">[</mo><mi>I</mi><mo stretchy="false">{</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo>=</mo><mi>j</mi><mo stretchy="false">}</mo><mfrac><mi mathvariant="normal">∂</mi><mrow><mi mathvariant="normal">∂</mi><msub><mi mathvariant="bold-italic">θ</mi><mi>q</mi></msub></mrow></mfrac><mo stretchy="false">(</mo><mi>ln</mi><mo>⁡</mo><mfrac><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>j</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup><mrow><msubsup><mo>∑</mo><mrow><mi>l</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>l</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup></mrow></mfrac><mo stretchy="false">)</mo><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">\nabla_{\boldsymbol{\theta}_q}^{L_\Theta}=-\frac{1}{m}\sum\limits_{i=1}^m\sum\limits_{j=1}^k[I\{y^{(i)}=j\}\frac{\partial}{\partial \boldsymbol{\theta}_q}(\ln\frac{e^{\boldsymbol{\theta}_j^T\mathbf{x}^{(i)}}}{\sum\limits_{l=1}^ke^{\boldsymbol{\theta}_l^T\mathbf{x}^{(i)}}})]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.4220639999999998em;vertical-align:-0.4986279999999999em;"></span><span class="mord"><span class="mord">∇</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9234359999999999em;"><span style="top:-2.398692em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285716em;"><span style="top:-2.357em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">q</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2818857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.1451050000000005em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3567071428571427em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">Θ</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.14329285714285717em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4986279999999999em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.64989em;vertical-align:-1.113777em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5361130000000003em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.113777em;"><span></span></span></span></span></span><span class="mopen">[</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mopen">{</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.030252em;vertical-align:-1.660847em;"></span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mclose">}</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285716em;"><span style="top:-2.357em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">q</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2818857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5423199999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mopen">(</span><span class="mop">ln</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.369405em;"><span style="top:-2.19em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop op-limits mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5890335714285715em;"><span style="top:-1.8379664285714286em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-2.7500050000000003em;"><span class="pstrut" style="height:2.75em;"></span><span><span class="mop op-symbol small-op mtight">∑</span></span></span><span style="top:-3.700005em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.0550335714285715em;"><span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.288742857142857em;"><span style="top:-3.288742857142857em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.79125em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.02813em;"><span style="top:-2.1488000000000005em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span><span style="top:-3.0392400000000004em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5456399999999999em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.10775em;"><span style="top:-3.1077500000000002em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.3423235em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.5063235em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.3934357142857143em;"><span style="top:-3.393435714285714em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0873300000000001em;"><span style="top:-2.23181em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span><span style="top:-3.0873299999999997em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.64596em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.660847em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose">)</span><span class="mclose">]</span></span></span></span>，由<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>ln</mi><mo>⁡</mo></mrow><annotation encoding="application/x-tex">\ln</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mop">ln</span></span></span></span>函数求导规则<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mi>d</mi><mrow><mi>d</mi><mi>x</mi></mrow></mfrac><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><mi>u</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mn>1</mn><mi>u</mi></mfrac><mfrac><mrow><mi>d</mi><mi>u</mi></mrow><mrow><mi>d</mi><mi>x</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">\frac{d}{dx}\ln(u)=\frac{1}{u}\frac{du}{dx}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.2251079999999999em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">d</span><span class="mord mathnormal mtight">x</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">d</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord mathnormal">u</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.2251079999999999em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">u</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">d</span><span class="mord mathnormal mtight">x</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">d</span><span class="mord mathnormal mtight">u</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>以及分数求导<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mfrac><mi>u</mi><mi>v</mi></mfrac><msup><mo stretchy="false">)</mo><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mfrac><mrow><msup><mi>u</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mi>v</mi><mo>−</mo><mi>u</mi><msup><mi>v</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><msup><mi>v</mi><mn>2</mn></msup></mfrac></mrow><annotation encoding="application/x-tex">(\frac{u}{v})^{\prime}=\frac{u^{\prime}v-uv^{\prime}}{v^2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.096892em;vertical-align:-0.345em;"></span><span class="mopen">(</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.695392em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">v</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">u</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.31848em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.97348em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7463142857142857em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">u</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8278285714285715em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mord mathnormal mtight" style="margin-right:0.03588em;">v</span><span class="mbin mtight">−</span><span class="mord mathnormal mtight">u</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8278285714285715em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>以及<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mi mathvariant="normal">∂</mi><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>j</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup></mrow><mrow><mi mathvariant="normal">∂</mi><msub><mi mathvariant="bold-italic">θ</mi><mi>q</mi></msub></mrow></mfrac><mo>=</mo><mrow><mo fence="true">{</mo><mtable rowspacing="0.3599999999999999em" columnalign="left left" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>j</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo separator="true">,</mo><mi>q</mi><mo>=</mo><mi>j</mi></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mn>0</mn><mo separator="true">,</mo><mi>q</mi><mo mathvariant="normal">≠</mo><mi>j</mi></mrow></mstyle></mtd></mtr></mtable></mrow><mo>=</mo><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>j</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup><mi>I</mi><mo stretchy="false">{</mo><mi>q</mi><mo>=</mo><mi>j</mi><mo stretchy="false">}</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">\frac{\partial e^{\boldsymbol{\theta}_j^T\mathbf{x}^{(i)}}}{\partial \boldsymbol{\theta}_q}=\begin{cases}e^{\boldsymbol{\theta}_j^T\mathbf{x}^{(i)}}\mathbf{x}^{(i)},q=j\\0,q\ne j\end{cases}=e^{\boldsymbol{\theta}_j^T\mathbf{x}^{(i)}}I\{q=j\}\mathbf{x}^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.911725em;vertical-align:-0.5423199999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.369405em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285716em;"><span style="top:-2.357em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">q</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2818857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight" style="margin-right:0.05556em;">∂</span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.3934357142857143em;"><span style="top:-3.393435714285714em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0873300000000001em;"><span style="top:-2.23181em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span><span style="top:-3.0873299999999997em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.64596em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5423199999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.0000299999999998em;vertical-align:-1.25003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size4">{</span></span><span class="mord"><span class="mtable"><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7269349999999997em;"><span style="top:-3.7269349999999997em;"><span class="pstrut" style="height:3.08187em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.0818699999999999em;"><span style="top:-3.10517em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9190928571428572em;"><span style="top:-2.214em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.42488571428571426em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9667142857142857em;"><span style="top:-2.966714285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5357142857142856em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mord"><span class="mord"><span class="mord mathbf">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span></span></span><span style="top:-2.2869349999999997em;"><span class="pstrut" style="height:3.08187em;"></span><span class="mord"><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><span class="mrel"><span class="mord vbox"><span class="thinbox"><span class="rlap"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="inner"><span class="mrel"></span></span><span class="fix"></span></span></span></span></span><span class="mrel">=</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.226935em;"><span></span></span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.3318699999999999em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.0818699999999999em;"><span style="top:-3.10517em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9190928571428572em;"><span style="top:-2.214em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.42488571428571426em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9667142857142857em;"><span style="top:-2.966714285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5357142857142856em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mopen">{</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mclose">}</span><span class="mord"><span class="mord"><span class="mord mathbf">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi mathvariant="normal">∇</mi><msub><mi mathvariant="bold-italic">θ</mi><mi>q</mi></msub><msub><mi>L</mi><mi mathvariant="normal">Θ</mi></msub></msubsup><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><msubsup><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><mo stretchy="false">[</mo><mi>I</mi><mo stretchy="false">{</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo>=</mo><mi>j</mi><mo stretchy="false">}</mo><mfrac><mrow><msubsup><mo>∑</mo><mrow><mi>l</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>l</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup></mrow><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>j</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup></mfrac><mfrac><mrow><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>j</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup><mi>I</mi><mo stretchy="false">{</mo><mi>q</mi><mo>=</mo><mi>j</mi><mo stretchy="false">}</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><msubsup><mo>∑</mo><mrow><mi>l</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>l</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup><mo>−</mo><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>j</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>q</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup></mrow><mrow><mo stretchy="false">(</mo><msubsup><mo>∑</mo><mrow><mi>l</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>l</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow></mfrac><mo stretchy="false">]</mo><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><msubsup><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><mo stretchy="false">[</mo><mi>I</mi><mo stretchy="false">{</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo>=</mo><mi>j</mi><mo stretchy="false">}</mo><mfrac><mrow><mi>I</mi><mo stretchy="false">{</mo><mi>q</mi><mo>=</mo><mi>j</mi><mo stretchy="false">}</mo><msubsup><mo>∑</mo><mrow><mi>l</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>l</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup><mo>−</mo><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>q</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup></mrow><mrow><msubsup><mo>∑</mo><mrow><mi>l</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>l</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup></mrow></mfrac><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">]</mo><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><mo stretchy="false">[</mo><mfrac><mrow><mi>I</mi><mo stretchy="false">{</mo><mi>q</mi><mo>=</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">}</mo><msubsup><mo>∑</mo><mrow><mi>l</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>l</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup><mo>−</mo><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>q</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup></mrow><mrow><msubsup><mo>∑</mo><mrow><mi>l</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msup><mi>e</mi><mrow><msubsup><mi mathvariant="bold-italic">θ</mi><mi>l</mi><mi>T</mi></msubsup><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow></msup></mrow></mfrac><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">]</mo><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><mo stretchy="false">[</mo><mo stretchy="false">(</mo><mi>I</mi><mo stretchy="false">{</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo>=</mo><mi>q</mi><mo stretchy="false">}</mo><mo>−</mo><mi>P</mi><mo stretchy="false">(</mo><mi>y</mi><mo>=</mo><mi>q</mi><mi mathvariant="normal">∣</mi><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo separator="true">,</mo><mi mathvariant="normal">Θ</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">\nabla_{\boldsymbol{\theta}_q}^{L_\Theta}=-\frac{1}{m}\sum\limits_{i=1}^m\sum\limits_{j=1}^k[I\{y^{(i)}=j\}\frac{\sum\limits_{l=1}^ke^{\boldsymbol{\theta}_l^T\mathbf{x}^{(i)}}}{e^{\boldsymbol{\theta}_j^T\mathbf{x}^{(i)}}}\frac{e^{\boldsymbol{\theta}_j^T\mathbf{x}^{(i)}}I\{q=j\}\mathbf{x}^{(i)}\sum\limits_{l=1}^ke^{\boldsymbol{\theta}_l^T\mathbf{x}^{(i)}}-e^{\boldsymbol{\theta}_j^T\mathbf{x}^{(i)}}\mathbf{x}^{(i)}e^{\boldsymbol{\theta}_q^T\mathbf{x}^{(i)}}}{(\sum\limits_{l=1}^ke^{\boldsymbol{\theta}_l^T\mathbf{x}^{(i)}})^2}]=-\frac{1}{m}\sum\limits_{i=1}^m\sum\limits_{j=1}^k[I\{y^{(i)}=j\}\frac{I\{q=j\}\sum\limits_{l=1}^ke^{\boldsymbol{\theta}_l^T\mathbf{x}^{(i)}}-e^{\boldsymbol{\theta}_q^T\mathbf{x}^{(i)}}}{\sum\limits_{l=1}^ke^{\boldsymbol{\theta}_l^T\mathbf{x}^{(i)}}}\mathbf{x}^{(i)}]=-\frac{1}{m}\sum\limits_{i=1}^m[\frac{I\{q=y^{(i)}\}\sum\limits_{l=1}^ke^{\boldsymbol{\theta}_l^T\mathbf{x}^{(i)}}-e^{\boldsymbol{\theta}_q^T\mathbf{x}^{(i)}}}{\sum\limits_{l=1}^ke^{\boldsymbol{\theta}_l^T\mathbf{x}^{(i)}}}\mathbf{x}^{(i)}]=-\frac{1}{m}\sum\limits_{i=1}^m[(I\{y^{(i)}=q\}-P(y=q|\mathbf{x}^{(i)},\Theta))\mathbf{x}^{(i)}]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.4220639999999998em;vertical-align:-0.4986279999999999em;"></span><span class="mord"><span class="mord">∇</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9234359999999999em;"><span style="top:-2.398692em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285716em;"><span style="top:-2.357em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">q</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2818857142857143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.1451050000000005em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3567071428571427em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">Θ</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.14329285714285717em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4986279999999999em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.64989em;vertical-align:-1.113777em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5361130000000003em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.113777em;"><span></span></span></span></span></span><span class="mopen">[</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mopen">{</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.821694em;vertical-align:-1.660847em;"></span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mclose">}</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.160847em;"><span style="top:-2.3204435em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.4026857142857143em;"><span style="top:-3.402685714285714em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.79125em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.02813em;"><span style="top:-2.1726099999999997em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span><span style="top:-3.02813em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.70516em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.10775em;"><span style="top:-3.1077500000000002em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.3423235em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-4.160847em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop op-limits mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5890335714285715em;"><span style="top:-1.8379664285714286em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-2.7500050000000003em;"><span class="pstrut" style="height:2.75em;"></span><span><span class="mop op-symbol small-op mtight">∑</span></span></span><span style="top:-3.700005em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.0550335714285715em;"><span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.2794928571428572em;"><span style="top:-3.279492857142857em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.08733em;"><span style="top:-2.208em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span><span style="top:-3.09844em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.48643999999999993em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7918799999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.160847em;"><span style="top:-2.19em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mop op-limits mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5890335714285715em;"><span style="top:-1.8379664285714286em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-2.7500050000000003em;"><span class="pstrut" style="height:2.75em;"></span><span><span class="mop op-symbol small-op mtight">∑</span></span></span><span style="top:-3.700005em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.0550335714285715em;"><span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.288742857142857em;"><span style="top:-3.288742857142857em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.79125em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.02813em;"><span style="top:-2.1488000000000005em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span><span style="top:-3.0392400000000004em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5456399999999999em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.10775em;"><span style="top:-3.1077500000000002em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mclose mtight"><span class="mclose mtight">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7463142857142857em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.3423235em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-4.160847em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.3934357142857143em;"><span style="top:-3.393435714285714em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0873300000000001em;"><span style="top:-2.23181em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span><span style="top:-3.0873299999999997em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.64596em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mord mathnormal mtight" style="margin-right:0.07847em;">I</span><span class="mopen mtight">{</span><span class="mord mathnormal mtight" style="margin-right:0.03588em;">q</span><span class="mrel mtight">=</span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mclose mtight">}</span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9667142857142857em;"><span style="top:-2.966714285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5357142857142856em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mop op-limits mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5890335714285715em;"><span style="top:-1.8379664285714286em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-2.7500050000000003em;"><span class="pstrut" style="height:2.75em;"></span><span><span class="mop op-symbol small-op mtight">∑</span></span></span><span style="top:-3.700005em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.0550335714285715em;"><span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.2794928571428572em;"><span style="top:-3.279492857142857em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.08733em;"><span style="top:-2.208em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span><span style="top:-3.09844em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.48643999999999993em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.3934357142857143em;"><span style="top:-3.393435714285714em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0873300000000001em;"><span style="top:-2.23181em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span><span style="top:-3.0873299999999997em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.64596em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9667142857142857em;"><span style="top:-2.966714285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5357142857142856em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.3566357142857144em;"><span style="top:-3.356635714285714em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0873300000000001em;"><span style="top:-2.28333em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.03588em;">q</span></span><span style="top:-3.0873299999999997em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5944400000000001em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.660847em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.64989em;vertical-align:-1.113777em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5361130000000003em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.113777em;"><span></span></span></span></span></span><span class="mopen">[</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mopen">{</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.821694em;vertical-align:-1.660847em;"></span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mclose">}</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.160847em;"><span style="top:-2.19em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop op-limits mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5890335714285715em;"><span style="top:-1.8379664285714286em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-2.7500050000000003em;"><span class="pstrut" style="height:2.75em;"></span><span><span class="mop op-symbol small-op mtight">∑</span></span></span><span style="top:-3.700005em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.0550335714285715em;"><span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.288742857142857em;"><span style="top:-3.288742857142857em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.79125em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.02813em;"><span style="top:-2.1488000000000005em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span><span style="top:-3.0392400000000004em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5456399999999999em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.10775em;"><span style="top:-3.1077500000000002em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.3423235em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-4.160847em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.07847em;">I</span><span class="mopen mtight">{</span><span class="mord mathnormal mtight" style="margin-right:0.03588em;">q</span><span class="mrel mtight">=</span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mclose mtight">}</span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mop op-limits mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5890335714285715em;"><span style="top:-1.8379664285714286em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-2.7500050000000003em;"><span class="pstrut" style="height:2.75em;"></span><span><span class="mop op-symbol small-op mtight">∑</span></span></span><span style="top:-3.700005em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.0550335714285715em;"><span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.2794928571428572em;"><span style="top:-3.279492857142857em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.08733em;"><span style="top:-2.208em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span><span style="top:-3.09844em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.48643999999999993em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.3566357142857144em;"><span style="top:-3.356635714285714em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0873300000000001em;"><span style="top:-2.28333em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.03588em;">q</span></span><span style="top:-3.0873299999999997em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5944400000000001em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.660847em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord"><span class="mord mathbf">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.821694em;vertical-align:-1.660847em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mopen">[</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.160847em;"><span style="top:-2.19em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop op-limits mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5890335714285715em;"><span style="top:-1.8379664285714286em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-2.7500050000000003em;"><span class="pstrut" style="height:2.75em;"></span><span><span class="mop op-symbol small-op mtight">∑</span></span></span><span style="top:-3.700005em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.0550335714285715em;"><span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.288742857142857em;"><span style="top:-3.288742857142857em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.79125em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.02813em;"><span style="top:-2.1488000000000005em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span><span style="top:-3.0392400000000004em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5456399999999999em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.10775em;"><span style="top:-3.1077500000000002em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.3423235em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-4.160847em;"><span class="pstrut" style="height:3.1123235em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.07847em;">I</span><span class="mopen mtight">{</span><span class="mord mathnormal mtight" style="margin-right:0.03588em;">q</span><span class="mrel mtight">=</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9667142857142857em;"><span style="top:-2.966714285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5357142857142856em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose mtight">}</span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mop op-limits mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5890335714285715em;"><span style="top:-1.8379664285714286em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-2.7500050000000003em;"><span class="pstrut" style="height:2.75em;"></span><span><span class="mop op-symbol small-op mtight">∑</span></span></span><span style="top:-3.700005em;margin-left:0em;"><span class="pstrut" style="height:2.75em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.0550335714285715em;"><span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.2794928571428572em;"><span style="top:-3.279492857142857em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.08733em;"><span style="top:-2.208em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span><span style="top:-3.09844em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.48643999999999993em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.3566357142857144em;"><span style="top:-3.356635714285714em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord boldsymbol mtight" style="margin-right:0.03194em;">θ</span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0873300000000001em;"><span style="top:-2.28333em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.03588em;">q</span></span><span style="top:-3.0873299999999997em;margin-right:0.1em;"><span class="pstrut" style="height:2.6833299999999998em;"></span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5944400000000001em;"><span></span></span></span></span></span></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.660847em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord"><span class="mord mathbf">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.329066em;vertical-align:-0.9776689999999999em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mopen">[</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mopen">{</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mclose">}</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mord">∣</span><span class="mord"><span class="mord"><span class="mord mathbf">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">Θ</span><span class="mclose">)</span><span class="mclose">)</span><span class="mord"><span class="mord"><span class="mord mathbf">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">]</span></span></span></span></p></div></div><p>上述给出的Softmax分类模型的损失其实就是所谓的交叉熵损失，下面给出简洁且常见的表示形式，对于单样本，其<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>分类预测值为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi mathvariant="bold">y</mi><mo>^</mo></mover></mrow><annotation encoding="application/x-tex">\hat{\mathbf{y}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.90232em;vertical-align:-0.19444em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.70788em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span></span></span><span style="top:-3.01344em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span></span></span></span>，真实值为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">y</mi></mrow><annotation encoding="application/x-tex">\mathbf{y}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.63888em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span></span></span></span>（所属标量类别<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span></span>经one-hot编码所得向量），于是有交叉熵损失：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>l</mi><mi mathvariant="normal">Θ</mi></msub><mo>=</mo><mo>−</mo><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msub><mi mathvariant="bold">y</mi><mi>i</mi></msub><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><msub><mover accent="true"><mi mathvariant="bold">y</mi><mo>^</mo></mover><mi>i</mi></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">l_\Theta=-\sum\limits_{i=1}^k\mathbf{y}_i\ln(\hat{\mathbf{y}}_i)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.01968em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">Θ</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.513782em;vertical-align:-0.9776689999999999em;"></span><span class="mord">−</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5361130000000003em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord"><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.70788em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span></span></span><span style="top:-3.01344em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>，对于<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span>个批量数据的总体交叉熵损失，求和取平均得到<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>L</mi><mi mathvariant="normal">Θ</mi></msub><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><msubsup><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msubsup><mi mathvariant="bold">y</mi><mi>j</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msubsup><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><msubsup><mover accent="true"><mi mathvariant="bold">y</mi><mo>^</mo></mover><mi>j</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msubsup><mo stretchy="false">)</mo><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><mo stretchy="false">(</mo><msup><mi mathvariant="bold">y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><msup><mo stretchy="false">)</mo><mi>T</mi></msup><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><msup><mover accent="true"><mi mathvariant="bold">y</mi><mo>^</mo></mover><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><mi>t</mi><mi>r</mi><mo stretchy="false">(</mo><mo stretchy="false">[</mo><msup><mi mathvariant="bold">y</mi><mrow><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></msup><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msup><mi mathvariant="bold">y</mi><mrow><mo stretchy="false">(</mo><mi>m</mi><mo stretchy="false">)</mo></mrow></msup><msup><mo stretchy="false">]</mo><mi>T</mi></msup><mo stretchy="false">[</mo><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><msup><mover accent="true"><mi mathvariant="bold">y</mi><mo>^</mo></mover><mrow><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><msup><mover accent="true"><mi mathvariant="bold">y</mi><mo>^</mo></mover><mrow><mo stretchy="false">(</mo><mi>m</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo><mo stretchy="false">]</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">L_\Theta=-\frac{1}{m}\sum\limits_{i=1}^m\sum\limits_{j=1}^k\mathbf{y}_j^{(i)}\ln(\hat{\mathbf{y}}_j^{(i)})=-\frac{1}{m}\sum\limits_{i=1}^m(\mathbf{y}^{(i)})^T\ln(\hat{\mathbf{y}}^{(i)})=-\frac{1}{m}tr([\mathbf{y}^{(1)},...,\mathbf{y}^{(m)}]^T[\ln(\hat{\mathbf{y}}^{(1)}),...,\ln(\hat{\mathbf{y}}^{(m)})])</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">Θ</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.64989em;vertical-align:-1.113777em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5361130000000003em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.113777em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0448em;"><span style="top:-2.4231360000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.2198em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4129719999999999em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord"><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.70788em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span></span></span><span style="top:-3.01344em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0448em;"><span style="top:-2.4231360000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.2198em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4129719999999999em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.329066em;vertical-align:-0.9776689999999999em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord"><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.70788em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span></span></span><span style="top:-3.01344em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.2329999999999999em;vertical-align:-0.345em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mopen">(</span><span class="mopen">[</span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mtight">1</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">m</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">]</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mopen">[</span><span class="mop">ln</span><span class="mopen">(</span><span class="mord"><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.70788em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span></span></span><span style="top:-3.01344em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mtight">1</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord"><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.70788em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span></span></span><span style="top:-3.01344em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">m</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mclose">]</span><span class="mclose">)</span></span></span></span>，通过最小化该损失函数，可以使样本的预测概率分布<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mover accent="true"><mi mathvariant="bold">y</mi><mo>^</mo></mover><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">\hat{\mathbf{y}}^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0824399999999998em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.70788em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span></span></span><span style="top:-3.01344em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span>尽可能接近真实的标签概率分布<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant="bold">y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{y}^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0824399999999998em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span>，其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi><mo>∈</mo><mo stretchy="false">{</mo><mn>1</mn><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><mi>m</mi><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">i\in \{1,...,m\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69862em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">i</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">m</span><span class="mclose">}</span></span></span></span>（某些地方还会看到另一种写法，若记<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi mathvariant="bold">x</mi><mo stretchy="false">)</mo><mo>=</mo><msup><mi mathvariant="normal">Θ</mi><mi>T</mi></msup><mi mathvariant="bold">x</mi></mrow><annotation encoding="application/x-tex">f(\mathbf{x})=\Theta^T\mathbf{x}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathbf">x</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">Θ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathbf">x</span></span></span></span></span>，称为“logit”，代入损失函数中可得：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>L</mi><mi mathvariant="normal">Θ</mi></msub><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><msubsup><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msubsup><mi mathvariant="bold">y</mi><mi>j</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msubsup><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><mfrac><msup><mi>e</mi><mrow><mi>f</mi><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><msub><mo stretchy="false">)</mo><mi>j</mi></msub></mrow></msup><mrow><msubsup><mo>∑</mo><mrow><mi>l</mi><mo>=</mo><mn>1</mn></mrow><mi>k</mi></msubsup><msup><mi>e</mi><mrow><mi>f</mi><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><msub><mo stretchy="false">)</mo><mi>l</mi></msub></mrow></msup></mrow></mfrac><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">L_\Theta=-\frac{1}{m}\sum\limits_{i=1}^m\sum\limits_{j=1}^k\mathbf{y}_j^{(i)}\ln(\frac{e^{f(\mathbf{x}^{(i)})_j}}{\sum_{l=1}^ke^{f(\mathbf{x}^{(i)})_l}})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">Θ</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.64989em;vertical-align:-1.113777em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5361130000000003em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.113777em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0448em;"><span style="top:-2.4231360000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.2198em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4129719999999999em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.301005em;"><span style="top:-2.3858800000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop mtight"><span class="mop op-symbol small-op mtight" style="position:relative;top:-0.0000050000000000050004em;">∑</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8931714285714285em;"><span style="top:-2.1785614285714283em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-2.8971428571428572em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.32143857142857146em;"><span></span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.148742857142857em;"><span style="top:-3.148742857142857em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.79125em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.10764em;">f</span><span class="mopen mtight">(</span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.10775em;"><span style="top:-3.1077500000000002em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span><span class="mclose mtight"><span class="mclose mtight">)</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.2957214285714287em;"><span style="top:-3.2957214285714285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.10764em;">f</span><span class="mopen mtight">(</span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span><span class="mclose mtight"><span class="mclose mtight">)</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.65952em;"></span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5091600000000001em;"><span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.839127em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose">)</span></span></span></span>，由于<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant="bold">y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{y}^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0824399999999998em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span>是标量类别<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">y^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0824399999999998em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span>的one-hot编码，因此<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant="bold">y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{y}^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0824399999999998em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">y</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span>只有在第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">y^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0824399999999998em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span>个下标位置处值为1，其余皆为0，因此损失函数继续等于<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>1</mn><mi>m</mi></mfrac><msubsup><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></msubsup><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><mn>1</mn><mo>+</mo><mfrac><mrow><msubsup><mo>∑</mo><mrow><mi>l</mi><mo>=</mo><mn>1</mn><mo separator="true">,</mo><mi>l</mi><mo mathvariant="normal">≠</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><mi>k</mi></msubsup><msup><mi>e</mi><mrow><mi>f</mi><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><msub><mo stretchy="false">)</mo><mi>l</mi></msub></mrow></msup></mrow><msup><mi>e</mi><mrow><mi>f</mi><mo stretchy="false">(</mo><msup><mi mathvariant="bold">x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><msub><mo stretchy="false">)</mo><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></msub></mrow></msup></mfrac><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\frac{1}{m}\sum\limits_{i=1}^m\ln(1+\frac{\sum_{l=1,l\ne y^{(i)}}^ke^{f(\mathbf{x}^{(i)})_l}}{e^{f(\mathbf{x}^{(i)})_{y^{(i)}}}})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.329066em;vertical-align:-0.9776689999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3513970000000004em;"><span style="top:-2.122331em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.0000050000000003em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop op-symbol small-op">∑</span></span></span><span style="top:-3.950005em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9776689999999999em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.5932899999999997em;vertical-align:-0.9179949999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.6752949999999998em;"><span style="top:-2.19em;"><span class="pstrut" style="height:3.107995em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.5828499999999999em;"><span style="top:-3.58285em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.79125em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.10764em;">f</span><span class="mopen mtight">(</span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.10775em;"><span style="top:-3.1077500000000002em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span><span class="mclose mtight"><span class="mclose mtight">)</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:3.1077500000000002em;"></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.10775em;"><span style="top:-3.1077500000000002em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.95739em;"><span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.337995em;"><span class="pstrut" style="height:3.107995em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.90459em;"><span class="pstrut" style="height:3.107995em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop mtight"><span class="mop op-symbol small-op mtight" style="position:relative;top:-0.0000050000000000050004em;">∑</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9270285714285713em;"><span style="top:-2.235em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.79125em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mrel mtight">=</span><span class="mord mtight">1</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mrel mtight"><span class="mrel mtight"><span class="mord vbox mtight"><span class="thinbox mtight"><span class="rlap mtight"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="inner"><span class="mrel mtight"></span></span><span class="fix"></span></span></span></span></span><span class="mrel mtight">=</span></span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.10775em;"><span style="top:-3.1077500000000002em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.22225em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.79125em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.6951357142857143em;"><span></span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mtight"><span class="mord mathnormal mtight">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.2552857142857143em;"><span style="top:-3.2552857142857143em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.8242857142857143em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.10764em;">f</span><span class="mopen mtight">(</span><span class="mord mtight"><span class="mord mtight"><span class="mord mathbf mtight">x</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.154em;"><span style="top:-3.154em;margin-right:0.1em;"><span class="pstrut" style="height:2.75em;"></span><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span><span class="mclose mtight"><span class="mclose mtight">)</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3448em;margin-left:0em;margin-right:0.1em;"><span class="pstrut" style="height:2.69444em;"></span><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34963999999999995em;"><span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9179949999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose">)</span></span></span></span>）</p></div><p>编程实现：</p><p>和线性回归示例一样，需要定义网络模型、定义损失函数、定义优化算法三大步骤。（批量<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span>个训练数据<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">X</mi><mo>∈</mo><msup><mi>R</mi><mrow><mi>d</mi><mo>×</mo><mi>m</mi></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{X}\in R^{d\times m}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72521em;vertical-align:-0.0391em;"></span><span class="mord"><span class="mord mathbf">X</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8491079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">d</span><span class="mbin mtight">×</span><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span></span></span></span></span>，且为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>分类）前向传播：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mover accent="true"><mi mathvariant="bold">Y</mi><mo>^</mo></mover><mrow><mi>k</mi><mo>×</mo><mi>m</mi></mrow></msub><mo>=</mo><mtext mathvariant="bold">softmax</mtext><mo stretchy="false">(</mo><msubsup><mi mathvariant="bold">W</mi><mrow><mi>d</mi><mo>×</mo><mi>k</mi></mrow><mi>T</mi></msubsup><msub><mi mathvariant="bold">X</mi><mrow><mi>d</mi><mo>×</mo><mi>m</mi></mrow></msub><mo>+</mo><msub><mi mathvariant="bold">B</mi><mrow><mi>k</mi><mo>×</mo><mn>1</mn></mrow></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\hat{\mathbf{Y}}_{k\times m}=\textbf{softmax}(\mathbf{W}_{d\times k}^T\mathbf{X}_{d\times m}+\mathbf{B}_{k\times 1})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.157881em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9495499999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.02875em;">Y</span></span></span></span><span style="top:-3.25511em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.25em;"><span class="mord">^</span></span></span></span></span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">×</span><span class="mord mathnormal mtight">m</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.1827699999999999em;vertical-align:-0.34143899999999994em;"></span><span class="mord text"><span class="mord textbf">softmax</span></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">W</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-2.4168920000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">d</span><span class="mbin mtight">×</span><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34143899999999994em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord"><span class="mord mathbf">X</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">d</span><span class="mbin mtight">×</span><span class="mord mathnormal mtight">m</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">B</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>（上面给出了<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="bold">softmax</mtext></mrow><annotation encoding="application/x-tex">\textbf{softmax}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord text"><span class="mord textbf">softmax</span></span></span></span></span>函数的定义，处理的向量，此处虽然接收的一个矩阵，但是是逐列分别计算的），损失函数：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>L</mi><mrow><mi>W</mi><mo separator="true">,</mo><mi>B</mi></mrow></msub><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><mi>m</mi></mfrac><mi>t</mi><mi>r</mi><mo stretchy="false">(</mo><msubsup><mi mathvariant="bold">Y</mi><mrow><mi>k</mi><mo>×</mo><mi>m</mi></mrow><mi>T</mi></msubsup><mi>ln</mi><mo>⁡</mo><mo stretchy="false">(</mo><msub><mover accent="true"><mi mathvariant="bold">Y</mi><mo>^</mo></mover><mrow><mi>k</mi><mo>×</mo><mi>m</mi></mrow></msub><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">L_{W,B}=-\frac{1}{m}tr(\mathbf{Y}_{k\times m}^T\ln(\hat{\mathbf{Y}}_{k\times m}))</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.969438em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.328331em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">W</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight" style="margin-right:0.05017em;">B</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.2945499999999999em;vertical-align:-0.345em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.02875em;">Y</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-2.4168920000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">×</span><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.34143899999999994em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">ln</span><span class="mopen">(</span><span class="mord"><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9495499999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.02875em;">Y</span></span></span></span><span style="top:-3.25511em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.25em;"><span class="mord">^</span></span></span></span></span></span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">×</span><span class="mord mathnormal mtight">m</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mclose">)</span></span></span></span>，优化算法：小批量随机梯度下降</p><div class="tabs" id="softmaxflbcsx"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#softmaxflbcsx-1">准备数据</button></li><li class="tab"><button type="button" data-href="#softmaxflbcsx-2">定义模型、损失和优化函数</button></li><li class="tab"><button type="button" data-href="#softmaxflbcsx-3">训练</button></li><li class="tab"><button type="button" data-href="#softmaxflbcsx-4">附（简洁实现）</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="softmaxflbcsx-1"><p>首先通过<code>torchvision.datasets</code>模块获取Fashion-MNIST图像分类数据集，并利用<code>transforms.ToTensor()</code>函数将所有图像数据（numpy对象，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mn>0</mn><mo>−</mo><mn>255</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[0-255]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">0</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">2</span><span class="mord">5</span><span class="mord">5</span><span class="mclose">]</span></span></span></span>的<code>Uint8</code>类型）转换成Tensor张量对象，且数值为介于<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mn>0.0</mn><mo>−</mo><mn>1.0</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[0.0-1.0]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">0</span><span class="mord">.</span><span class="mord">0</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mord">.</span><span class="mord">0</span><span class="mclose">]</span></span></span></span>的<code>torch.float32</code>类型：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> torchvision</span><br><span class="line"><span class="keyword">import</span> torchvision.transforms <span class="keyword">as</span> transforms</span><br><span class="line"></span><br><span class="line">mnist_train = torchvision.datasets.FashionMNIST(root=<span class="string">&#x27;./data/FashionMNIST&#x27;</span>, train=<span class="literal">True</span>, download=<span class="literal">True</span>, transform=transforms.ToTensor())</span><br><span class="line">mnist_test = torchvision.datasets.FashionMNIST(root=<span class="string">&#x27;./data/FashionMNIST&#x27;</span>, train=<span class="literal">False</span>, download=<span class="literal">True</span>, transform=transforms.ToTensor())</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">len</span>(mnist_train),<span class="built_in">len</span>(mnist_test))</span><br><span class="line">feature,label=mnist_train[<span class="number">0</span>] <span class="comment">#通过下标索引第一个训练图像</span></span><br><span class="line"><span class="built_in">print</span>(feature.shape,label) <span class="comment">#需要注意的是，类别是标量数据，后面训练的时候我再转换成one-hot编码形式</span></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">60000 10000</span></span><br><span class="line"><span class="string">torch.Size([1, 28, 28]) 9</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>训练集和测试集中的每个类别的图像数分别为6,000和1,000，统共10个类别，为t-shirt（T恤）、trouser（裤子）、pullover（套衫）、dress（连衣裙）、coat（外套）、sandal（凉鞋）、shirt（衬衫）、sneaker（运动鞋）、bag（包）和ankle boot（短靴），因此总计有70,000张图像。图像数据的形状为<code>(c,h,w)</code>，三个符号分别代表通道数、高度、宽度，根据上述输出可知，此处图像是单通道的</p><p>可视化：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">get_fashion_mnist_labels</span>(<span class="params">labels</span>):</span><br><span class="line">    text_labels = [<span class="string">&#x27;t-shirt&#x27;</span>, <span class="string">&#x27;trouser&#x27;</span>, <span class="string">&#x27;pullover&#x27;</span>, <span class="string">&#x27;dress&#x27;</span>, <span class="string">&#x27;coat&#x27;</span>,</span><br><span class="line">                   <span class="string">&#x27;sandal&#x27;</span>, <span class="string">&#x27;shirt&#x27;</span>, <span class="string">&#x27;sneaker&#x27;</span>, <span class="string">&#x27;bag&#x27;</span>, <span class="string">&#x27;ankle boot&#x27;</span>]</span><br><span class="line">    <span class="keyword">return</span> [text_labels[<span class="built_in">int</span>(i)] <span class="keyword">for</span> i <span class="keyword">in</span> labels]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 定义一个可以在一行里画出多张图像和对应标签的函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">show_fashion_mnist</span>(<span class="params">images,labels</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(images)):</span><br><span class="line">        ax=plt.subplot(<span class="number">1</span>,<span class="built_in">len</span>(images),i+<span class="number">1</span>)</span><br><span class="line">        plt.imshow(np.squeeze(images[i].numpy()).reshape(<span class="number">28</span>,<span class="number">28</span>),cmap=<span class="string">&#x27;gray&#x27;</span>)</span><br><span class="line">        plt.xlabel(get_fashion_mnist_labels([labels[i]])[<span class="number">0</span>])</span><br><span class="line">        plt.xticks([])</span><br><span class="line">        plt.yticks([])</span><br><span class="line">    plt.show()</span><br><span class="line">    </span><br><span class="line">X, y = [], []</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">5</span>):</span><br><span class="line">    X.append(mnist_train[i][<span class="number">0</span>])</span><br><span class="line">    y.append(mnist_train[i][<span class="number">1</span>])</span><br><span class="line">show_fashion_mnist(X,y)</span><br></pre></td></tr></table></figure><div class="img-wrap"><div class="img-bg"><img class="img" src="https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210609202322.png" alt="图5.&nbsp;Fashion-MNIST数据集图例" onerror="this.onerror=null,this.src='https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210328224519.jpg'" /></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="softmaxflbcsx-2"><p>首先定义前向传播时要用到的softmax函数：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">softmax</span>(<span class="params">WX</span>):</span><br><span class="line">    WX=WX.exp()</span><br><span class="line">    <span class="keyword">return</span> WX/WX.<span class="built_in">sum</span>()</span><br></pre></td></tr></table></figure><p>再定义模型、损失和优化函数：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### 定义网络模型</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">softmax_classify</span>(<span class="params">X,W,B</span>):</span><br><span class="line">    <span class="keyword">return</span> softmax(pt.t(W).mm(X)+B)</span><br><span class="line"></span><br><span class="line"><span class="comment">### 定义损失函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">cross_loss</span>(<span class="params">Y_hat,Y</span>):</span><br><span class="line">    <span class="keyword">return</span> -pt.trace(pt.t(Y).mm(pt.log(Y_hat))) <span class="comment">#注意这里并未除以m（批量数），我们会在更新参数的时候再做，同线性回归示例</span></span><br><span class="line">    </span><br><span class="line"><span class="comment">### 定义优化算法</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sgd</span>(<span class="params">params,learn_rate,batch_sise</span>): <span class="comment">#同线性回归示例</span></span><br><span class="line">    <span class="keyword">for</span> param <span class="keyword">in</span> params:</span><br><span class="line">        param.data-=(learn_rate*param.grad/batch_size)</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="softmaxflbcsx-3"><p>在训练前还要准备一些东西：批量数据生成器、one-hot编码以及参数初始化：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line"><span class="comment">#批量读取数据。mnist_train对象是torch.utils.data.Dataset的子类，所以我们可以将其传入torch.utils.data.DataLoader来创建一个读取小批量数据样本的DataLoader实例。PyTorch的DataLoader一个很好的功能是允许使用多进程来加速数据读取，这里我们通过参数num_workers来设置4个进程读取数据</span></span><br><span class="line">batch_size = <span class="number">256</span> <span class="comment">#自定义批量尺寸</span></span><br><span class="line">num_workers = <span class="number">4</span> <span class="comment">#0则表示不用额外的进程来加速读取数据</span></span><br><span class="line">train_iter = pt.utils.data.DataLoader(mnist_train, batch_size=batch_size, shuffle=<span class="literal">True</span>, num_workers=num_workers) <span class="comment">#定义批量数据迭代器</span></span><br><span class="line">test_iter = pt.utils.data.DataLoader(mnist_test, batch_size=batch_size, shuffle=<span class="literal">False</span>, num_workers=num_workers)</span><br><span class="line"><span class="comment">#此处查看读取一遍训练数据需要的时间（作为对比，num_workers=0需4.64s，num_workers=4需要1.99s）</span></span><br><span class="line">start = time.time()</span><br><span class="line"><span class="keyword">for</span> X, y <span class="keyword">in</span> train_iter:</span><br><span class="line">    <span class="keyword">continue</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;%.2f sec&#x27;</span> % (time.time() - start))</span><br><span class="line"></span><br><span class="line"><span class="comment"># labels转换为one-hot编码</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">to_onehot</span>(<span class="params">labels,N</span>): <span class="comment">#N为类别数（labels中标签标量取值范围应为[0,N-1]）</span></span><br><span class="line">    <span class="keyword">return</span> (pt.arange(N).view(N,<span class="number">1</span>)==labels).to(pt.float32) <span class="comment">#形状为(N,len(labels))</span></span><br><span class="line"></span><br><span class="line"><span class="comment">### 初始化模型参数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">init_params</span>(<span class="params">d,k</span>): <span class="comment">#d是图像样本展开后的维度，也就是输入层的节点数量，k是分类数，即输出层节点数量</span></span><br><span class="line">    W=pt.tensor(np.random.normal(<span class="number">0</span>,<span class="number">0.01</span>,(d,k)),dtype=pt.float32)</span><br><span class="line">    B=pt.zeros(k,<span class="number">1</span>,dtype=pt.float32)</span><br><span class="line">    W.requires_grad_(requires_grad=<span class="literal">True</span>)</span><br><span class="line">    B.requires_grad_(requires_grad=<span class="literal">True</span>)</span><br><span class="line">    <span class="keyword">return</span> W,B</span><br></pre></td></tr></table></figure><p>为了评判模型在测试集上的性能，在每一轮epoch结束后都会计算预测准确率，对于批量测试数据，网络的输出<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi mathvariant="bold">Y</mi><mo>^</mo></mover></mrow><annotation encoding="application/x-tex">\hat{\mathbf{Y}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9495499999999999em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9495499999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.02875em;">Y</span></span></span></span><span style="top:-3.25511em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.25em;"><span class="mord">^</span></span></span></span></span></span></span></span></span></span>是一个矩阵，每一列代表其中一个样本的预测概率分布，其中最大值所在位置就是预测的类别，同时已知的测试集真实值标签<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="bold">Y</mi></mrow><annotation encoding="application/x-tex">\mathbf{Y}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68611em;vertical-align:0em;"></span><span class="mord"><span class="mord mathbf" style="margin-right:0.02875em;">Y</span></span></span></span></span>，和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi mathvariant="bold">Y</mi><mo>^</mo></mover></mrow><annotation encoding="application/x-tex">\hat{\mathbf{Y}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9495499999999999em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9495499999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.02875em;">Y</span></span></span></span><span style="top:-3.25511em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.25em;"><span class="mord">^</span></span></span></span></span></span></span></span></span></span>是一个同形矩阵，含义一样，每一列都是其中一个样本的one-hot编码，于是精度计算代码就是<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mover accent="true"><mi mathvariant="bold">Y</mi><mo>^</mo></mover><mi mathvariant="normal">.</mi><mi>a</mi><mi>r</mi><mi>g</mi><mi>m</mi><mi>a</mi><mi>x</mi><mo stretchy="false">(</mo><mi>d</mi><mi>i</mi><mi>m</mi><mo>=</mo><mn>0</mn><mo stretchy="false">)</mo><mo>=</mo><mo>=</mo><mi mathvariant="bold">Y</mi><mi mathvariant="normal">.</mi><mi>a</mi><mi>r</mi><mi>g</mi><mi>m</mi><mi>a</mi><mi>x</mi><mo stretchy="false">(</mo><mi>d</mi><mi>i</mi><mi>m</mi><mo>=</mo><mn>0</mn><mo stretchy="false">)</mo><mo stretchy="false">)</mo><mi mathvariant="normal">.</mi><mi>m</mi><mi>e</mi><mi>a</mi><mi>n</mi><mo stretchy="false">(</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(\hat{\mathbf{Y}}.argmax(dim=0)==\mathbf{Y}.argmax(dim=0)).mean()</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.19955em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9495499999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.02875em;">Y</span></span></span></span><span style="top:-3.25511em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.25em;"><span class="mord">^</span></span></span></span></span></span></span><span class="mord">.</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">m</span><span class="mord mathnormal">a</span><span class="mord mathnormal">x</span><span class="mopen">(</span><span class="mord mathnormal">d</span><span class="mord mathnormal">i</span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">0</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span></span><span class="base"><span class="strut" style="height:0.36687em;vertical-align:0em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathbf" style="margin-right:0.02875em;">Y</span></span><span class="mord">.</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">m</span><span class="mord mathnormal">a</span><span class="mord mathnormal">x</span><span class="mopen">(</span><span class="mord mathnormal">d</span><span class="mord mathnormal">i</span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">0</span><span class="mclose">)</span><span class="mclose">)</span><span class="mord">.</span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mopen">(</span><span class="mclose">)</span></span></span></span>：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#计算单个批次数据的精确率</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">acc</span>(<span class="params">Y_hat,Y</span>):</span><br><span class="line">    <span class="keyword">return</span> (Y_hat.argmax(dim=<span class="number">0</span>)==Y.argmax(dim=<span class="number">0</span>)).<span class="built_in">float</span>().mean().item()</span><br><span class="line"></span><br><span class="line"><span class="comment">#计算多个批次数据的精确率</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">calc_accuracy</span>(<span class="params">data_iter, net_with_wb</span>):</span><br><span class="line">    acc_sum, n = <span class="number">0.0</span>, <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> X, y <span class="keyword">in</span> data_iter:</span><br><span class="line">        acc_sum += (net_with_wb(pt.t(X.view(-<span class="number">1</span>,<span class="number">784</span>))).argmax(dim=<span class="number">0</span>)==y).<span class="built_in">float</span>().<span class="built_in">sum</span>().item()</span><br><span class="line">        n += <span class="built_in">len</span>(y)</span><br><span class="line">    <span class="keyword">return</span> acc_sum / n</span><br></pre></td></tr></table></figure><p>开始训练：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> partial</span><br><span class="line"></span><br><span class="line"><span class="comment">### 训练过程</span></span><br><span class="line">start_time=time.time()</span><br><span class="line">epoches=<span class="number">10</span> <span class="comment">#自定义迭代周期</span></span><br><span class="line">learn_rate=<span class="number">0.1</span> <span class="comment">#自定义学习率</span></span><br><span class="line">W,B=init_params(<span class="number">784</span>,<span class="number">10</span>) <span class="comment">#784是图像一维化展开后的长度</span></span><br><span class="line"><span class="keyword">for</span> epoch <span class="keyword">in</span> <span class="built_in">range</span>(epoches):</span><br><span class="line">    <span class="keyword">for</span> mini_samples,mini_labels <span class="keyword">in</span> train_iter:</span><br><span class="line">        mini_X=pt.t(mini_samples.view(-<span class="number">1</span>,<span class="number">784</span>)) <span class="comment">#将小批量训练数据转换到(d,batch_size)二维形状</span></span><br><span class="line">        mini_Y=to_onehot(mini_labels,<span class="number">10</span>) <span class="comment">#将标签向量转换成one-hot编码</span></span><br><span class="line">        mini_Y_hat=softmax_classify(mini_X,W,B) <span class="comment">#前向传播</span></span><br><span class="line">        loss=cross_loss(mini_Y_hat,mini_Y) <span class="comment">#得到损失</span></span><br><span class="line">        loss.backward() <span class="comment">#反向传播求偏导</span></span><br><span class="line">        sgd((W,B),learn_rate,batch_size) <span class="comment">#根据偏导以及梯度下降算法更新网络参数</span></span><br><span class="line">        _=W.grad.data.zero_()</span><br><span class="line">        _=B.grad.data.zero_()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;epoch=%d,train_loss=%f,test_accuracy=%f&#x27;</span>%(epoch+<span class="number">1</span>,loss.data.item(),calc_accuracy(test_iter,partial(softmax_classify,W=W,B=B))))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;Time: %f&#x27;</span>%(time.time()-start_time))</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">epoch=1,train_loss=513.109375,test_accuracy=0.795100</span></span><br><span class="line"><span class="string">epoch=2,train_loss=505.963837,test_accuracy=0.811600</span></span><br><span class="line"><span class="string">epoch=3,train_loss=506.121246,test_accuracy=0.819600</span></span><br><span class="line"><span class="string">epoch=4,train_loss=499.465485,test_accuracy=0.821300</span></span><br><span class="line"><span class="string">epoch=5,train_loss=491.453918,test_accuracy=0.823300</span></span><br><span class="line"><span class="string">epoch=6,train_loss=500.663055,test_accuracy=0.826000</span></span><br><span class="line"><span class="string">epoch=7,train_loss=496.945709,test_accuracy=0.820800</span></span><br><span class="line"><span class="string">epoch=8,train_loss=493.426422,test_accuracy=0.830900</span></span><br><span class="line"><span class="string">epoch=9,train_loss=493.445496,test_accuracy=0.829300</span></span><br><span class="line"><span class="string">epoch=10,train_loss=494.146027,test_accuracy=0.825700</span></span><br><span class="line"><span class="string">Time: 33.636117</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>编写预测函数：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### 预测函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">predict</span>(<span class="params">images,true_labels</span>):</span><br><span class="line">    t=pt.cat(images,<span class="number">0</span>)</span><br><span class="line">    t=t.view(t.shape[<span class="number">0</span>],-<span class="number">1</span>)</span><br><span class="line">    y=softmax_classify(pt.t(t),W,B).argmax(dim=<span class="number">0</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;预测结果:&#x27;</span>)</span><br><span class="line">    show_fashion_mnist(images,y)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;真实标签:&#x27;</span>,get_fashion_mnist_labels(true_labels))</span><br><span class="line"></span><br><span class="line">X, y = [], []</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> pt.randint(<span class="number">0</span>,<span class="number">10000</span>,(<span class="number">8</span>,)):</span><br><span class="line">    X.append(mnist_test[i][<span class="number">0</span>])</span><br><span class="line">    y.append(mnist_test[i][<span class="number">1</span>])</span><br><span class="line">predict(X,y)</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="softmaxflbcsx-4"><p>比较简单，直接看代码：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> torch <span class="keyword">as</span> pt</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="comment">### 一些参数设置</span></span><br><span class="line">batch_size=<span class="number">128</span></span><br><span class="line">num_inputs=<span class="number">784</span></span><br><span class="line">num_outputs=<span class="number">10</span></span><br><span class="line"></span><br><span class="line"><span class="comment">### 获取fashion-mnist训练数据以及小批量生成器</span></span><br><span class="line">train_iter,test_iter=load_data_fashion_mnist(batch_size,root=<span class="string">&#x27;./data/FashionMNIST&#x27;</span>) <span class="comment">#注意迭代产生的训练样本的形状为(batch_size,1,h,w)，标签形状为(batch_size,)</span></span><br><span class="line"></span><br><span class="line"><span class="comment">### 定义网络模型，定义展开层和线性层而无需定义softmax层（因为pytorch的softmax交叉熵损失nn.CrossEntropyLoss完成了这一步）</span></span><br><span class="line"><span class="keyword">import</span> torch.nn <span class="keyword">as</span> nn</span><br><span class="line">net=nn.Sequential(FlattenLayer(),nn.Linear(num_inputs,num_outputs))</span><br><span class="line"></span><br><span class="line"><span class="comment">### 定义损失函数</span></span><br><span class="line"><span class="comment">#分开定义softmax运算和交叉熵损失函数可能会造成数值不稳定。因此，PyTorch提供了一个包括softmax运算和交叉熵损失计算的函数。它的数值稳定性更好</span></span><br><span class="line">loss=nn.CrossEntropyLoss()</span><br><span class="line"></span><br><span class="line"><span class="comment">### 定义优化算法</span></span><br><span class="line">optimizer=pt.optim.SGD(net.parameters(), lr=<span class="number">0.1</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">### 训练</span></span><br><span class="line"><span class="keyword">from</span> torch.nn <span class="keyword">import</span> init</span><br><span class="line">_=init.normal_(net[<span class="number">1</span>].weight, mean=<span class="number">0</span>, std=<span class="number">0.01</span>) <span class="comment">#初始化权重</span></span><br><span class="line">_=init.constant_(net[<span class="number">1</span>].bias, val=<span class="number">0</span>)</span><br><span class="line">num_epochs = <span class="number">5</span></span><br><span class="line">train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, <span class="literal">None</span>, <span class="literal">None</span>, optimizer)</span><br></pre></td></tr></table></figure><p>上述代码用到了几个别人写好的<a href="https://tangshusen.me/Dive-into-DL-PyTorch/#/chapter03_DL-basics/3.6_softmax-regression-scratch">功能函数</a>（后面还会用到，写在d2l.py中，作为模块调用）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> torch</span><br><span class="line"><span class="keyword">import</span> torchvision</span><br><span class="line"><span class="keyword">import</span> sys</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">load_data_fashion_mnist</span>(<span class="params">batch_size, resize=<span class="literal">None</span>, root=<span class="string">&#x27;~/Datasets/FashionMNIST&#x27;</span></span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;Download the fashion mnist dataset and then load into memory.&quot;&quot;&quot;</span></span><br><span class="line">    trans = []</span><br><span class="line">    <span class="keyword">if</span> resize:</span><br><span class="line">        trans.append(torchvision.transforms.Resize(size=resize))</span><br><span class="line">    trans.append(torchvision.transforms.ToTensor())</span><br><span class="line">    </span><br><span class="line">    transform = torchvision.transforms.Compose(trans)</span><br><span class="line">    mnist_train = torchvision.datasets.FashionMNIST(root=root, train=<span class="literal">True</span>, download=<span class="literal">True</span>, transform=transform)</span><br><span class="line">    mnist_test = torchvision.datasets.FashionMNIST(root=root, train=<span class="literal">False</span>, download=<span class="literal">True</span>, transform=transform)</span><br><span class="line">    <span class="keyword">if</span> sys.platform.startswith(<span class="string">&#x27;win&#x27;</span>):</span><br><span class="line">        num_workers = <span class="number">4</span>  <span class="comment"># 0表示不用额外的进程来加速读取数据</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        num_workers = <span class="number">6</span></span><br><span class="line">    train_iter = torch.utils.data.DataLoader(mnist_train, batch_size=batch_size, shuffle=<span class="literal">True</span>, num_workers=num_workers)</span><br><span class="line">    test_iter = torch.utils.data.DataLoader(mnist_test, batch_size=batch_size, shuffle=<span class="literal">False</span>, num_workers=num_workers)</span><br><span class="line"> </span><br><span class="line">    <span class="keyword">return</span> train_iter, test_iter</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">FlattenLayer</span>(torch.nn.Module):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">super</span>(FlattenLayer, self).__init__()</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">forward</span>(<span class="params">self, x</span>): <span class="comment"># x shape: (batch, *, *, ...)</span></span><br><span class="line">        <span class="keyword">return</span> x.view(x.shape[<span class="number">0</span>], -<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sgd</span>(<span class="params">params, lr, batch_size</span>):</span><br><span class="line">    <span class="comment"># 为了和原书保持一致，这里除以了batch_size，但是应该是不用除的，因为一般用PyTorch计算loss时就默认已经</span></span><br><span class="line">    <span class="comment"># 沿batch维求了平均了。</span></span><br><span class="line">    <span class="keyword">for</span> param <span class="keyword">in</span> params:</span><br><span class="line">        param.data -= lr * param.grad / batch_size <span class="comment"># 注意这里更改param时用的param.data</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">evaluate_accuracy_ch3</span>(<span class="params">data_iter, net</span>):</span><br><span class="line">    acc_sum, n = <span class="number">0.0</span>, <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> X, y <span class="keyword">in</span> data_iter:</span><br><span class="line">        acc_sum += (net(X).argmax(dim=<span class="number">1</span>) == y).<span class="built_in">float</span>().<span class="built_in">sum</span>().item()</span><br><span class="line">        n += y.shape[<span class="number">0</span>]</span><br><span class="line">    <span class="keyword">return</span> acc_sum / n</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">train_ch3</span>(<span class="params">net, train_iter, test_iter, loss, num_epochs, batch_size,</span></span><br><span class="line"><span class="params">              params=<span class="literal">None</span>, lr=<span class="literal">None</span>, optimizer=<span class="literal">None</span></span>):</span><br><span class="line">    <span class="keyword">for</span> epoch <span class="keyword">in</span> <span class="built_in">range</span>(num_epochs):</span><br><span class="line">        train_l_sum, train_acc_sum, n = <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0</span></span><br><span class="line">        <span class="keyword">for</span> X, y <span class="keyword">in</span> train_iter:</span><br><span class="line">            y_hat = net(X)</span><br><span class="line">            l = loss(y_hat, y).<span class="built_in">sum</span>()</span><br><span class="line">            </span><br><span class="line">            <span class="comment"># 梯度清零</span></span><br><span class="line">            <span class="keyword">if</span> optimizer <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">None</span>:</span><br><span class="line">                optimizer.zero_grad()</span><br><span class="line">            <span class="keyword">elif</span> params <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">None</span> <span class="keyword">and</span> params[<span class="number">0</span>].grad <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">None</span>:</span><br><span class="line">                <span class="keyword">for</span> param <span class="keyword">in</span> params:</span><br><span class="line">                    param.grad.data.zero_()</span><br><span class="line">            </span><br><span class="line">            l.backward()</span><br><span class="line">            <span class="keyword">if</span> optimizer <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line">                sgd(params, lr, batch_size)</span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                optimizer.step()  <span class="comment"># “softmax回归的简洁实现”一节将用到</span></span><br><span class="line">            </span><br><span class="line">            train_l_sum += l.item()</span><br><span class="line">            train_acc_sum += (y_hat.argmax(dim=<span class="number">1</span>) == y).<span class="built_in">sum</span>().item()</span><br><span class="line">            n += y.shape[<span class="number">0</span>]</span><br><span class="line">        test_acc = evaluate_accuracy_ch3(test_iter, net)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;epoch %d, loss %.4f, train acc %.3f, test acc %.3f&#x27;</span></span><br><span class="line">              % (epoch + <span class="number">1</span>, train_l_sum / n, train_acc_sum / n, test_acc))</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="MLP多层感知器">MLP多层感知器</h2><p>简要回顾：</p><div class="img-wrap"><div class="img-bg"><img class="img" src="https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210611092144.png" alt="图6.&nbsp;由单个隐层构成的多层感知器[3]" onerror="this.onerror=null,this.src='https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210328224519.jpg'" /></div></div><p>和线性回归、Softmax多分类相比，MLP增加了隐藏层的概念（实现了对输入空间的非线性映射+输出层线性判别分析）。给定批量<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span>个数据，对于任意第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi></mrow><annotation encoding="application/x-tex">l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span>层节点，有<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant="bold">Z</mi><mi>l</mi></msup><mo>=</mo><mo stretchy="false">(</mo><msup><mi mathvariant="bold">W</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msup><msup><mo stretchy="false">)</mo><mi>T</mi></msup><msup><mi mathvariant="bold">A</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msup><mo>+</mo><msup><mi mathvariant="bold">B</mi><mi>l</mi></msup></mrow><annotation encoding="application/x-tex">\mathbf{Z}^l=(\mathbf{W}^{l-1})^T\mathbf{A}^{l-1}+\mathbf{B}^l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.849108em;vertical-align:0em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">Z</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.0991079999999998em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">W</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mord"><span class="mord"><span class="mord mathbf">A</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.849108em;vertical-align:0em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">B</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant="bold">A</mi><mi>l</mi></msup><mo>=</mo><mi>σ</mi><mo stretchy="false">(</mo><msup><mi mathvariant="bold">Z</mi><mi>l</mi></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\mathbf{A}^{l}=\sigma(\mathbf{Z}^l)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.849108em;vertical-align:0em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">A</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.099108em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathbf">Z</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>，其中<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant="bold">A</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msup><mo>∈</mo><msup><mi>R</mi><mrow><msub><mi>S</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>×</mo><mi>n</mi></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{A}^{l-1}\in R^{S_{l-1}\times n}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8882079999999999em;vertical-align:-0.0391em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">A</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.34480000000000005em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.21074999999999994em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span>为上一层的输出、当前层的输入，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant="bold">B</mi><mi>l</mi></msup><mo>∈</mo><msup><mi>R</mi><mrow><msub><mi>S</mi><mi>l</mi></msub><mo>×</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{B}^l\in R^{S_l\times 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.888208em;vertical-align:-0.0391em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">B</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>为当前层偏置（广播为形状<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>S</mi><mi>l</mi></msub><mo>×</mo><mi>n</mi></mrow><annotation encoding="application/x-tex">S_l\times n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span>），<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant="bold">Z</mi><mi>l</mi></msup><mo>∈</mo><msup><mi>R</mi><mrow><msub><mi>S</mi><mi>l</mi></msub><mo>×</mo><mi>n</mi></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{Z}^l\in R^{S_l\times n}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.888208em;vertical-align:-0.0391em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">Z</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span>为当前层的输入加权和，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant="bold">W</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msup><mo>∈</mo><msup><mi>R</mi><mrow><msub><mi>S</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>×</mo><msub><mi>S</mi><mi>l</mi></msub></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{W}^{l-1}\in R^{S_{l-1}\times S_l}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8882079999999999em;vertical-align:-0.0391em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">W</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.34480000000000005em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.21074999999999994em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>的第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathnormal">i</span></span></span></span>列代表第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">l-1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>层所有节点和第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi></mrow><annotation encoding="application/x-tex">l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span>层第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathnormal">i</span></span></span></span>个节点的连线权重，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant="bold">A</mi><mi>l</mi></msup><mo>∈</mo><msup><mi>R</mi><mrow><msub><mi>S</mi><mi>l</mi></msub><mo>×</mo><mi>n</mi></mrow></msup></mrow><annotation encoding="application/x-tex">\mathbf{A}^l\in R^{S_l\times n}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.888208em;vertical-align:-0.0391em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">A</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span>为当前层的输出，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>S</mi><mi>l</mi></msub></mrow><annotation encoding="application/x-tex">S_l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>为第<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi></mrow><annotation encoding="application/x-tex">l</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span></span>层节点数，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>σ</mi><mo stretchy="false">(</mo><mo separator="true">⋅</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\sigma(·)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mpunct">⋅</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mclose">)</span></span></span></span>为激活函数，包括但不限于Sigmoid函数（<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>s</mi><mi>i</mi><mi>g</mi><mi>m</mi><mi>o</mi><mi>i</mi><mi>d</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mn>1</mn><mrow><mn>1</mn><mo>+</mo><mi>e</mi><mi>x</mi><mi>p</mi><mo stretchy="false">(</mo><mo>−</mo><mi>x</mi><mo stretchy="false">)</mo></mrow></mfrac></mrow><annotation encoding="application/x-tex">sigmoid(x)=\frac{1}{1+exp(-x)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">s</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">m</span><span class="mord mathnormal">o</span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.365108em;vertical-align:-0.52em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mbin mtight">+</span><span class="mord mathnormal mtight">e</span><span class="mord mathnormal mtight">x</span><span class="mord mathnormal mtight">p</span><span class="mopen mtight">(</span><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span><span class="mclose mtight">)</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.52em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>）、ReLU函数（<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>r</mi><mi>e</mi><mi>l</mi><mi>u</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mi>m</mi><mi>a</mi><mi>x</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">relu(x)=max(x,0)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">u</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">m</span><span class="mord mathnormal">a</span><span class="mord mathnormal">x</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">0</span><span class="mclose">)</span></span></span></span>）以及Tanh函数（<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>t</mi><mi>a</mi><mi>n</mi><mi>h</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mrow><mn>1</mn><mo>−</mo><mi>e</mi><mi>x</mi><mi>p</mi><mo stretchy="false">(</mo><mo>−</mo><mn>2</mn><mi>x</mi><mo stretchy="false">)</mo></mrow><mrow><mn>1</mn><mo>+</mo><mi>e</mi><mi>x</mi><mi>p</mi><mo stretchy="false">(</mo><mo>−</mo><mn>2</mn><mi>x</mi><mo stretchy="false">)</mo></mrow></mfrac></mrow><annotation encoding="application/x-tex">tanh(x)=\frac{1-exp(-2x)}{1+exp(-2x)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal">h</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.53em;vertical-align:-0.52em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.01em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mbin mtight">+</span><span class="mord mathnormal mtight">e</span><span class="mord mathnormal mtight">x</span><span class="mord mathnormal mtight">p</span><span class="mopen mtight">(</span><span class="mord mtight">−</span><span class="mord mtight">2</span><span class="mord mathnormal mtight">x</span><span class="mclose mtight">)</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.485em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mbin mtight">−</span><span class="mord mathnormal mtight">e</span><span class="mord mathnormal mtight">x</span><span class="mord mathnormal mtight">p</span><span class="mopen mtight">(</span><span class="mord mtight">−</span><span class="mord mtight">2</span><span class="mord mathnormal mtight">x</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.52em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>）</p><img class="showonphone65" src="https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210611092628.png" alt="图7. 常见激活函数" style="width:40%"><p>编程实现：<br>以单隐层为例，模型总计三层，第一层是输入层，第二层是隐藏层，第三层是输出层，由于是多分类问题，所以第三层后面还要接一个Softmax层，注意pytorch为了数值稳定性（具体我也不清楚），前向传播时最后的输出并不会执行Softmax运算，而是留到计算交叉熵损失的时候再算（<code>torch.nn.CrossEntropyLoss()</code>），由于<code>torch.utils.data.DataLoader</code>迭代产生的批量样本数据的形状是<code>(batch_size,dim)</code>，前述计算式中则是基于相反的形状，所以为了适用于已经定义好的<code>d2l.train_ch3()</code>等方法，我稍稍修改了该单隐层网络的前向传播计算式：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi mathvariant="bold">Z</mi><mrow><mi>n</mi><mo>×</mo><msub><mi>S</mi><mn>2</mn></msub></mrow><mn>2</mn></msubsup><mo>=</mo><msub><mi mathvariant="bold">X</mi><mrow><mi>n</mi><mo>×</mo><msub><mi>S</mi><mn>1</mn></msub></mrow></msub><msubsup><mi mathvariant="bold">W</mi><mrow><msub><mi>S</mi><mn>1</mn></msub><mo>×</mo><msub><mi>S</mi><mn>2</mn></msub></mrow><mn>1</mn></msubsup><mo>+</mo><msubsup><mi mathvariant="bold">B</mi><mrow><mn>1</mn><mo>×</mo><msub><mi>S</mi><mn>2</mn></msub></mrow><mn>2</mn></msubsup></mrow><annotation encoding="application/x-tex">\mathbf{Z}_{n\times S_2}^2=\mathbf{X}_{n\times S_1}\mathbf{W}_{S_1\times S_2}^1+\mathbf{B}_{1\times S_2}^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.189539em;vertical-align:-0.37543099999999996em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">Z</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.424669em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">×</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.37543099999999996em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.189539em;vertical-align:-0.37543099999999996em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">X</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">×</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2501em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">W</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.424669em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.37543099999999996em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.189539em;vertical-align:-0.37543099999999996em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">B</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.424669em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mbin mtight">×</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.37543099999999996em;"><span></span></span></span></span></span></span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi mathvariant="bold">A</mi><mrow><mi>n</mi><mo>×</mo><msub><mi>S</mi><mn>2</mn></msub></mrow><mn>2</mn></msubsup><mo>=</mo><mi>σ</mi><mo stretchy="false">(</mo><msubsup><mi mathvariant="bold">Z</mi><mrow><mi>n</mi><mo>×</mo><msub><mi>S</mi><mn>2</mn></msub></mrow><mn>2</mn></msubsup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\mathbf{A}_{n\times S_2}^2=\sigma(\mathbf{Z}_{n\times S_2}^2)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.189539em;vertical-align:-0.37543099999999996em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">A</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.424669em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">×</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.37543099999999996em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.189539em;vertical-align:-0.37543099999999996em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathbf">Z</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.424669em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">×</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.37543099999999996em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi mathvariant="bold">Z</mi><mrow><mi>n</mi><mo>×</mo><msub><mi>S</mi><mn>3</mn></msub></mrow><mn>3</mn></msubsup><mo>=</mo><msubsup><mi mathvariant="bold">A</mi><mrow><mi>n</mi><mo>×</mo><msub><mi>S</mi><mn>2</mn></msub></mrow><mn>2</mn></msubsup><msubsup><mi mathvariant="bold">W</mi><mrow><mi>S</mi><mn>2</mn><mo>×</mo><msub><mi>S</mi><mn>3</mn></msub></mrow><mn>2</mn></msubsup><mo>+</mo><msubsup><mi mathvariant="bold">B</mi><mrow><mn>1</mn><mo>×</mo><msub><mi>S</mi><mn>3</mn></msub></mrow><mn>3</mn></msubsup></mrow><annotation encoding="application/x-tex">\mathbf{Z}_{n\times S_3}^3=\mathbf{A}_{n\times S_2}^2\mathbf{W}_{S2\times S_3}^2+\mathbf{B}_{1\times S_3}^3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.189539em;vertical-align:-0.37543099999999996em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">Z</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.424669em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">×</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.37543099999999996em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.189539em;vertical-align:-0.37543099999999996em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">A</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.424669em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">×</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.37543099999999996em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.01597em;">W</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.424669em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="mord mtight">2</span><span class="mbin mtight">×</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.37543099999999996em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.189539em;vertical-align:-0.37543099999999996em;"></span><span class="mord"><span class="mord"><span class="mord mathbf">B</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.424669em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mbin mtight">×</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.37543099999999996em;"><span></span></span></span></span></span></span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi mathvariant="bold">Y</mi><mo>^</mo></mover><mo>=</mo><menclose notation="horizontalstrike"><mtext mathvariant="bold">softmax</mtext></menclose><mo stretchy="false">(</mo><msubsup><mi mathvariant="bold">Z</mi><mrow><mi>n</mi><mo>×</mo><msub><mi>S</mi><mn>3</mn></msub></mrow><mn>3</mn></msubsup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\hat{\mathbf{Y}}=\sout{\textbf{softmax}}(\mathbf{Z}_{n\times S_3}^3)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9495499999999999em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9495499999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathbf" style="margin-right:0.02875em;">Y</span></span></span></span><span style="top:-3.25511em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.25em;"><span class="mord">^</span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.189539em;vertical-align:-0.37543099999999996em;"></span><span class="mord"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord text"><span class="mord textbf">softmax</span></span></span></span><span style="top:-3.2155em;"><span class="pstrut" style="height:3em;"></span><span class="stretchy sout"></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathbf">Z</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.424669em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">×</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.05764em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.37543099999999996em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span></p><div class="tabs" id="mlpbcsx"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#mlpbcsx-1">准备数据</button></li><li class="tab"><button type="button" data-href="#mlpbcsx-2">定义模型、损失和优化函数</button></li><li class="tab"><button type="button" data-href="#mlpbcsx-3">训练</button></li><li class="tab"><button type="button" data-href="#mlpbcsx-4">附（简洁实现）</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="mlpbcsx-1"><p>仍使用Fashion-MNIST数据集，同Softmax多分类</p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="mlpbcsx-2"><p>首先定义激活函数，作为网络中的激活层：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### 定义激活函数</span></span><br><span class="line"><span class="keyword">import</span> torch <span class="keyword">as</span> pt</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sigmoid</span>(<span class="params">Z</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>/(<span class="number">1</span>+pt.exp(-Z))</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">relu</span>(<span class="params">Z</span>):</span><br><span class="line">    <span class="keyword">return</span> pt.<span class="built_in">max</span>(Z,other=pt.Tensor([<span class="number">0.0</span>])) <span class="comment">#尽管ReLU并不完全处处可导，但是从实验看pytorch的自动求偏导机制并不会因此出错</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">tanh</span>(<span class="params">Z</span>):</span><br><span class="line">    <span class="keyword">return</span> (<span class="number">1</span>-pt.exp(-<span class="number">2</span>*Z))/(<span class="number">1</span>+pt.exp(-<span class="number">2</span>*Z))</span><br></pre></td></tr></table></figure><p>优化函数当然还是简单的随机梯度下降，而将要调用的训练方法<code>d2l.train_ch3()</code>中已经定义了SGD过程：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### 定义网络模型</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">MLP_1</span>(<span class="params">X,W1,W2,B1,B2,activate</span>):</span><br><span class="line">    X=X.view((-<span class="number">1</span>,<span class="number">784</span>)) <span class="comment">#注意fashion-mnist的批量数据形状为(batch_size,1,28,28)，形状重塑为(batch_sise,784)</span></span><br><span class="line">    <span class="keyword">return</span> activate(X.mm(W1)+B1).mm(W2)+B2</span><br><span class="line"></span><br><span class="line"><span class="comment">### 定义损失函数</span></span><br><span class="line"><span class="keyword">import</span> torch.nn <span class="keyword">as</span> nn</span><br><span class="line">loss=nn.CrossEntropyLoss() <span class="comment">#为了得到更好的数值稳定性，我们直接使用PyTorch提供的包括softmax运算和交叉熵损失计算的函数</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="mlpbcsx-3"><p>训练前还是先准备数据生成器并作参数初始化：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### 获取fashion-mnist训练数据以及小批量生成器</span></span><br><span class="line"><span class="keyword">import</span> d2l</span><br><span class="line">batch_size=<span class="number">256</span></span><br><span class="line">train_iter,test_iter=d2l.load_data_fashion_mnist(batch_size,root=<span class="string">&#x27;./data/FashionMNIST&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">### 初始化模型参数</span></span><br><span class="line">num_inputs=<span class="number">784</span> <span class="comment">#输入层节点数</span></span><br><span class="line">num_hiddens=<span class="number">256</span> <span class="comment">#隐层节点数</span></span><br><span class="line">num_outputs=<span class="number">10</span> <span class="comment">#输出层节点数</span></span><br><span class="line">W1 = pt.tensor(np.random.normal(<span class="number">0</span>, <span class="number">0.01</span>, (num_inputs, num_hiddens)), dtype=pt.<span class="built_in">float</span>)</span><br><span class="line">B1 = pt.zeros(num_hiddens, dtype=pt.<span class="built_in">float</span>)</span><br><span class="line">W2 = pt.tensor(np.random.normal(<span class="number">0</span>, <span class="number">0.01</span>, (num_hiddens, num_outputs)), dtype=pt.<span class="built_in">float</span>)</span><br><span class="line">B2 = pt.zeros(num_outputs, dtype=pt.<span class="built_in">float</span>)</span><br><span class="line"><span class="comment">#设置权重/偏置参数可导</span></span><br><span class="line">params = [W1, B1, W2, B2]</span><br><span class="line"><span class="keyword">for</span> param <span class="keyword">in</span> params:</span><br><span class="line">    _=param.requires_grad_(requires_grad=<span class="literal">True</span>)</span><br></pre></td></tr></table></figure><p>开始训练：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### 训练</span></span><br><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> partial</span><br><span class="line">num_epochs = <span class="number">5</span></span><br><span class="line">lr = <span class="number">100.0</span> <span class="comment">#注意交叉熵中已经除以了batch_size，而sgd中又除以batch_size，所以这边学习率设大一点以抵消其中一个除法</span></span><br><span class="line">net = partial(MLP_1,W1=W1,W2=W2,B1=B1,B2=B2,activate=relu)</span><br><span class="line">d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params, lr)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">epoch 1, loss 0.0030, train acc 0.709, test acc 0.737</span></span><br><span class="line"><span class="string">epoch 2, loss 0.0019, train acc 0.824, test acc 0.787</span></span><br><span class="line"><span class="string">epoch 3, loss 0.0017, train acc 0.845, test acc 0.795</span></span><br><span class="line"><span class="string">epoch 4, loss 0.0016, train acc 0.855, test acc 0.854</span></span><br><span class="line"><span class="string">epoch 5, loss 0.0015, train acc 0.864, test acc 0.816</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="mlpbcsx-4"><p><code>train_iter</code>,<code>test_iter</code>,<code>loss</code>都复用自前面的代码，此处简洁实现只要重新定义网络部分即可：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### 定义模型</span></span><br><span class="line">num_inputs, num_outputs, num_hiddens = <span class="number">784</span>, <span class="number">10</span>, <span class="number">256</span></span><br><span class="line">net=nn.Sequential(</span><br><span class="line">    d2l.FlattenLayer(),</span><br><span class="line">    nn.Linear(num_inputs,num_hiddens),</span><br><span class="line">    nn.ReLU(),</span><br><span class="line">    nn.Linear(num_hiddens,num_outputs)</span><br><span class="line">)</span><br><span class="line"><span class="comment">#初始化模型参数</span></span><br><span class="line"><span class="keyword">from</span> torch.nn <span class="keyword">import</span> init</span><br><span class="line"><span class="keyword">for</span> params <span class="keyword">in</span> net.parameters():</span><br><span class="line">    _=init.normal_(params, mean=<span class="number">0</span>, std=<span class="number">0.01</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">### 定义损失函数、优化算法并训练模型</span></span><br><span class="line">optimizer = pt.optim.SGD(net.parameters(), lr=<span class="number">0.5</span>) <span class="comment">#优化算法</span></span><br><span class="line">num_epochs = <span class="number">5</span></span><br><span class="line">d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, <span class="literal">None</span>, <span class="literal">None</span>, optimizer)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">epoch 1, loss 0.0030, train acc 0.708, test acc 0.700</span></span><br><span class="line"><span class="string">epoch 2, loss 0.0019, train acc 0.821, test acc 0.745</span></span><br><span class="line"><span class="string">epoch 3, loss 0.0017, train acc 0.842, test acc 0.829</span></span><br><span class="line"><span class="string">epoch 4, loss 0.0015, train acc 0.856, test acc 0.858</span></span><br><span class="line"><span class="string">epoch 5, loss 0.0014, train acc 0.865, test acc 0.846</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><style>.tip{width:80%;}@media only screen and (max-width: 600px){    .tip{width:100%}}</style><div class="tip fas fa-quote-left"><p>[1] <a href="https://github.com/TingsongYu/PyTorch_Tutorial" target="_blank">Pytorch模型训练实用教程</a><br>[2] <a href="https://www.amazon.cn/dp/B072ZCXMRN" target="_blank"><!--span title="错误有点多啊"-->Python机器学习算法<!--/span--> 赵志勇 著</a><br>[3] <a href="https://tangshusen.me/Dive-into-DL-PyTorch/" target="_blank">动手学深度学习 PyTorch版</a><br><span class="dyhideonlight">[4] <a href="https://zhuanlan.zhihu.com/p/45014864" target="_blank">从最优化的角度看待Softmax损失函数</a></span></p></div>]]></content>
      
      
      <categories>
          
          <category> 深度学习 </category>
          
          <category> DL基础 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> Pytorch </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>Python基础 - 面向对象编程</title>
      <link href="posts/22901/"/>
      <url>posts/22901/</url>
      
        <content type="html"><![CDATA[<div style="display:none;"><div class="note green icon flat"><i class="note-icon fas fa-rocket"></i><p>📚 文档目录 <!--pjax.loadUrl(...)加载方式仅限于加密页面内的站内地址跳转--><br>🎃 <span style="color:#49b1f5;cursor:pointer;" onclick="pjax.loadUrl('/posts/5311/')"><span style="color:#3a96dd">类型和对象</span></span> - 🎈 <span style="color:#49b1f5;cursor:pointer;" onclick="pjax.loadUrl('/posts/176/')"><span style="color:#3a96dd">程序结构与函数编程</span></span> - 🎏 面向对象编程</p></div></div><div class="note green icon flat"><i class="note-icon fas fa-rocket"></i><p>📚 文档目录<br>🎃 <a href="/posts/5311/"><span style="color:#3a96dd">类型和对象</span></a> - 🎈 <a href="/posts/176/"><span style="color:#3a96dd">程序结构与函数编程</span></a> - 🎏 面向对象编程</p></div><h2 id="类">类</h2><div class="tabs" id="sxfwkz"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#sxfwkz-1"><code>class</code>语句</button></li><li class="tab"><button type="button" data-href="#sxfwkz-2"><code>__slots__</code></button></li><li class="tab"><button type="button" data-href="#sxfwkz-3">私有属性</button></li><li class="tab"><button type="button" data-href="#sxfwkz-4"><code>__new__()</code></button></li><li class="tab"><button type="button" data-href="#sxfwkz-5">元类</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="sxfwkz-1"><p>类定义了一组属性，包括变量（指类变量，为所有实例共享）、方法（有三种类型，实例方法、静态方法和类方法）以及由<code>@property</code>支持的特性（需要计算的属性），使用<code>class</code>语句可以创建类对象（注意区分“类对象”和“类实例”），类可以充当一个命名空间，与模块很类似，类的实例是以函数形式调用类对象来创建的（类名后加小括号），然后将创建的实例传递给类的<code>__init__()</code>方法，<code>__init__()</code>方法的参数包括新创建的实例<code>self</code>和用于初始化实例的一些其他参数（可以缺省），注意<code>__init__()</code>只能返回<code>None</code>，可以在其中将一些初始化参数绑定在<code>self</code>对象上作为实例属性，之后可以通过属性名和<code>.</code>运算符访问到实例的这些属性（任意对象都有一个<code>__dict__</code>字典属性，当然也有特例，存储了所有通过<code>obj.property=value</code>方式动态绑定在对象上的属性），在访问属性时，首先会检查实例，如果不知道该属性的任何信息，则会对实例的类进行搜索，如果还没有，会继续搜索其父类，直到没有更多的基类可供搜索</p><p>继承是一种创建新类的机制，目的是专门使用或修改现有类的行为，原始类称为基类或超类，新类称为派生类或子类，通过继承创建类时（可以有多个基类，即多继承，否则叫单继承），所创建的类将继承其基类定义中的属性（注意继承的是类属性而不会继承基类的任何实例的绑定属性），且派生类可以重新定义任何这些属性并添加自己的新属性。子类如果没有定义自己的<code>__init__()</code>方法，实例化子类的时候将会自动调用父类的初始化函数（<code>__new__()</code>也一样），反之，则不会调用，除非手动执行<code>super().__init__()</code>（不建议通过父类类名调用<code>__init__()</code>方法），关于多重继承时的属性查找，会按照MRO顺序（<a href="/posts/5311/">第一章节</a>已经谈过这个问题）依序搜索基类</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Dog</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,name</span>):</span><br><span class="line">        self.name=name</span><br><span class="line">    </span><br><span class="line"><span class="keyword">class</span> <span class="title class_">WorkDog</span>(<span class="title class_ inherited__">Dog</span>): <span class="comment">#工作狗</span></span><br><span class="line">    allnum=<span class="number">0</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,name,identity</span>): <span class="comment">#工作狗除了姓名，还具有编制identity，当前全部注册的工作狗数量由allnum类属性记录</span></span><br><span class="line">        self.__class__.allnum+=<span class="number">1</span> <span class="comment">#千万不能写成self.allnum+=1或者WorkDog.allnum+=1，如果没有派生类的话，后者才正确，前者将会创建一个与类属性allnum同名的实例绑定属性（但若类定义allnum是一个可变对象的话，则又不会新创建实例绑定属性，除非写成self.allnum=self.allnum+1的形式，因为+=对可变对象来说是一个原址操作，示例参见https://github.com/leisurelicht/wtfpython-cn#-class-attributes-and-instance-attributes%E7%B1%BB%E5%B1%9E%E6%80%A7%E5%92%8C%E5%AE%9E%E4%BE%8B%E5%B1%9E%E6%80%A7），数值将总是为1，但是在访问该类属性的时候，总是可以写成self.allnum，因为实例上找不到，会自动到类中寻找</span></span><br><span class="line">        self.identity=identity</span><br><span class="line">        <span class="built_in">super</span>().__init__(name) <span class="comment">#自定义__init__()后，除非手动调用父类初始化方法，否则不会自动调用，在单继承情况下写成Dog.__init__(self,name)也没问题，但是多继承就不一定了，因此总是建议采用super方式，而且后者形式更加简约，super()（python3中等价于super(WorkDog,self)）返回super对象（相当于父类但不是原始父类，是绑定了实例self的bound super object，且多继承的时候返回的还可能是兄弟类，具体参见第一章节所提到的钻石继承），不同于其他通过类访问实例方法（返回非绑定方法，只有通过实例访问实例方法才返回绑定方法）的情况，此处返回的也是“绑定方法”，即绑定了self参数的父类__init__()方法，因此调用时不需要再传入self参数</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">work</span>(<span class="params">self</span>): <span class="comment">#一个公开的未实现的接口，子类应重载之</span></span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__del__</span>(<span class="params">self</span>):</span><br><span class="line">        self.__class__.allnum-=<span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ArmyDog</span>(<span class="title class_ inherited__">WorkDog</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">work</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.name&#125;</span>(<span class="subst">&#123;self.identity&#125;</span>)在追击敌人&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">DrugDog</span>(<span class="title class_ inherited__">WorkDog</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">work</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.name&#125;</span>(<span class="subst">&#123;self.identity&#125;</span>)在追查毒品&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">SuperDog</span>(DrugDog,ArmyDog):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,name,identity</span>):</span><br><span class="line">        self.__class__.allnum=<span class="number">0</span> <span class="comment">#访问SuperDog.allnum时会在基类（ArmyDog或DrugDog）中查找，可能已经非零了</span></span><br><span class="line">        <span class="built_in">super</span>().__init__(name,identity)</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line">army_dog_1=ArmyDog(<span class="string">&#x27;Cherry&#x27;</span>,<span class="built_in">id</span>(<span class="string">&#x27;Cherry&#x27;</span>)) <span class="comment">#ArmyDog直接继承了父类的__init__()方法，初始化ArmyDog类实例的时候会自动调用之</span></span><br><span class="line">army_dog_2=ArmyDog(<span class="string">&#x27;Black&#x27;</span>,<span class="built_in">id</span>(<span class="string">&#x27;Black&#x27;</span>))</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(army_dog_2.__dict__) <span class="comment">#&#123;&#x27;identity&#x27;: 1761656222920, &#x27;name&#x27;: &#x27;Black&#x27;&#125; #通过__dict__实例属性字典查找用户绑定在实例上的所有属性</span></span><br><span class="line">army_dog_2_ref=army_dog_2 <span class="comment">#对army_dog_2所指向的对象引用计数+1，于是当前引用数总计为2</span></span><br><span class="line"></span><br><span class="line">drug_dog_1=DrugDog(<span class="string">&#x27;HelloKit&#x27;</span>,<span class="built_in">id</span>(<span class="string">&#x27;HelloKit&#x27;</span>))</span><br><span class="line">drug_dog_2=DrugDog(<span class="string">&#x27;Jack&#x27;</span>,<span class="built_in">id</span>(<span class="string">&#x27;Jack&#x27;</span>))</span><br><span class="line">drug_dog_3=DrugDog(<span class="string">&#x27;Pig&#x27;</span>,<span class="built_in">id</span>(<span class="string">&#x27;Pig&#x27;</span>))</span><br><span class="line"></span><br><span class="line"><span class="keyword">del</span> army_dog_2 <span class="comment">#del语句看似是“删除对象”，准确说其实是对象引用计数-1，且del语句并不会立即执行__del__()方法，只有在对象的引用计数降为0的时候才会执行，这时候对象才会真的从内存中删除</span></span><br><span class="line"><span class="built_in">print</span>(ArmyDog.allnum) <span class="comment">#2 #写成army_dog_1.allnum也正确，但是语义不明，因为allnum明明是一个类属性，通过实例访问会让人误以为是实例属性</span></span><br><span class="line"><span class="built_in">print</span>(DrugDog.allnum) <span class="comment">#3</span></span><br><span class="line"><span class="keyword">del</span> army_dog_2_ref</span><br><span class="line"><span class="built_in">print</span>(ArmyDog.allnum) <span class="comment">#1</span></span><br><span class="line"></span><br><span class="line">drug_dog_2.work() <span class="comment">#Jack(2607617062368)在追查毒品</span></span><br><span class="line"></span><br><span class="line">super_dog_1=SuperDog(<span class="string">&#x27;Hero&#x27;</span>,<span class="built_in">id</span>(<span class="string">&#x27;Hero&#x27;</span>))</span><br><span class="line"><span class="built_in">print</span>(super_dog_1.__class__.mro()) <span class="comment">#[&lt;class &#x27;__main__.SuperDog&#x27;&gt;, &lt;class &#x27;__main__.DrugDog&#x27;&gt;, &lt;class &#x27;__main__.ArmyDog&#x27;&gt;, &lt;class &#x27;__main__.WorkDog&#x27;&gt;, &lt;class &#x27;__main__.Dog&#x27;&gt;, &lt;class &#x27;object&#x27;&gt;]</span></span><br><span class="line">super_dog_1.work() <span class="comment">#Hero(2359695357632)在追查毒品 #SuperDog并未实现自己的work()方法，因此在属性查找时，会顺着MRO列表依次在“基类”中寻找，MRO列表中位于SuperDog之后的正是DrugDog，而DrugDog类确实定义了自己的work()方法，所以属性查找到此结束，就是它</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">work</span>(<span class="params">self</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.name&#125;</span>(<span class="subst">&#123;self.identity&#125;</span>)在追击敌人，同时在追查毒品&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">SuperDog.work=work <span class="comment">#给类动态绑定属性方法，且默认是实例方法，相当于你一开始在定义SuperDog的地方写了work()方法</span></span><br><span class="line">super_dog_1.work() <span class="comment">#Hero(1559184520896)在追击敌人，同时在追查毒品</span></span><br><span class="line"></span><br><span class="line"><span class="meta">@classmethod</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">print_allnum</span>(<span class="params">cls</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;cls&#125;</span>类总数量为<span class="subst">&#123;cls.allnum&#125;</span>&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">SuperDog.print_allnum=print_allnum <span class="comment">#给类对象动态绑定类方法，同理静态方法也可以</span></span><br><span class="line">SuperDog.print_allnum() <span class="comment">#&lt;class &#x27;__main__.SuperDog&#x27;&gt;类总数量为1 #也可以通过实例调用类方法，super_dog_1.print_allnum()</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="sxfwkz-2"><p>通常你可以为类实例动态绑定任意数量的任意属性，当你要限制此行为时，或者当一个类需要创建大量实例要节省内存时，可以设置<code>__slots__</code>类属性声明实例可动态绑定的属性范围，一旦定义<code>__slots__</code>，类实例就不再有<code>__dict__</code>属性，且类中不能再定义与<code>__slots__</code>列表中同名的类属性：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">student</span>:</span><br><span class="line">    __slots__=(<span class="string">&#x27;name&#x27;</span>,<span class="string">&#x27;score&#x27;</span>)</span><br><span class="line">    <span class="comment">#name=&#x27;xxx&#x27; #ValueError: &#x27;name&#x27; in __slots__ conflicts with class variable #类中不能再定义出现在__slots__列表中的属性</span></span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line">    </span><br><span class="line">s=student()</span><br><span class="line">s.name=<span class="string">&#x27;dy&#x27;</span></span><br><span class="line">s.score=<span class="number">8.0</span></span><br><span class="line"><span class="comment">#s.sex=&#x27;female&#x27; #AttributeError: &#x27;student&#x27; object has no attribute &#x27;sex&#x27; #无法为实例动态绑定非__slots__列表属性</span></span><br><span class="line"><span class="comment">#print(s.__dict__) #AttributeError: &#x27;student&#x27; object has no attribute &#x27;__dict__&#x27; #定义__slots__类属性的类实例不再有__dict__属性字典</span></span><br><span class="line"></span><br><span class="line">student.school=<span class="string">&#x27;nuist&#x27;</span> <span class="comment">#__slots__不会限制类本身可动态绑定属性的范围</span></span><br><span class="line"><span class="built_in">print</span>(student.__dict__) <span class="comment">#&#123;&#x27;__module__&#x27;: &#x27;__main__&#x27;, &#x27;__slots__&#x27;: (&#x27;name&#x27;, &#x27;score&#x27;), &#x27;name&#x27;: &lt;member &#x27;name&#x27; of &#x27;student&#x27; objects&gt;, &#x27;score&#x27;: &lt;member &#x27;score&#x27; of &#x27;student&#x27; objects&gt;, &#x27;__doc__&#x27;: None, &#x27;school&#x27;: &#x27;nuist&#x27;&#125; #注意看类的__dict__中有了name和score两个属性，这也是为什么上面在类中定义同名属性name时会发生冲突</span></span><br></pre></td></tr></table></figure><p>在实际使用中，<code>__slots__</code>不是作为一种安全特性，虽然定义了<code>__slots__</code>的类不再依赖<code>__dict__</code>字典进行实例属性的存储和查找，从而达到隐藏实例动态绑定的属性的目的，但是并没有对属性访问本身增加任何控制，其主要目的还是对内存和性能的优化，使用<code>__slots__</code>的类实例不再使用字典来存储实例绑定属性，它会使用基于数组的更加紧密的数据结构，在创建大量对象的程序中，使用<code>__slots__</code>可以显著减少<a href="http://tech.oyster.com/save-ram-with-python-slots/">内存占用</a>和执行时间（直接通过数组内存地址偏移访问<code>__slots__</code>中定义的属性比通过<code>__dict__</code>字典进行属性查找要快），但是也会带来一些需要注意的问题，1）<code>__slots__</code>无法被继承，每个子类都要重新定义一遍，如果忘记这一点，子类的执行速度将比没有使用<code>__slots__</code>时更慢，2）实例只能动态绑定那些在<code>__slots__</code>列表中出现的属性，极大影响了程序的灵活性，3）实例不能被弱引用，除非将<code>'__weakref__'</code>放进<code>__slots__</code></p><p>关于上述第一点，子类如果没有重新定义<code>__slots__</code>，动态绑定将不受限制，重新定义时如果和基类一致，可以直接赋一个空值<code>__slots__=()</code>，也可以在基类的基础上进行增补，但无法删除</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">graduate</span>(<span class="title class_ inherited__">student</span>):</span><br><span class="line">    __slots__=(<span class="string">&#x27;sex&#x27;</span>) <span class="comment">#一个笔误，之前以为__slots__必须是一个列表，此处等同于：__slots__=&#x27;sex&#x27;，当前子类graduate的__slots__在基类基础上扩展，属性范围限制在[&#x27;name&#x27;,&#x27;score&#x27;,&#x27;sex&#x27;]</span></span><br><span class="line">    </span><br><span class="line">g=graduate()</span><br><span class="line">g.name=<span class="string">&#x27;dy&#x27;</span></span><br><span class="line">g.score=<span class="number">25</span></span><br><span class="line">g.sex=<span class="string">&#x27;female&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(g.sex)</span><br></pre></td></tr></table></figure><p>关于第三点，弱引用的问题，定义了<code>__slots__</code>的类实例无法被弱引用，因为此时不仅是类实例的<code>__dict__</code>属性被禁用，<code>__weakref__</code>属性也被禁用，<code>__weakref__</code>属性是干嘛的？假设对对象进行弱引用，那么创建的弱引用将存储在对象的<code>__weakref__</code>属性中，因此解决办法就是将<code>'__weakref__'</code>放进<code>__slots__</code>列表中：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">graduate</span>(<span class="title class_ inherited__">student</span>):</span><br><span class="line">    __slots__=(<span class="string">&#x27;sex&#x27;</span>,<span class="string">&#x27;__weakref__&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> weakref</span><br><span class="line"></span><br><span class="line">g=graduate()</span><br><span class="line"><span class="built_in">print</span>(g.__weakref__) <span class="comment">#None #此时还没有弱引用</span></span><br><span class="line">ref=weakref.ref(g) <span class="comment">#如果没有将&#x27;__weakref__&#x27;放到__slots__中，则报错：TypeError: cannot create weak reference to &#x27;graduate&#x27; object</span></span><br><span class="line"><span class="built_in">print</span>(g.__weakref__) <span class="comment">#&lt;weakref at 0x000002595C39C4F8; to &#x27;graduate&#x27; at 0x000002595C60CDC8&gt;</span></span><br><span class="line"></span><br><span class="line">g.name=<span class="string">&#x27;muggle&#x27;</span></span><br><span class="line">g.score=<span class="number">25</span></span><br><span class="line">g.sex=<span class="string">&#x27;female&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;ref().name&#125;</span>,<span class="subst">&#123;ref().sex&#125;</span>,<span class="subst">&#123;ref().score&#125;</span>&#x27;</span>) <span class="comment">#muggle,female,25 #调用弱引用将获取被弱引用的原始对象</span></span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>弱引用</span></div>    <div class="hide-content"><p><code>weakref</code>模块允许用户创建对对象的弱引用（weak reference），相比于普通的引用（为了和“弱引用”这一名词对应，在官方文档中明确有strong reference“强引用”一说）来说，只要存在任何一个对对象的强引用（即引用计数大于1，注意弱引用不计在内，要删除某个强引用，使用<code>del</code>语句，引用计数减一），这个对象就不会被垃圾收集器销毁，而当引用计数为0时（没有强引用），无论还有多少弱引用，那么它将会被垃圾收集器收回。在对象未被销毁之前，可以通过弱引用访问到对象，否则只能得到<code>None</code></p><p>weakref运行在“观察者模式”，当我们创建一个对对象的弱引用，意味着对该对象进行观察，当对象被回收，观察者将立即得到一个反馈并执行回调函数，假设存在的话。另外并非所有对象都可以创建弱引用，可以创建弱引用的对象包括类实例、函数对象、实例方法、集合、冰冻集合、文件对象、生成器、类对象、sockets、数组、队列（deque）、正则表达式对象（regular expression pattern）以及code对象，而列表和字典是不能直接支持弱引用的：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">import</span> weakref</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>wr=weakref.ref(a)</span><br><span class="line">Traceback (most recent call last):</span><br><span class="line">  File <span class="string">&quot;&lt;stdin&gt;&quot;</span>, line <span class="number">1</span>, <span class="keyword">in</span> &lt;module&gt;</span><br><span class="line">TypeError: cannot create weak reference to <span class="string">&#x27;list&#x27;</span> <span class="built_in">object</span></span><br></pre></td></tr></table></figure><p>通过子类化列表或字典可以增加这样的支持：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> weakref</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">new_list</span>(<span class="title class_ inherited__">list</span>):</span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">callback</span>(<span class="params">ref</span>):</span><br><span class="line">    <span class="keyword">if</span> ref <span class="keyword">is</span> wr:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;列表对象[1,2,3]被回收&#x27;</span>)</span><br><span class="line"></span><br><span class="line">a=new_list([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line">wr=weakref.ref(a,callback)</span><br><span class="line"><span class="keyword">del</span> a</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">列表对象[1,2,3]被回收</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>但是像元组和整型，即使子类化也不能支持弱引用。在上述示例中，通过<code>weakref.ref()</code>创建了一个弱引用对象，可以像调用函数那样调用它以获取被引用的对象（因为弱引用类实现了<code>__call__()</code>方法），称之为referent，如果referent不再存活，调用将返回<code>None</code>，因此如果你要测试一个referent是否存活，可以使用逻辑表达式<code>ref() is not None</code>（其中<code>ref</code>是一个弱引用对象）</p><p>简单介绍<code>weakref</code>模块的类或方法：</p><ul><li><p><code>class weakref.ref(obj[, callback])</code>（创建对对象的弱引用）<br>参数<code>obj</code>是被弱引用的原始对象（被称为referent），<code>callback</code>是回调函数，当<code>obj</code>引用计数减为0被当作垃圾回收清理的时候，会自动调用该函数，且传入该弱引用作为唯一参数，可以创建多个弱引用，当referent被回收的时候，会根据弱引用创建的时间由近及远地逐个执行回调函数，假设定义了的话</p><p>假设referent是可哈希的，弱引用对象也是可哈希的，即使referent被销毁，弱引用对象仍能维持其哈希值，但是如果你在referent被销毁之后才第一次计算弱引用对象的哈希值，将导致<code>TypeError</code></p><p>弱引用对象支持等值测试（<code>==</code>），但是不支持排序，不同弱引用之间的等值关系等同于各自对应的referent之间的等值关系（举个例子，假设有两个不同对象满足<code>a==b</code>，且<code>wra</code>是对<code>a</code>的弱引用，<code>wrb</code>是对<code>b</code>的弱引用，那么立即推，<code>wra==wrb</code>是成立的，若其中一方的referent被销毁，则不再相等），特别的，对同一对象所创建的不同弱引用总是等值的（创建弱引用时所传入的回调函数参数不影响等值测试的结果，但会影响<code>is</code>判断的结果），示例：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> weakref</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,name</span>):</span><br><span class="line">        self.name=name</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__hash__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">hash</span>(self.name)</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__eq__</span>(<span class="params">self,another</span>):</span><br><span class="line">        <span class="keyword">if</span> self.name==another.name:</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line">        <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"></span><br><span class="line">a=A(<span class="string">&#x27;msy&#x27;</span>)</span><br><span class="line">b=A(<span class="string">&#x27;msy&#x27;</span>)</span><br><span class="line">wra=weakref.ref(a)</span><br><span class="line">wrb=weakref.ref(b)</span><br><span class="line"><span class="built_in">print</span>(a==b,wra==wrb)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">hash</span>(wra))</span><br><span class="line"><span class="keyword">del</span> b</span><br><span class="line"><span class="comment">#print(hash(wrb)) #TypeError: weak object has gone away</span></span><br><span class="line"><span class="built_in">print</span>(wra==wrb) <span class="comment">#False</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">callback</span>(<span class="params">ref</span>):</span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line">wra2=weakref.ref(a,<span class="built_in">callable</span>)</span><br><span class="line"><span class="built_in">print</span>(wra==wra2,wra <span class="keyword">is</span> wra2) <span class="comment">#True False</span></span><br><span class="line">wra3=weakref.ref(a)</span><br><span class="line"><span class="built_in">print</span>(wra==wra2,wra <span class="keyword">is</span> wra3) <span class="comment">#True True</span></span><br></pre></td></tr></table></figure></li><li><p><code>weakref.proxy(obj[, callback])</code>（创建对对象的代理）<br>代理对象是不可哈希的（无论referent可不可哈希），这阻止了将其用于字典的键，和<code>weakref.ref()</code>一样，支持回调，代理和弱引用的显著的区别是，1）要从弱引用获取referent，你需要使用<code>()</code>调用这个弱引用对象，但是代理不需要，使用代理对象就如同使用对象本身一样，2）当referent销毁后，弱引用调用会返回<code>None</code>，而访问代理则导致<code>ReferenceError</code>：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> weakref</span><br><span class="line"></span><br><span class="line">a=&#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>&#125;</span><br><span class="line">wr=weakref.ref(a)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">callback</span>(<span class="params">ref</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;删除对象&#x27;</span>)</span><br><span class="line"></span><br><span class="line">proxy=weakref.proxy(a,callback)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(wr()) <span class="comment">#&#123;1, 2, 3&#125;</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">repr</span>(proxy))</span><br><span class="line"><span class="built_in">print</span>(proxy) <span class="comment">#&#123;1, 2, 3&#125;</span></span><br><span class="line"></span><br><span class="line">proxy.add(<span class="number">4</span>)</span><br><span class="line"><span class="built_in">print</span>(proxy) <span class="comment">#&#123;1, 2, 3, 4&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">del</span> a <span class="comment">#对象a的引用计数降为0后，自动调用代理的回调函数，输出：删除对象</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(wr()) <span class="comment">#None</span></span><br><span class="line"><span class="built_in">print</span>(proxy) <span class="comment">#ReferenceError: weakly-referenced object no longer exists</span></span><br></pre></td></tr></table></figure></li><li><p><code>weakref.getweakrefcount(obj)</code>（返回对象<code>obj</code>的全部弱引用以及代理数量）</p></li><li><p><code>weakref.getweakrefs(obj)</code>（返回对象<code>obj</code>的全部弱引用和代理对象，以列表返回）</p></li><li><p><code>class weakref.WeakMethod(method)</code>（创建对绑定方法的弱引用）<br>假设你有一个类实例<code>a</code>，<code>f</code>是实例方法，要对<code>a.f</code>创建弱引用，使用<code>WeakMethod(a.f)</code>即可，而标准弱引用对象构造办法（<code>ref(a.f)()</code>将返回<code>None</code>）无法做到这一点，因为<code>a.f</code>返回的是一个全新的“绑定了实例的方法”，其引用计数为0，如果一定要使用标准弱引用对象构造办法，只要将<code>a.f</code>赋给一个变量即可（使引用计数非0），因为<code>WeakMethod</code>是<code>ref</code>的子类，因此要获取被弱引用的原始绑定方法对象，也是通过<code>()</code>进行调用来获取：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> weakref</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;实例方法&#x27;</span>)</span><br><span class="line">    </span><br><span class="line"><span class="meta">    @classmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">cf</span>(<span class="params">cls</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;类方法&#x27;</span>)</span><br><span class="line">        </span><br><span class="line"><span class="meta">    @staticmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">sf</span>():</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;静态方法&#x27;</span>)</span><br><span class="line"></span><br><span class="line">a=A()</span><br><span class="line">m1=weakref.WeakMethod(a.f) <span class="comment">#替换成WeakMethod(a.cf)也可以，但是替换成WeakMethod(a.sf)不行，因为a.sf返回的是非绑定方法</span></span><br><span class="line">m1()()</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(weakref.ref(a.f)()) <span class="comment">#None</span></span><br><span class="line">t=a.f <span class="comment">#替换成a.sf或a.cf都可以</span></span><br><span class="line">m2=weakref.ref(t)</span><br><span class="line">m2()()</span><br></pre></td></tr></table></figure></li><li><p><code>class weakref.finalize(obj, func, *args, **kwargs)</code><br>创建一个可通过<code>()</code>调用的finalizer对象（<code>finalize</code>类的<code>__call__()</code>方法体即是执行<code>func(*args,**kwargs)</code>），当referent对象<code>obj</code>的引用计数降为0时将自动触发调用，另外在程序结束时也总会调用这些finalizer对象（调用顺序和这些对象的创建顺序相反，对比<code>ref(obj,callback)</code>，程序结束时则不会调用<code>callback()</code>，除非在程序中手动执行<code>del</code>语句降低引用计数为0），除非其<code>atexit</code>属性被设置为<code>False</code>，finalizer一旦被调用一次将“死亡”，若调用一个死亡了的finalizer，将返回<code>None</code>（另请注意<code>func</code>、<code>args</code>和<code>kwargs</code>不能直接或间接对<code>obj</code>存在任何引用，否则会导致<code>obj</code>不能被回收，特别的，<code>func</code>不能是<code>obj</code>的实例绑定方法）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> weakref</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>:</span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">callback</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;回收&#x27;</span>)</span><br><span class="line">    <span class="keyword">return</span> <span class="number">888</span></span><br><span class="line"></span><br><span class="line">a=A()</span><br><span class="line">t=weakref.finalize(a,callback)</span><br><span class="line"><span class="built_in">print</span>(t())</span><br><span class="line"><span class="built_in">print</span>(t()) <span class="comment">#1、如果替换这两行为del a，输出结果一致，2、如果注释掉这两行，将先后输出&quot;OVER&quot;和&quot;回收&quot;</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;OVER&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">回收</span></span><br><span class="line"><span class="string">888</span></span><br><span class="line"><span class="string">None</span></span><br><span class="line"><span class="string">OVER</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>finalizer对象的属性、方法：</p><ul><li><code>__call__()</code><br>当finalizer对象存活时调用<code>__call__()</code>将返回<code>func(*args,**kwargs)</code>的结果，并在此之后宣判其死亡，当finalizer对象死亡时调用<code>__call__()</code>将返回<code>None</code></li><li><code>detach()</code><br>当finalizer对象存活时调用<code>detach()</code>将返回<code>(obj, func, args, kwargs)</code>元组，并在此之后宣判其死亡，当finalizer对象死亡时调用<code>detach()</code>将返回<code>None</code></li><li><code>peek()</code><br>同<code>detach()</code>，但是调用后不会导致finalizer对象死亡</li><li><code>alive</code><br>判断finalizer对象是否存活</li><li><code>atexit</code><br>一个可写的布尔属性，默认值为<code>True</code>，且只有<code>atexit</code>属性为<code>True</code>的finalizer对象才会被触发调用</li></ul></li><li><p><code>weakref.ReferenceType</code>（返回弱引用对象的类型<code>&lt;class 'weakref'&gt;</code>）</p></li><li><p><code>weakref.ProxyType</code>（返回不可调用对象的弱代理的类型<code>&lt;class 'weakproxy'&gt;</code>）</p></li><li><p><code>weakref.CallableProxyType</code>（返回可调用对象的弱代理的类型<code>&lt;class 'weakcallableproxy'&gt;</code>）</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> weakref</span><br><span class="line"></span><br><span class="line">s=<span class="built_in">set</span>() <span class="comment">#不可调用对象</span></span><br><span class="line"></span><br><span class="line">t1=weakref.proxy(s)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>(t1))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">isinstance</span>(t1,weakref.ProxyType))</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(): <span class="comment">#可调用对象</span></span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line">t2=weakref.proxy(f)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>(t2))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">isinstance</span>(t2,weakref.CallableProxyType))</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">&lt;class &#x27;weakproxy&#x27;&gt;</span></span><br><span class="line"><span class="string">True</span></span><br><span class="line"><span class="string">&lt;class &#x27;weakcallableproxy&#x27;&gt;</span></span><br><span class="line"><span class="string">True</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></li><li><p><code>weakref.ProxyTypes</code>（返回全部代理类型，即<code>(&lt;class 'weakproxy'&gt;, &lt;class 'weakcallableproxy'&gt;)</code>）</p></li></ul><p>弱引用的主要用途是实现持有大量“大”对象（指占用内存大）的高速缓存或映射，以往由于对象作为高速缓存或映射的条目被引用，导致用户使用完后无法使用<code>del</code>将这些对象的引用计数降为0（只要高速缓存或映射还存在），从而浪费大量空间，为此<code>weakref</code>模块提供了<code>WeakKeyDictionary</code>和<code>WeakValueDictionary</code>用来解决该问题</p><ul><li><code>class weakref.WeakKeyDictionary([dict])</code><br>该字典中的键是弱引用的，当外部不存在对某键的强引用时，会自动删除字典中此键对应的条目，另外<code>WeakKeyDictionary</code>对象拥有一个额外的方法<code>keyrefs()</code>，其返回全部弱引用的键的列表<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> weakref</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>:</span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line">d=weakref.WeakKeyDictionary()</span><br><span class="line">d[A()]=<span class="number">1</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(d.keys())) <span class="comment">#[] #弱字典中空无一物，原因在于&quot;d[A()]=1&quot;中的键&quot;A()&quot;的引用计数为0，它随即被删除</span></span><br><span class="line"></span><br><span class="line">a=A()</span><br><span class="line">d[a]=<span class="number">1</span> <span class="comment">#键&quot;a&quot;存在外部引用：a=A()，其引用计数为1</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(d.keys())) <span class="comment">#[&lt;__main__.A object at 0x000001FA6AB16EB8&gt;]</span></span><br><span class="line"><span class="built_in">print</span>(d[a]) <span class="comment">#1</span></span><br><span class="line"><span class="keyword">del</span> a <span class="comment">#del使&quot;a&quot;的引用计数减1，变为0</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(d.keys())) <span class="comment">#[]</span></span><br><span class="line"><span class="comment">#print(d[a]) #NameError: name &#x27;a&#x27; is not defined</span></span><br></pre></td></tr></table></figure></li><li><code>class weakref.WeakValueDictionary([dict])</code><br>该字典中键的值是弱引用的，当外部不存在对某键值的强引用时，会自动删除此字典中该键值对应的条目，另外<code>WeakValueDictionary</code>对象拥有一个额外的方法<code>valuerefs()</code>，其返回全部弱引用的值的列表</li></ul><p>除了“弱字典”，模块还提供了“弱集合”<code>class weakref.WeakSet([elements])</code>，当弱集合中的某个元素的引用计数降低为0时，将自动从弱集合中删除</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> weakref</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>:</span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line">s=weakref.WeakSet()</span><br><span class="line">a=A()</span><br><span class="line">b=A()</span><br><span class="line">s.add(a)</span><br><span class="line">s.add(b)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(s))</span><br><span class="line"><span class="keyword">del</span> a</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(s))</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">[&lt;__main__.A object at 0x0000019127A1D588&gt;, &lt;__main__.A object at 0x0000019127A1D160&gt;]</span></span><br><span class="line"><span class="string">[&lt;__main__.A object at 0x0000019127A1D588&gt;]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="sxfwkz-3"><p>Python中无法为类声明私有类型的属性，声明私有类型的目的是阻止子类继承该属性，并且只能在类定义中访问私有属性，在类外任何地方都无法直接通过属性名访问它。一种变通是python内部会对类定义中所有以<code>__</code>双下划线开头且不超过一个下划线结尾（这样命名的属性就被认为是“私有属性”）的属性进行名字转换，具体的，在原始属性名前加上“<code>_类名</code>”，譬如：类<code>Foo</code>的“私有属性”<code>__spam</code>被替换为<code>_Foo__spam</code>，使得子类无法通过原始属性名访问它，python把这种技术叫做“name mangling”（属性名轧压机制），示例：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        self.__private()</span><br><span class="line">        self.public()</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__private</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;A.__private()&#x27;</span>)</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">public</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;A.public()&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">B</span>(<span class="title class_ inherited__">A</span>):</span><br><span class="line">    <span class="comment"># def __init__(self): #此处写不写都一样，因为没有实现__init__方法时，本就会自动调用父类的__init__方法</span></span><br><span class="line">    <span class="comment">#     super(B,self).__init__() #或者A.__init__(self)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__private</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;B.__private()&#x27;</span>)</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">public</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;B.public()&#x27;</span>)</span><br><span class="line">        </span><br><span class="line">a=A()</span><br><span class="line">b=B()</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">A.__private()</span></span><br><span class="line"><span class="string">A.public()</span></span><br><span class="line"><span class="string">A.__private()</span></span><br><span class="line"><span class="string">B.public()</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>输出倒数第二行为什么是<code>A.__private()</code>而不是<code>B.__private()</code>（上述示例既展示了python中“私有属性”的工作方式，也展示其愚蠢，为了纠正，应这样实现<code>B</code>的初始化函数：<code>self.__private();self.public()</code>，而不是偷懒直接调用父类的初始化函数），不急，先来看看属性名轧压机制是否真的工作了：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.__private()</span><br><span class="line">---------------------------------------------------------------------------</span><br><span class="line">AttributeError                            Traceback (most recent call last)</span><br><span class="line">&lt;ipython-<span class="built_in">input</span>-<span class="number">2</span>-cc12b64d1d3b&gt; <span class="keyword">in</span> &lt;module&gt;()</span><br><span class="line">----&gt; <span class="number">1</span> a.__private()</span><br><span class="line"></span><br><span class="line">AttributeError: <span class="string">&#x27;A&#x27;</span> <span class="built_in">object</span> has no attribute <span class="string">&#x27;__private&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a._A__private()</span><br><span class="line">A.__private()</span><br></pre></td></tr></table></figure><p>对象<code>a</code>确实访问不到原始的属性方法<code>__private</code>了，名字已经转变为<code>_A__private</code>，实际上解释器在遇到类定义语句时，会首先修改这些“私有”属性的名字，即在内存中的类定义如下（在类定义外动态绑定的双下划线属性名不会被轧压）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        self._A__private() <span class="comment">#修改1</span></span><br><span class="line">        self.public()</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">_A__private</span>(<span class="params">self</span>): <span class="comment">#修改2</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;A.__private()&#x27;</span>)</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">public</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;A.public()&#x27;</span>)</span><br><span class="line">        </span><br><span class="line"><span class="keyword">class</span> <span class="title class_">B</span>(<span class="title class_ inherited__">A</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">_B__private</span>(<span class="params">self</span>): <span class="comment">#修改3</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;B.__private()&#x27;</span>)</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">public</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;B.public()&#x27;</span>)</span><br></pre></td></tr></table></figure><p>现在可以回答上述问题了，当实例化<code>B</code>类时，会调用父类<code>A</code>类的初始化函数，并传入<code>B</code>类实例，记作<code>b</code>，于是在<code>__init__()</code>中将先后执行<code>b._A__private()</code>和<code>b.public()</code>，真相大白</p><p>另外经常遇到以<code>_</code>单下划线开头的变量名（实际上是以任何数量下划线开头的变量，仅习惯上以单下划线打头），如果位于模块级别，在<code>from module import *</code>时是无法导入的（可以预防错误，因为这种方式导入的变量很容易导致“覆盖”，即“命名空间污染”），如果要设置<code>from module import *</code>所允许导入的变量，可以使用<code>__all__</code>指定</p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="sxfwkz-4"><p><code>__new__()</code>是一个静态方法，通用的定义为<code>__new__(cls,*args,**kwargs)</code>（第一个参数<code>cls</code>表示要实例化的类，你总是需要手动传递它），其中<code>*args</code>和<code>**kwargs</code>接收的参数与传递给<code>__init__()</code>的参数相同，注意<code>__new__()</code>是唯一可以编写在创建实例之前执行的代码的地方，其必须有返回值，返回的是创建的实例对象，一般调用父类或<code>object</code>类的<code>__new__()</code>方法来创建，如果返回值不是当前类的实例那么<code>__init__()</code>函数将不会被调用</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__new__</span>(<span class="params">cls,*args,**kwargs</span>): <span class="comment">#__new__和__init__方法的参数除第一个参数(cls或self)外必须完全一致</span></span><br><span class="line">        ret=<span class="built_in">super</span>(A,cls).__new__(cls)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;Return of __new__(): <span class="subst">&#123;ret&#125;</span>&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> ret</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,*args,**kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;Init A <span class="subst">&#123;self&#125;</span> with <span class="subst">&#123;args&#125;</span> and <span class="subst">&#123;kwargs&#125;</span>&#x27;</span>)</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line">        </span><br><span class="line"><span class="keyword">class</span> <span class="title class_">B</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__new__</span>(<span class="params">cls</span>):</span><br><span class="line">        <span class="keyword">return</span> A.__new__(A) <span class="comment">#事实上__new__方法可以生产非当前类的其他任意类的实例对象，这表示__new__方法拥有决定实例对象所属类型的绝对权力，但此时__init__方法则不再被自动调用</span></span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;Init B&#x27;</span>)</span><br><span class="line"></span><br><span class="line">a=A(<span class="string">&#x27;Hello,&#x27;</span>,<span class="string">&#x27;muggledy&#x27;</span>)</span><br><span class="line">b=B()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;-&#x27;</span>*<span class="number">10</span>)</span><br><span class="line">b.__init__()</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">Return of __new__(): &lt;__main__.A object at 0x0000013B40CFB4A8&gt;</span></span><br><span class="line"><span class="string">Init A &lt;__main__.A object at 0x0000013B40CFB4A8&gt; with (&#x27;Hello,&#x27;, &#x27;muggledy&#x27;) and &#123;&#125;</span></span><br><span class="line"><span class="string">Return of __new__(): &lt;__main__.A object at 0x0000013B40CFB518&gt;</span></span><br><span class="line"><span class="string">----------</span></span><br><span class="line"><span class="string">Init A &lt;__main__.A object at 0x0000013B40CFB518&gt; with () and &#123;&#125;</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p><code>__new__</code>方法可用于当你继承一些不可变的类型时（如<code>int</code>、<code>str</code>、<code>tuple</code>），提供给你一个自定义这些类的实例化过程的途径，譬如你要继承<code>int</code>类型实现一个永远为正数的整型，由于是不可变对象，显然你无法在实例创建之后（如<code>__init__()</code>中）进行任何修改：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">PositiveInteger</span>(<span class="title class_ inherited__">int</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__new__</span>(<span class="params">cls,value</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">super</span>(PositiveInteger,cls).__new__(cls,<span class="built_in">abs</span>(value))</span><br><span class="line"></span><br><span class="line">i=PositiveInteger(-<span class="number">3</span>)</span><br><span class="line"><span class="built_in">print</span>(i) <span class="comment">#3</span></span><br></pre></td></tr></table></figure><p>还可以用来实现“单例”，具体后面再说</p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="sxfwkz-5"><p>所谓元类，就是创建类对象本身的类，我们在创建类实例的时候，是通过类名加括号（括号中是初始化参数）的方式，又知道“类的类”是<code>type</code>类型，可想而知类对象是通过<code>type(...)</code>形式创建的，现给定一个类定义，解释器究竟做了什么呢？譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Foo</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    ...</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">func</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line">    ...</span><br></pre></td></tr></table></figure><p>解释器扫描完这一段内容后，可以得到类名<code>class_name</code>、继承的基类<code>bases</code>以及类主体<code>class_body</code>三个内容：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">class_name=<span class="string">&#x27;Foo&#x27;</span></span><br><span class="line">bases=(<span class="built_in">object</span>,)</span><br><span class="line">class_body= \</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;\</span></span><br><span class="line"><span class="string">...</span></span><br><span class="line"><span class="string">def func(self):</span></span><br><span class="line"><span class="string">    pass</span></span><br><span class="line"><span class="string">...</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>然后在局部空间<code>class_dict={}</code>中执行类主体：<code>exec(class_body,globals(),class_dict)</code>，最后使用默认元类也就是<code>type</code>类创建类对象：<code>Foo=type(class_name,bases,class_dict)</code></p><p>除了使用默认的<code>type</code>类创建类对象，还可以继承<code>type</code>类，也就是自定义元类，通过重载<code>__new__()</code>或<code>__init__()</code>来进一步控制用户自定义类的定义内容（如果是修改类定义的话，应该在<code>__new__()</code>中类对象创建之前修改，如果是一些检查逻辑如类属性值是否合法等，则在类对象创建后再检查也不迟，即放在<code>__init__()</code>中），看个示例，已知有一个<code>factory</code>类，现要求其只能有三个属性，名称<code>name</code>、地址<code>location</code>以及业务<code>business</code>，其实就是添加一个类属性<code>__slots__</code>（注意类对象创建后，再添加类属性<code>__slots__</code>是没效果的，必须写在类定义中）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">MyMetaCls</span>(<span class="title class_ inherited__">type</span>): <span class="comment">#自定义元类</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__new__</span>(<span class="params">cls,class_name,bases,class_dict</span>):</span><br><span class="line">        class_dict[<span class="string">&#x27;__slots__&#x27;</span>]=[<span class="string">&#x27;name&#x27;</span>,<span class="string">&#x27;location&#x27;</span>,<span class="string">&#x27;business&#x27;</span>]</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">type</span>.__new__(cls,class_name,bases,class_dict)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">factory</span>(metaclass=MyMetaCls):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,name,location,business</span>):</span><br><span class="line">        self.name,self.location,self.business=name,location,business</span><br><span class="line">    </span><br><span class="line">f=factory(name=<span class="string">&#x27;中石化&#x27;</span>,location=<span class="string">&#x27;西北&#x27;</span>,business=<span class="string">&#x27;中国能源供给&#x27;</span>)</span><br><span class="line">f.xxx=<span class="string">&#x27;xxx&#x27;</span> <span class="comment">#AttributeError: &#x27;factory&#x27; object has no attribute &#x27;xxx&#x27;</span></span><br></pre></td></tr></table></figure><p>如上，要设置元类，只需要在基类元组中提供<code>metaclass</code>关键字参数，或者在类定义中指定<code>__metaclass__</code>属性。尽管使用元类可以显著改变用户定义的类的行为和语义，但在使用元类时，不应使类的工作方式和其文档描述相距甚远，这会使得用户对代码感到困惑</p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="属性访问控制">属性访问控制</h2><div class="tabs" id="sxfwkz"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#sxfwkz-1">静态方法与类方法</button></li><li class="tab"><button type="button" data-href="#sxfwkz-2"><code>&#64;property</code>特性</button></li><li class="tab"><button type="button" data-href="#sxfwkz-3">描述符</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="sxfwkz-1"><p>在类定义中，所有方法默认都是在实例上操作的，特点是总是存在一个名为<code>self</code>（当然名称可以自定义）的位置参数，在通过实例访问这些方法属性时，譬如<code>obj.method</code>（<code>obj</code>是某一类实例，<code>method</code>是类中定义的普通实例方法），python会利用“特性”（特殊属性）机制来进行访问控制，事实上，用户得到的不是原始函数对象<code>method</code>，而是会得到所谓的“绑定方法”，绑定方法类似于偏函数（<code>obj.method</code>返回的相当于是<code>partial(method,self=obj)</code>），其中<code>self</code>参数已经填入，保存在绑定方法的执行环境中，但是其他参数仍需在调用该（绑定）方法时提供（其实你也可以通过类调用实例方法，不过这时候你就需要手动传入实例对象了，如<code>cls.method(obj,...)</code>，<code>cls</code>为<code>obj</code>的所属类，省略号省略了方法可能存在的其他参数），这种绑定方法是由在后台执行的特性函数静默创建的，你还可以手动指定其他两种特性函数分别用于创建静态方法和类方法，静态方法是一种普通函数，但是位于类定义的命名空间中，要定义静态方法，可使用<code>@staticmethod</code>装饰器，譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Foo</span>:</span><br><span class="line"><span class="meta">    @staticmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">x,y</span>):</span><br><span class="line">        <span class="keyword">return</span> x+y</span><br></pre></td></tr></table></figure><p>不同于实例方法，静态方法属性访问返回的就是原始的函数对象而非绑定方法，且既可以通过类也可以通过实例来调用静态方法。如果在编写类时需要采用很多不同的方式来创建新实例，而类中只能由一个<code>__init__()</code>方法，可以使用静态方法，替代的创建函数通常按如下形式定义：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Date</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,year,month,day</span>):</span><br><span class="line">        self.year,self.month,self.day=year,month,day</span><br><span class="line">        </span><br><span class="line"><span class="meta">    @staticmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">now</span>():</span><br><span class="line">        t=time.localtime()</span><br><span class="line">        <span class="keyword">return</span> Date(t.tm_year,t.tm_mon,t.tm_mday)</span><br><span class="line">        </span><br><span class="line"><span class="meta">    @staticmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">tomorrow</span>():</span><br><span class="line">        t=time.localtime(time.time()+<span class="number">86400</span>)</span><br><span class="line">        <span class="keyword">return</span> Date(t.tm_year,t.tm_mon,t.tm_mday)</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="string">f&#x27;<span class="subst">&#123;self.year&#125;</span>-<span class="subst">&#123;self.month&#125;</span>-<span class="subst">&#123;self.day&#125;</span>&#x27;</span></span><br><span class="line">        </span><br><span class="line"><span class="built_in">print</span>(Date(<span class="number">1967</span>,<span class="number">4</span>,<span class="number">9</span>)) <span class="comment">#1967-4-9</span></span><br><span class="line"><span class="built_in">print</span>(Date.now()) <span class="comment">#2021-5-18</span></span><br><span class="line"><span class="built_in">print</span>(Date.tomorrow()) <span class="comment">#2021-5-19</span></span><br></pre></td></tr></table></figure><p>类方法是将类本身作为对象进行操作的方法，类方法使用<code>@classmethod</code>装饰器，与实例方法不同在于，类方法定义的第一个参数通常命名为<code>cls</code>，且将类本身作为第一个参数进行传递，譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Times</span>:</span><br><span class="line">    factor=<span class="number">1</span></span><br><span class="line"><span class="meta">    @classmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">mul</span>(<span class="params">cls,x</span>):</span><br><span class="line">        <span class="keyword">return</span> cls.factor*x</span><br><span class="line">        </span><br><span class="line"><span class="keyword">class</span> <span class="title class_">TwoTimes</span>(<span class="title class_ inherited__">Times</span>):</span><br><span class="line">    factor=<span class="number">2</span></span><br><span class="line">    </span><br><span class="line"><span class="built_in">print</span>(TwoTimes.mul(<span class="number">4</span>)) <span class="comment">#8</span></span><br></pre></td></tr></table></figure><p>类似于实例方法的属性访问，类方法属性访问同样返回绑定方法，因此上述示例中<code>TwoTimes.mul</code>返回的相当于<code>partial(mul,cls=TwoTimes)</code>，且类方法也能通过实例调用，譬如<code>t=TwoTimes();t.mul(4)</code>，其中<code>t.mul</code>返回的相当于<code>partial(mul,cls=t.__class__)</code></p><p>在之前的<code>Date</code>类示例中我们使用静态方法实现多个创建函数，假设有一个子类<code>EuroDate</code>继承它以输出欧洲日期格式，但是你会发现结果不符合预期：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">EuroDate</span>(<span class="title class_ inherited__">Date</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="string">f&#x27;<span class="subst">&#123;self.day:02d&#125;</span>/<span class="subst">&#123;self.month:02d&#125;</span>/<span class="subst">&#123;self.year&#125;</span>&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(EuroDate.now()) <span class="comment">#2021-5-18</span></span><br></pre></td></tr></table></figure><p>输出之所以还是旧格式，这是因为<code>EuroDate.now()</code>返回的是一个<code>Date</code>对象，应采用类方法实现创建函数来避免该错误：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Date</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,year,month,day</span>):</span><br><span class="line">        self.year,self.month,self.day=year,month,day</span><br><span class="line">        </span><br><span class="line"><span class="meta">    @classmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">now</span>(<span class="params">cls</span>):</span><br><span class="line">        t=time.localtime()</span><br><span class="line">        <span class="keyword">return</span> cls(t.tm_year,t.tm_mon,t.tm_mday)</span><br><span class="line">        </span><br><span class="line"><span class="meta">    @classmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">tomorrow</span>(<span class="params">cls</span>):</span><br><span class="line">        t=time.localtime(time.time()+<span class="number">86400</span>)</span><br><span class="line">        <span class="keyword">return</span> cls(t.tm_year,t.tm_mon,t.tm_mday)</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="string">f&#x27;<span class="subst">&#123;self.year&#125;</span>-<span class="subst">&#123;self.month&#125;</span>-<span class="subst">&#123;self.day&#125;</span>&#x27;</span></span><br><span class="line">        </span><br><span class="line"><span class="keyword">class</span> <span class="title class_">EuroDate</span>(<span class="title class_ inherited__">Date</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="string">f&#x27;<span class="subst">&#123;self.day:02d&#125;</span>/<span class="subst">&#123;self.month:02d&#125;</span>/<span class="subst">&#123;self.year&#125;</span>&#x27;</span></span><br><span class="line">        </span><br><span class="line"><span class="built_in">print</span>(EuroDate.now()) <span class="comment">#18/05/2021</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="sxfwkz-2"><p>通常，访问实例或类属性时，会返回所存储的相关值，由<code>@property</code>特性支持的属性，可以在访问时经过计算得到返回值，譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> math</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Circle</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,radius</span>):</span><br><span class="line">        self.radius=radius</span><br><span class="line">    </span><br><span class="line"><span class="meta">    @property</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">area</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> math.pi*self.radius**<span class="number">2</span></span><br><span class="line">        </span><br><span class="line"><span class="meta">    @property</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">perimeter</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="number">2</span>*math.pi*self.radius</span><br><span class="line">        </span><br><span class="line">c=Circle(<span class="number">4</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;半径：<span class="subst">&#123;c.radius&#125;</span>，周长：<span class="subst">&#123;c.perimeter&#125;</span>，面积：<span class="subst">&#123;c.area&#125;</span>&#x27;</span>) <span class="comment">#半径：4，周长：25.132741228718345，面积：50.26548245743669</span></span><br><span class="line"><span class="comment">#c.area=8 #AttributeError: can&#x27;t set attribute #当前area“属性”仅仅是只读的，除非设置setter方法，具体见下</span></span><br></pre></td></tr></table></figure><p>上述示例中，计算面积的<code>area()</code>实例方法和计算周长的<code>perimeter()</code>实例方法，通过装饰器<code>@property</code>修饰后，支持以简单属性的形式访问（不需要加<code>()</code>调用），用户很难发现正在“计算”一个属性，除非在试图重新定义该属性时生成了错误消息（<code>AttributeError</code>异常），这种特性使用方式遵循所谓的统一访问原则，你不需要费力了解何时添加额外的<code>()</code>所带来的不必要的混淆</p><p>事实上，该特性还可以拦截操作，以设置和删除属性，这是通过向特性附加<code>setter</code>和<code>deleter</code>操作来实现的，譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">student</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,name</span>):</span><br><span class="line">        self.name=name</span><br><span class="line">        </span><br><span class="line"><span class="meta">    @property</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">score</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> self.__score <span class="comment">#将值实际存储在其他名称中，通常是在加两个下划线前缀，即“私有属性”中，但是注意“私有属性”其实也直接暴露在外，而且易于辨识，你可以通过访问实例的__dict__看到它，可以定义__slots__来禁用__dict__，但是你依旧无法阻止通过setattr(...)的方式进行非法赋值</span></span><br><span class="line">        </span><br><span class="line"><span class="meta">    @score.setter</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">score</span>(<span class="params">self,score</span>):</span><br><span class="line">        <span class="keyword">if</span> score&gt;=<span class="number">0</span> <span class="keyword">and</span> score&lt;=<span class="number">100</span>:</span><br><span class="line">            self.__score=score</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">raise</span> ValueError(<span class="string">&#x27;score must between 0 ~ 100!&#x27;</span>)</span><br><span class="line"></span><br><span class="line">s=student(<span class="string">&#x27;zj&#x27;</span>)</span><br><span class="line">s.score=<span class="number">99</span> <span class="comment">#如果设置的数值大于100，将导致错误，因为我们利用特性进行了相关的访问控制</span></span><br><span class="line"><span class="built_in">print</span>(s.name,s.score) <span class="comment">#zj 99</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(s.__dict__) <span class="comment">#&#123;&#x27;name&#x27;: &#x27;zj&#x27;, &#x27;_student__score&#x27;: 99&#125;</span></span><br><span class="line"></span><br><span class="line">s.__sex=<span class="string">&#x27;female&#x27;</span> <span class="comment">#只有在类定义中绑定的以双下划线打头的实例属性被认为是“私有属性”并被倾轧，在类定义外动态绑定的则不会被认为是私有属性，也不会被倾轧</span></span><br><span class="line"><span class="built_in">print</span>(s.__dict__) <span class="comment">#&#123;&#x27;name&#x27;: &#x27;zj&#x27;, &#x27;_student__score&#x27;: 99, &#x27;__sex&#x27;: &#x27;female&#x27;&#125;</span></span><br></pre></td></tr></table></figure><p>在上述示例中，首先使用<code>@property</code>装饰器将相关方法<code>score()</code>转变成了只读属性，后面的<code>@score.setter</code>装饰器将其他方法与<code>score</code>属性上的设置操作相关联，这个“其他方法”的名称应该与原始特性的名称完全匹配</p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="sxfwkz-3"><p>使用<code>@property</code>特性后，对属性的访问将由一系列用户定义的get、set和delete函数控制，这种属性控制方式可以由“描述符”进一步推广，描述符就是一个表示属性值的对象，凡是实现<code>__get__()</code>、<code>__set__()</code>和<code>__delete__()</code>方法的就是描述符，注意描述符只能在类级别上进行实例化，当你通过实例访问一个描述符对象时，会自动调用描述符的<code>__get__()</code>、<code>__set__()</code>或<code>__delete__()</code>，并总是传入实例作为参数之一</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">movie</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,title,score,ratings</span>):</span><br><span class="line">        self.title=title</span><br><span class="line">        self.score=score</span><br><span class="line">        self.ratings=ratings</span><br><span class="line">        </span><br><span class="line"><span class="meta">    @property</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">score</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> self._score</span><br><span class="line">        </span><br><span class="line"><span class="meta">    @score.setter</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">score</span>(<span class="params">self,newValue</span>):</span><br><span class="line">        <span class="keyword">if</span> newValue&lt;<span class="number">0</span> <span class="keyword">or</span> newValue&gt;<span class="number">10</span>:</span><br><span class="line">            <span class="keyword">raise</span> ValueError(<span class="string">&quot;movie&#x27;s score can&#x27;t be negative or greater than 10&quot;</span>)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            self._score=newValue</span><br><span class="line">            </span><br><span class="line"><span class="meta">    @property</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">ratings</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> self._ratings</span><br><span class="line">        </span><br><span class="line"><span class="meta">    @ratings.setter</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">ratings</span>(<span class="params">self,newValue</span>):</span><br><span class="line">        <span class="keyword">if</span> newValue&lt;<span class="number">0</span> <span class="keyword">or</span> newValue&gt;<span class="number">10</span>:</span><br><span class="line">            <span class="keyword">raise</span> ValueError(<span class="string">&quot;movie&#x27;s ratings can&#x27;t be negative or greater than 10&quot;</span>)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            self._ratings=newValue</span><br><span class="line">            </span><br><span class="line">m=movie(<span class="string">&#x27;后天&#x27;</span>,<span class="number">7.5</span>,<span class="number">3</span>)</span><br></pre></td></tr></table></figure><p>上述示例中定义了一个通过<code>@property</code>进行属性访问控制的电影类，可以看到<code>score</code>和<code>ratings</code>两个属性拥有相同的访问控制，从而导致上述代码有较高的重复率，而描述符的访问控制可以被多个属性重复利用，需要注意的是你总是应该通过实例而非类名访问描述符，示例如下：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> weakref <span class="keyword">import</span> WeakKeyDictionary</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">descriptor</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,default</span>):</span><br><span class="line">        self.default=default</span><br><span class="line">        self.data=WeakKeyDictionary() <span class="comment">#由于描述符是定义在类层级的，因此对于类的所有实例都是可访问的，所以我们定义一个字典，存储类的所有实例及其属性值</span></span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__get__</span>(<span class="params">self,instance,owner</span>): <span class="comment">#在访问movie实例m的score属性时，会被解释器解释为m.__class__.score.__get__(m,m.__class__)</span></span><br><span class="line">        <span class="comment">#print(owner) #&lt;class &#x27;__main__.movie&#x27;&gt;</span></span><br><span class="line">        <span class="keyword">if</span> instance==<span class="literal">None</span>: <span class="comment">#如果通过类访问描述符，传入的实例将为None，此时返回描述符对象本身，该操作是通用操作，该设置允许我们能够获取到在类层级定义的描述符对象本身</span></span><br><span class="line">            <span class="keyword">return</span> self</span><br><span class="line">        <span class="keyword">return</span> self.data.get(instance,self.default)</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__set__</span>(<span class="params">self,instance,value</span>):</span><br><span class="line">        <span class="keyword">if</span> value&lt;<span class="number">0</span> <span class="keyword">or</span> value&gt;<span class="number">10</span>:</span><br><span class="line">            <span class="keyword">raise</span> ValueError(<span class="string">&quot;movie&#x27;s score or ratings can&#x27;t be negative or greater than 10&quot;</span>)</span><br><span class="line">        self.data[instance]=value</span><br><span class="line">        </span><br><span class="line"><span class="keyword">class</span> <span class="title class_">movie</span>:</span><br><span class="line">    score=descriptor(<span class="number">0</span>)</span><br><span class="line">    ratings=descriptor(<span class="number">0</span>)</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,title,score,ratings</span>):</span><br><span class="line">        self.title=title</span><br><span class="line">        self.score=score <span class="comment">#注意千万不能通过类名访问描述符对象，譬如movie.score=score，这将导致类的score属性从一个描述符对象转变为一个数值对象，因为这不会触发调用描述符的__set__()方法，不过print(movie.score)还是会触发调用描述符的__get__()方法的，只是此时传入__get__()的instance实例对象是None</span></span><br><span class="line">        self.ratings=ratings</span><br><span class="line"></span><br><span class="line">m1=movie(<span class="string">&#x27;后天&#x27;</span>,<span class="number">7.5</span>,<span class="number">3</span>)</span><br><span class="line"><span class="built_in">print</span>(m1.score,m1.ratings) <span class="comment">#7.5 3</span></span><br><span class="line"><span class="comment">#m2=movie(&#x27;后天&#x27;,7.5,-3) #ValueError: movie&#x27;s score or ratings can&#x27;t be negative or greater than 10</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#m1.score=-1 #ValueError: movie&#x27;s score or ratings can&#x27;t be negative or greater than 10</span></span><br><span class="line">movie.score.data[m1]=-<span class="number">1</span> <span class="comment">#在这种基于“实例-属性值”字典实现的描述符下其实你还是可以绕过描述符的访问控制实现非法赋值</span></span><br><span class="line"><span class="built_in">print</span>(m1.score) <span class="comment">#-1</span></span><br></pre></td></tr></table></figure><p>当访问实例属性的时候，<code>obj.x</code>总是调用<code>__getattribute__()</code>方法（因此你也可以通过重载<code>__getattributr__()</code>进行最简单的属性访问控制，在这种情况下，不要忘记调用父类的<code>__getattributr__()</code>方法以防属性查找失败，所以不太建议这么做），其行为是，1）检查类中是否有同名的数据描述符对象，如果有，则自动变形为<code>obj.__class__.__dict__['x'].__get__(obj,obj.__class__)</code>，否则，2）检查实例字典，即在实例的<code>__dict__</code>中查找，找到则返回，否则，3）检查类字典，即在<code>obj.__class__.__dict__</code>中查找，找到则返回，如果是同名的非数据描述符，则还会自动变形，否则，4）按照MRO顺序依次检查基类字典，如果还找不到，则检查<code>obj</code>所在类是否定义了<code>__getattr__()</code>方法，有则返回<code>__getattr__()</code>的调用结果，否则抛出<code>AttributeError</code><!-- https://www.cnblogs.com/hemengjita/p/12292548.html --></p><p>当访问实例属性并进行赋值的时候，<code>obj.x=value</code>总是调用<code>__setattr__()</code>方法，其行为是，1）如果类中有同名的数据描述符对象，则自动变形为<code>obj.__class__.__dict__['x'].__set__(obj,value)</code>，否则，2）在实例的字典<code>__dict__</code>中查找，有则修改相应的键值，没有则将属性<code>x</code>直接绑定在实例上，即<code>__dict__.update({'x':value})</code>（<code>del obj.x</code>语句将触发调用<code>__delattr__()</code>方法，和<code>obj.x=value</code>触发调用<code>__setattr__()</code>类似，只不过其默认行为是删除<code>obj</code>的<code>__dict__</code>中存储的键值，除非请求的属性正好是一个描述符对象，此时将会执行<code>obj.__class__.__dict__['x'].__delete__(obj)</code>，如果实例字典中没有该属性，则抛出<code>AttributeError</code>）</p><p>注：实现了<code>__set__()</code>和<code>__get__()</code>方法的描述符类被称为数据描述符，如果只实现了<code>__get__()</code>方法，则称为非数据描述符</p><p>上面的描述符示例中采用字典存储所有的实例和属性值，但如果实例是不可哈希对象呢，为此我们还可以直接将属性值绑定到实例（的<code>__dict__</code>）上面：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">descriptor</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,label,default</span>):</span><br><span class="line">        self.label=label</span><br><span class="line">        self.default=default</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__get__</span>(<span class="params">self,instance,owner</span>):</span><br><span class="line">        <span class="keyword">if</span> instance==<span class="literal">None</span>:</span><br><span class="line">            <span class="keyword">return</span> self</span><br><span class="line">        <span class="keyword">return</span> instance.__dict__.get(self.label,self.default)</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__set__</span>(<span class="params">self,instance,value</span>):</span><br><span class="line">        <span class="keyword">if</span> value&lt;<span class="number">0</span> <span class="keyword">or</span> value&gt;<span class="number">10</span>:</span><br><span class="line">            <span class="keyword">raise</span> ValueError(<span class="string">&quot;movie&#x27;s score or ratings can&#x27;t be negative or greater than 10&quot;</span>)</span><br><span class="line">        instance.__dict__[self.label]=value</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">movie</span>:</span><br><span class="line">    score=descriptor(<span class="string">&#x27;score&#x27;</span>,<span class="number">0</span>) <span class="comment">#不同名也行，但这就重蹈@property的覆辙了，譬如名称改为&#x27;_score&#x27;，此时通过“obj.score=非法值”自然会受到访问控制，但是“obj._score=非法值”则不受保护</span></span><br><span class="line">    ratings=descriptor(<span class="string">&#x27;ratings&#x27;</span>,<span class="number">0</span>)</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,title,score,ratings</span>):</span><br><span class="line">        self.title=title</span><br><span class="line">        self.score=score</span><br><span class="line">        self.ratings=ratings</span><br><span class="line"></span><br><span class="line">m1=movie(<span class="string">&#x27;后天&#x27;</span>,<span class="number">7.5</span>,<span class="number">3</span>)</span><br><span class="line"><span class="built_in">print</span>(m1.score,m1.ratings) <span class="comment">#7.5 3</span></span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    m1.score=-<span class="number">10</span></span><br><span class="line"><span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(e)</span><br><span class="line">    </span><br><span class="line"><span class="built_in">print</span>(m1.__dict__) <span class="comment">#&#123;&#x27;title&#x27;: &#x27;后天&#x27;, &#x27;score&#x27;: 7.5, &#x27;ratings&#x27;: 3&#125;</span></span><br><span class="line"></span><br><span class="line">m1.__dict__[<span class="string">&#x27;score&#x27;</span>]=-<span class="number">1000</span> <span class="comment">#在这种情况下你可以通过直接修改实例字典来绕过描述符的访问控制，唉，有完美的解决方案吗</span></span><br><span class="line"><span class="built_in">print</span>(m1.score) <span class="comment">#-1000</span></span><br></pre></td></tr></table></figure><p>上述在类层级定义描述符的时候需要手动传入属性名称字符串，<code>score=descriptor('score',0)</code>，这不太方便，为了隐藏该细节，可以借助元类，使得定义变回<code>score=descriptor(0)</code>这种简洁形式：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">descriptor</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,default,label=<span class="literal">None</span></span>): <span class="comment">#此处参数定义要稍稍修改</span></span><br><span class="line">        self.label=label</span><br><span class="line">        self.default=default</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__get__</span>(<span class="params">self,instance,owner</span>):</span><br><span class="line">        <span class="keyword">if</span> instance==<span class="literal">None</span>:</span><br><span class="line">            <span class="keyword">return</span> self</span><br><span class="line">        <span class="keyword">return</span> instance.__dict__.get(self.label,self.default)</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__set__</span>(<span class="params">self,instance,value</span>):</span><br><span class="line">        <span class="keyword">if</span> value&lt;<span class="number">0</span> <span class="keyword">or</span> value&gt;<span class="number">10</span>:</span><br><span class="line">            <span class="keyword">raise</span> ValueError(<span class="string">&quot;movie&#x27;s score or ratings can&#x27;t be negative or greater than 10&quot;</span>)</span><br><span class="line">        instance.__dict__[self.label]=value</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__delete__</span>(<span class="params">self,instance</span>): <span class="comment">#__delete__()不太常用，主要用来使实例（描述符）属性不可删除，但是你不能在__del__()方法中通过抛出异常阻止对象的删除</span></span><br><span class="line">        <span class="keyword">raise</span> AttributeError(<span class="string">&#x27;Can\&#x27;t delete this attribute!&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">addLabelMeta</span>(<span class="title class_ inherited__">type</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__new__</span>(<span class="params">cls,name,bases,local_dict</span>):</span><br><span class="line">        <span class="keyword">for</span> k,v <span class="keyword">in</span> local_dict.items():</span><br><span class="line">            <span class="keyword">if</span> <span class="built_in">isinstance</span>(v,descriptor):</span><br><span class="line">                v.label=k</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">super</span>(cls,cls).__new__(cls,name,bases,local_dict)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">movie</span>(metaclass=addLabelMeta):</span><br><span class="line">    score=descriptor(<span class="number">0</span>)</span><br><span class="line">    ratings=descriptor(<span class="number">0</span>)</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,title,score,ratings</span>):</span><br><span class="line">        self.title=title</span><br><span class="line">        self.score=score</span><br><span class="line">        self.ratings=ratings</span><br><span class="line"></span><br><span class="line">m1=movie(<span class="string">&#x27;后天&#x27;</span>,<span class="number">7.5</span>,<span class="number">3</span>)</span><br><span class="line"><span class="built_in">print</span>(m1.score,m1.ratings) <span class="comment">#7.5 3</span></span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    m1.score=-<span class="number">10</span></span><br><span class="line"><span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(e)</span><br><span class="line">    </span><br><span class="line"><span class="built_in">print</span>(m1.__dict__) <span class="comment">#&#123;&#x27;title&#x27;: &#x27;后天&#x27;, &#x27;score&#x27;: 7.5, &#x27;ratings&#x27;: 3&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    <span class="keyword">del</span> m1.score</span><br><span class="line"><span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(e)</span><br><span class="line">    </span><br><span class="line"><span class="built_in">print</span>(m1.score) <span class="comment">#7.5</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><p>未完待续…</p><div class="tip fas fa-quote-left"><p>[1] <a href="https://pan.baidu.com/s/17r__wNMxIXTMWhglf3wyuw" title="密码：1y2r" target="_blank"><span style="color:red">Python参考手册</span> 第4版 修订版 [美] 大卫·M.比兹利（David M.Beazley）著，谢俊，杨越，高伟 译</a><br>[2] <a href="https://segmentfault.com/a/1190000009157792" target="_blank">绑定方法与非绑定方法</a></p></div>]]></content>
      
      
      <categories>
          
          <category> 计算机基础 </category>
          
          <category> 编程语言 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> Python </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>Python基础 - 程序结构与函数编程</title>
      <link href="posts/176/"/>
      <url>posts/176/</url>
      
        <content type="html"><![CDATA[<div class="note green icon flat"><i class="note-icon fas fa-rocket"></i><p>📚 文档目录<br>🎃 <a href="/posts/5311/"><span style="color:#3a96dd">类型和对象</span></a> - 🎈 程序结构与函数编程 - 🎏 <a href="/posts/22901/"><span style="color:#3a96dd">面向对象编程</span></a></p></div><h2 id="程序结构与执行">程序结构与执行</h2><p>Python程序由一些语句序列组成，这些语句包括变量赋值、函数定义、类和模块导入等，加载源文件时，解释器始终顺序执行每条语句，直到再无语句可以执行，这种执行模式同样适用于作为主程序运行的文件和通过<code>import</code>加载的库文件</p><div class="tabs" id="py2-1"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#py2-1-1">条件语句</button></li><li class="tab"><button type="button" data-href="#py2-1-2">循环与迭代</button></li><li class="tab"><button type="button" data-href="#py2-1-3">异常</button></li><li class="tab"><button type="button" data-href="#py2-1-4">上下文管理器</button></li><li class="tab"><button type="button" data-href="#py2-1-5">断言</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="py2-1-1"><p>条件语句可由<code>if</code>以及可省的<code>elif</code>、<code>else</code>子句构成</p><p>在一些编程语言中存在<code>switch</code>语句，譬如C语言中实现成绩等级判断：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span>&#123;</span><br><span class="line">  <span class="type">int</span> a;</span><br><span class="line">  <span class="built_in">printf</span>(<span class="string">&quot;Input your score:&quot;</span>);</span><br><span class="line">  <span class="built_in">scanf</span>(<span class="string">&quot;%d&quot;</span>,&amp;a);</span><br><span class="line">  <span class="keyword">switch</span>(a/<span class="number">10</span>)&#123;</span><br><span class="line">    <span class="keyword">case</span> <span class="number">10</span>:</span><br><span class="line">    <span class="keyword">case</span> <span class="number">9</span>: <span class="built_in">printf</span>(<span class="string">&quot;\nA&quot;</span>); <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="number">8</span>: <span class="built_in">printf</span>(<span class="string">&quot;\nB&quot;</span>); <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="number">7</span>: <span class="built_in">printf</span>(<span class="string">&quot;\nC&quot;</span>); <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">default</span>:<span class="built_in">printf</span>(<span class="string">&quot;\nD&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>Python中没有<code>switch</code>关键字，可以通过以下方式替代<a href="http://www.zzvips.com/article/117299.html">实现</a>：</p><ol><li>利用字典实现：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">switch=&#123;</span><br><span class="line">    <span class="number">10</span>: <span class="string">&#x27;A&#x27;</span>, <span class="comment">#此处需重复定义内容</span></span><br><span class="line">     <span class="number">9</span>: <span class="string">&#x27;A&#x27;</span>,</span><br><span class="line">     <span class="number">8</span>: <span class="string">&#x27;B&#x27;</span>,</span><br><span class="line">     <span class="number">7</span>: <span class="string">&#x27;C&#x27;</span>,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">a=<span class="built_in">input</span>(<span class="string">&#x27;Input your score:&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(switch.get(<span class="built_in">int</span>(<span class="built_in">int</span>(a)/<span class="number">10</span>),<span class="string">&#x27;D&#x27;</span>))</span><br></pre></td></tr></table></figure></li><li>创建一个<code>switch</code>类来处理程序的流转：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">switch</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,value</span>):</span><br><span class="line">        self.value=value</span><br><span class="line">        self.fall=<span class="literal">False</span> <span class="comment">#如果case匹配，且没有break，则置为True，表示继续向下执行，且不论下面的case是否匹配</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__iter__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">yield</span> self.<span class="keyword">match</span> <span class="comment">#由于yield关键字，__iter__()方法变成一个生成器方法，当调用该方法时将返回一个生成器对象（而生成器又是迭代器，因此switch类实例是一个可迭代对象），此时__iter__()内部实际还未执行，直到调用生成器对象的__next__()方法，返回match函数对象</span></span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">match</span>(<span class="params">self,*args</span>): <span class="comment">#args只允许接收0或1个参数</span></span><br><span class="line">        <span class="keyword">if</span> self.fall <span class="keyword">or</span> <span class="keyword">not</span> args: <span class="comment">#如果fall为True，则返回True表示继续执行当前的case子句，或当前case子句没有匹配参数，则表示为default默认分支（请将default放在最后一行，但并无代码严格检查，此代码仅为demo展示）</span></span><br><span class="line">            <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line">        <span class="keyword">elif</span> args[<span class="number">0</span>]==self.value: <span class="comment">#匹配成功</span></span><br><span class="line">            self.fall=<span class="literal">True</span></span><br><span class="line">            <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line">        <span class="keyword">else</span>: <span class="comment">#匹配失败</span></span><br><span class="line">            <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line">        </span><br><span class="line">score=<span class="number">96</span></span><br><span class="line"><span class="keyword">for</span> <span class="keyword">case</span> <span class="keyword">in</span> switch(score//<span class="number">10</span>): <span class="comment">#这个for只迭代一次，case循环变量指向的就是match()函数对象</span></span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">case</span>(<span class="number">10</span>):</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">case</span>(<span class="number">9</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;A&#x27;</span>)</span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">case</span>(<span class="number">8</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;B&#x27;</span>)</span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">case</span>(<span class="number">7</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;C&#x27;</span>)</span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">case</span>(): <span class="comment">#default分支</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;D&#x27;</span>)</span><br></pre></td></tr></table></figure></li></ol><p>不过实在没必要，特别是上述第二种方式，过于词不达意，这种<code>for</code>循环的写法就很迷，但是好像也找不到更好的写法</p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="py2-1-2"><p>可以使用<code>while</code>（满足条件时不断循环直至条件不再满足）或<code>for</code>（遍历可迭代对象）实现循环，一般推荐使用<code>for</code>循环，如果想在迭代过程中同时获取下标索引，可以将可迭代对象<code>iterable</code>替换成<code>enumerate(iterable)</code>，其等同于<code>zip(range(len(iterable)),iterable)</code></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">a=<span class="number">10</span></span><br><span class="line"><span class="keyword">while</span> (a&gt;<span class="number">0</span>): <span class="comment">#while expression等同于while(expression)，即加不加括号都一样，expression表达式所得也是一个python对象嘛，而(obj)就并未变成一个元组对象，它仍是obj对象本身，有obj is (obj)成立，除非写成(obj,)，这才变成了一个长度为1的元组对象。括号常用于表达式中，用于界定不同运算的优先级别，最内层的括号中的子表达式最先运算，譬如：((a+b)*c)-2</span></span><br><span class="line">    a-=<span class="number">1</span></span><br><span class="line">    <span class="built_in">print</span>(a)</span><br><span class="line"><span class="built_in">print</span>() <span class="comment">#输出一个空行</span></span><br><span class="line"></span><br><span class="line">i=<span class="number">888</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>):</span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;i:<span class="subst">&#123;i&#125;</span>&#x27;</span>) <span class="comment">#注意输出的是i:9，因为迭代变量（i）的作用域并非for语句私有，即如果前面已经定义过一个相同名称的变量，它的值将被改写</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#迭代过程中同时获取下标索引</span></span><br><span class="line">a=<span class="string">&#x27;muggledy&#x27;</span></span><br><span class="line"><span class="keyword">for</span> index,element <span class="keyword">in</span> <span class="built_in">enumerate</span>(a):</span><br><span class="line">    <span class="built_in">print</span>(index,element)</span><br></pre></td></tr></table></figure><p>注（<code>for-else</code>语句）：<code>else</code>语句会在<code>for</code>循环结束之后执行，除非循环过程中遇到<code>break</code>（或者遇到其他意外如抛出异常，当然也不会执行到<code>else</code>语句），特别地，如果循环根本就没有开始（可迭代序列长度为0时），也会执行<code>else</code>语句，一般来说，<code>else</code>语句可以用于编写循环正常结束时的某些后续操作</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;demo1: for循环全部遍历结束&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> []:</span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;demo2: for循环全部遍历结束&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">    <span class="keyword">if</span> i==<span class="number">2</span>:</span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;demo3: for循环全部遍历结束&#x27;</span>)</span><br><span class="line">    </span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">demo1: for循环全部遍历结束</span></span><br><span class="line"><span class="string">demo2: for循环全部遍历结束</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="py2-1-3"><p>异常会中断正常的程序执行流，可以使用<code>raise exception([value])</code>来手动抛出异常（<code>exception</code>是异常类型，内置异常类型请查阅文献[1]-p70，<code>value</code>是一个与指定异常相关的可选参数，通常是一条自定义的错误消息，如果<code>raise</code>语句不带任何参数，则将会重复引发最近一次出现的异常，如果最近没有出现异常，则抛出运行时异常<code>RuntimeError: No active exception to reraise</code>），使用<code>try-except</code>（能够嵌套使用）可以捕捉异常，<code>except</code>语句中用于编写异常处理程序，其还有一个可选的修饰符<code>as var</code>，可以将捕捉到的异常实例赋给变量<code>var</code>，另外可以在一个<code>try</code>块后跟随多个<code>except</code>块以捕捉多种不同类型的异常，当然也可以在一个<code>except</code>中同时捕捉，这时你可以在<code>except</code>语句块内使用<code>isinstance</code>进行异常类型判断，示例：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#示例1</span></span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    <span class="keyword">raise</span></span><br><span class="line"><span class="keyword">except</span>: <span class="comment">#不带任何异常类型时将捕捉所有异常，也可以捕捉指定类型异常：except RuntimeError:</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;出现异常！&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">#示例2</span></span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    <span class="keyword">raise</span> RuntimeError(<span class="string">&#x27;运行错误啦！&#x27;</span>)</span><br><span class="line"><span class="keyword">except</span> Exception <span class="keyword">as</span> e: <span class="comment">#将异常实例赋值给变量e（Exception是所有非退出异常类型的基类，这样你就可以捕捉任意派生自Exception的异常类型）</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;异常:&#x27;</span>,e)</span><br><span class="line">    </span><br><span class="line"><span class="comment">#示例3（示例3和示例4都是不可执行的伪代码）</span></span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    do something may cause IOError, TypeError <span class="keyword">or</span> NameError...</span><br><span class="line"><span class="keyword">except</span> IOError <span class="keyword">as</span> e:</span><br><span class="line">    process IOError...</span><br><span class="line"><span class="keyword">except</span> TypeError <span class="keyword">as</span> e:</span><br><span class="line">    process TypeError...</span><br><span class="line"><span class="keyword">except</span> NameError <span class="keyword">as</span> e:</span><br><span class="line">    process NameError...</span><br><span class="line">    </span><br><span class="line"><span class="comment">#示例4（示例3的另一种写法）</span></span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    do something may cause IOError, TypeError <span class="keyword">or</span> NameError...</span><br><span class="line"><span class="keyword">except</span> (IOError,TypeError,NameError) <span class="keyword">as</span> e: <span class="comment">#注意括号不可省略</span></span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">isinstance</span>(e,IOError):</span><br><span class="line">        process IOError...</span><br><span class="line">    <span class="keyword">elif</span> <span class="built_in">isinstance</span>(e,TypeError):</span><br><span class="line">        process TypeError...</span><br><span class="line">    <span class="keyword">else</span> <span class="built_in">isinstance</span>(e,NameError):</span><br><span class="line">        process NameError...</span><br></pre></td></tr></table></figure><p><code>try-except</code>支持<code>else</code>子句（可省），但必须跟随在最后一个<code>except</code>子句后，如果<code>try</code>块中的内容并未引发异常，就会执行<code>else</code>子句中的代码（除非<code>try</code>块直接<code>return</code>返回了）。<code>try-except</code>还支持<code>finally</code>子句（可省），其必须写在最最后，无论<code>try</code>是否出现异常都会执行<code>finally</code>块中的内容（即使在<code>try</code>块、<code>except</code>块或<code>else</code>块中遇到<code>return</code>，也会执行<code>finally</code>块），且在<code>except</code>或<code>else</code>之后执行</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    f=<span class="built_in">open</span>(<span class="string">&#x27;foo.txt&#x27;</span>,<span class="string">&#x27;r&#x27;</span>)</span><br><span class="line"><span class="keyword">except</span> IOError <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;Fail to open!(<span class="subst">&#123;e&#125;</span>)&#x27;</span>)</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;Open successfully!&#x27;</span>)</span><br><span class="line"><span class="keyword">finally</span>: <span class="comment">#如果文件打开（f存在）则关闭之，否则什么也不做</span></span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        f.close()</span><br><span class="line">    <span class="keyword">except</span>:</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line">        </span><br><span class="line"><span class="comment">#小结：try-except是基本的异常捕获流程，else和finally则都是可选的，一般的执行顺序是：首先执行try中语句，如果没有异常，则跳转到else块，最后是finally块；如果try块中存在异常，则由except捕获异常，最后进入finally块</span></span><br></pre></td></tr></table></figure><p>关于异常捕捉中<code>return</code>返回值的问题，试想，如果<code>try</code>块中存在<code>return</code>语句，通常我们认为函数遇到<code>return</code>会立即返回，确实如此吗？如果存在<code>finally</code>块，那么其中的代码还会执行吗？具体看下面的例子：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#try-except-finally结构</span></span><br><span class="line"><span class="comment">#示例1</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">a</span>):</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        <span class="keyword">return</span> a+<span class="number">1</span> <span class="comment">#首先计算表达式a+1的值然后保存下来，暂不return，转而执行finally块，（由于finally中没有遇到return，于是）结束后会回到此处，return之前保存的表达式值</span></span><br><span class="line">    <span class="keyword">except</span>:</span><br><span class="line">        <span class="keyword">return</span> a-<span class="number">1</span></span><br><span class="line">    <span class="keyword">finally</span>:</span><br><span class="line">        a+=<span class="number">4</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;a=<span class="subst">&#123;a&#125;</span>&#x27;</span>)</span><br><span class="line">        </span><br><span class="line"><span class="built_in">print</span>(f(<span class="number">1</span>))</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">a=5</span></span><br><span class="line"><span class="string">2</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#示例2</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">a</span>):</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        <span class="keyword">return</span> a/<span class="number">0</span> <span class="comment">#出现除0异常，显然此return永远也不会执行，直接进入except块</span></span><br><span class="line">    <span class="keyword">except</span>:</span><br><span class="line">        <span class="keyword">return</span> a-<span class="number">1</span> <span class="comment">#计算表达式a-1的值，然后先保存下来，继续执行finally中的代码，（由于finally中没有遇到return，于是）结束后回到此处，return之前保存的表达式值</span></span><br><span class="line">    <span class="keyword">finally</span>:</span><br><span class="line">        a+=<span class="number">4</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;a=<span class="subst">&#123;a&#125;</span>&#x27;</span>)</span><br><span class="line">        </span><br><span class="line"><span class="built_in">print</span>(f(<span class="number">1</span>))</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">a=5</span></span><br><span class="line"><span class="string">0</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#示例3</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">a</span>):</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        <span class="keyword">return</span> a+<span class="number">1</span> <span class="comment">#首先计算表达式a+1的值然后保存下来，暂不return，转而执行finally块</span></span><br><span class="line">    <span class="keyword">except</span>:</span><br><span class="line">        <span class="keyword">return</span> a-<span class="number">1</span></span><br><span class="line">    <span class="keyword">finally</span>:</span><br><span class="line">        a+=<span class="number">4</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;a=<span class="subst">&#123;a&#125;</span>&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> a <span class="comment">#在finally中遇到return，那就不管了，函数直接返回，OVER</span></span><br><span class="line">        </span><br><span class="line"><span class="built_in">print</span>(f(<span class="number">1</span>))</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">a=5</span></span><br><span class="line"><span class="string">5</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#try-except-else-finally结构</span></span><br><span class="line"><span class="comment">#示例4</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">a</span>):</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        <span class="keyword">return</span> a+<span class="number">1</span> <span class="comment">#首先计算表达式a+1的值然后保存下来，暂不return，但因为return的存在，虽然没有异常也不会执行else块，但是finally必须执行，（由于finally中没有遇到return，于是）结束后仍回到此处，return之前保存下来的a+1的值，OVER</span></span><br><span class="line">    <span class="keyword">except</span>:</span><br><span class="line">        <span class="keyword">return</span> a-<span class="number">1</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">return</span> a+<span class="number">2</span></span><br><span class="line">    <span class="keyword">finally</span>:</span><br><span class="line">        a+=<span class="number">4</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;a=<span class="subst">&#123;a&#125;</span>&#x27;</span>)</span><br><span class="line">        </span><br><span class="line"><span class="built_in">print</span>(f(<span class="number">1</span>))</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">a=5</span></span><br><span class="line"><span class="string">2</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#示例5</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">a</span>):</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        a+<span class="number">1</span></span><br><span class="line">    <span class="keyword">except</span>:</span><br><span class="line">        <span class="keyword">return</span> a-<span class="number">1</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">return</span> a+<span class="number">2</span> <span class="comment">#try中没有异常和return，于是执行else块，首先保存下表达式a+2的值，然后进入finally，（由于finally中没有遇到return，于是）结束后仍回到此处，return之前保存下来的值，OVER</span></span><br><span class="line">    <span class="keyword">finally</span>:</span><br><span class="line">        a+=<span class="number">4</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;a=<span class="subst">&#123;a&#125;</span>&#x27;</span>)</span><br><span class="line">        </span><br><span class="line"><span class="built_in">print</span>(f(<span class="number">1</span>))</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">a=5</span></span><br><span class="line"><span class="string">3</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#示例6</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">a</span>):</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        a+<span class="number">1</span></span><br><span class="line">    <span class="keyword">except</span>:</span><br><span class="line">        <span class="keyword">return</span> a-<span class="number">1</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">return</span> a+<span class="number">2</span> <span class="comment">#try中没有异常和return，于是跳转到else块，（由于finally的存在）首先保存下表达式a+2的值，然后进入finally</span></span><br><span class="line">    <span class="keyword">finally</span>:</span><br><span class="line">        a+=<span class="number">4</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;a=<span class="subst">&#123;a&#125;</span>&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> a <span class="comment">#finally中有return，于是不会再回到else块中的return位置处，此时函数直接返回，OVER</span></span><br><span class="line">        </span><br><span class="line"><span class="built_in">print</span>(f(<span class="number">1</span>))</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">a=5</span></span><br><span class="line"><span class="string">5</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>要自定义异常类型，需继承<code>Exception</code>基类，引发异常时传递的参数即是<code>__init__()</code>构造函数的参数，可以重载<code>__str__()</code>方法，以自定义异常输出的错误消息，示例：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">myException</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,*args</span>): <span class="comment">#可以接收n个（任意个）错误信息</span></span><br><span class="line">        self.args=args</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="string">f&quot;myException: <span class="subst">&#123;<span class="string">&#x27;,&#x27;</span>.join(<span class="built_in">map</span>(<span class="keyword">lambda</span> i:<span class="built_in">str</span>(i),self.args))&#125;</span>&quot;</span></span><br><span class="line">        </span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    <span class="keyword">raise</span> myException(<span class="string">&#x27;错误信息1&#x27;</span>,<span class="string">&#x27;错误信息2&#x27;</span>,<span class="number">8848</span>)</span><br><span class="line"><span class="keyword">except</span> myException <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(e)</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="py2-1-4"><p>正确地管理各种资源（如文件句柄的获取与关闭、互斥锁的获取与释放和数据库的连接与断开等），在涉及异常时通常都比较棘手，异常的引发很可能导致控制流跳过负责释放某些关键资源的语句，<code>with</code>语句支持在由上下文管理器对象控制的运行时上下文中执行一系列语句，譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#此种写法可以确保文件资源被安全释放</span></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;debuglog.txt&#x27;</span>,<span class="string">&#x27;a&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">    f.write(<span class="string">&#x27;Debugging\n&#x27;</span>)</span><br><span class="line">    ...</span><br><span class="line">    f.write(<span class="string">&#x27;Done\n&#x27;</span>)</span><br><span class="line"><span class="comment">#在控制流离开with语句块时会自动执行文件关闭的操作，不论with语句块中是否引发异常</span></span><br></pre></td></tr></table></figure><p><code>with obj</code>语句在控制流进入和离开其后的相关代码块时，允许（上下文管理器）对象<code>obj</code>管理所发生的的事情，执行<code>with obj</code>语句时，将执行<code>obj.__enter__()</code>来指示进入一个新的上下文，当控制流离开该上下文时，就会执行<code>obj.__exit__(type,value,traceback)</code>，如果没有引发异常，<code>__exit__()</code>方法的三个参数均被设为<code>None</code>，否则，它们将包含导致控制流离开上下文的异常相关的类型、值和跟踪信息，<code>__exit__()</code>方法返回<code>True</code>或<code>False</code>，用于指示被引发的异常是否得到处理，如果返回<code>False</code>，引发的任何异常都将被继续向外抛出。<code>with obj</code>语句接受一个可选的<code>as var</code>修饰符，此时<code>obj.__enter__()</code>方法的返回值将被赋给变量<code>var</code></p><p>自定义一个上下文管理器的伪代码示例如下：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">contextor</span>: <span class="comment">#类实现的“上下文管理器”</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,*args,**kwargs</span>):</span><br><span class="line">        <span class="comment">#初始化上下文管理器</span></span><br><span class="line">        ...</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__enter__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="comment">#可以是获取资源等操作</span></span><br><span class="line">        ...</span><br><span class="line">        <span class="keyword">return</span> something <span class="comment">#返回值将赋给with的as从句所定义的变量var</span></span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__exit__</span>(<span class="params">self, <span class="built_in">type</span>, value, traceback</span>):</span><br><span class="line">        <span class="comment">#可以是释放资源等操作</span></span><br><span class="line">        ...</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">True</span> <span class="keyword">or</span> <span class="literal">False</span> <span class="comment">#是否向with语句块外抛出异常</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> contextor(*args,**kwargs) <span class="keyword">as</span> var:</span><br><span class="line">    <span class="comment">#with语句块</span></span><br><span class="line">    ...</span><br></pre></td></tr></table></figure><p>还有一种定义上下文管理器的方式，借助<code>contextlib</code>模块的<code>contextmanager</code>装饰器实现，伪代码示例如下：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> contextlib <span class="keyword">import</span> contextmanager</span><br><span class="line"></span><br><span class="line"><span class="meta">@contextmanager</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">contextor</span>(<span class="params">*args,**kwargs</span>): <span class="comment">#函数版本的“上下文管理器”</span></span><br><span class="line">    <span class="comment">#语句块1</span></span><br><span class="line">    ...</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        <span class="keyword">yield</span> expression</span><br><span class="line">    <span class="keyword">except</span>:</span><br><span class="line">        <span class="comment">#捕捉with语句块内可能发生的异常，如果不捕捉，将被抛给with的外层，这也意味着语句块2（等同于上下文管理器的__exit__()方法代码）不会执行，这与上下文管理器的精神相违背（即不论with语句块内是否引发异常，__exit__()方法都会执行），因此一般都要在yield位置捕捉可能的异常</span></span><br><span class="line">        <span class="comment">#2023.5.2 update: 由于支持try...finally写法，因此可以选择外抛异常同时确保语句块2的执行，即将语句块2写在finally中</span></span><br><span class="line">        ...</span><br><span class="line">    <span class="comment">#语句块2</span></span><br><span class="line">    ...</span><br><span class="line">    </span><br><span class="line"><span class="keyword">with</span> contextor(*args,**kwargs) <span class="keyword">as</span> var:</span><br><span class="line">    <span class="comment">#with语句块</span></span><br><span class="line">    ...</span><br></pre></td></tr></table></figure><p><code>contextmanager</code>装饰器的原理很简单，其实现依赖于一个名为<code>_GeneratorContextManager</code>的类，这是一个定义了<code>__enter__()</code>和<code>__exit__()</code>方法的上下文管理器类型，而被装饰的函数<code>contextor</code>是一个生成器函数，根据装饰器原理有<code>contextor=contextmanager(contextor)</code>，返回的是一个闭包函数对象，其包含有一个指向真实<code>contextor</code>函数地址的变量，姑且记作<code>func</code>，当你调用<code>contextor(*args,**kwargs)</code>时将使用<code>args</code>、<code>kwargs</code>和<code>func</code>来初始化构造一个<code>_GeneratorContextManager</code>类实例，姑且记作<code>c</code>，具体的，在其初始化函数<code>__init__()</code>中会执行<code>func(*args,**keargs)</code>得到一个生成器对象，并保存为实例属性，姑且记作<code>c.g</code>，配合<code>with</code>使用时（<code>with contextor(*args,**kwargs) as var</code>），将自动调用<code>c</code>的<code>__enter__()</code>方法，而<code>__enter__()</code>的实现即是执行<code>return c.g.__next__()</code>，换句话说，上述生成器函数中<code>yield</code>之前的语句块1将作为上下文管理器的<code>__enter__()</code>方法定义，且<code>yield</code>表达式值将赋给变量<code>var</code>，当离开<code>with</code>语句块，将自动调用<code>c</code>的<code>__exit__()</code>方法，而<code>__exit__()</code>的实现即是再一次调用<code>c.g.__next__()</code>，换句话说，<code>yield</code>之后的语句块2将作为上下文管理器的<code>__exit__()</code>方法定义，另外，由于<code>with</code>语句块内部可能引发异常，异常将被<code>c</code>的<code>__exit__()</code>方法接收，默认下<code>c.__exit__()</code>返回<code>False</code>，即异常将被抛给<code>with</code>的外层，如果你不想抛出异常，则需要在上述生成器函数的<code>yield</code>位置处捕捉，因为<code>c.__exit__()</code>中会在存在异常的情况下，调用生成器对象的<code>throw()</code>方法，具体的，执行<code>c.g.throw(type,value,traceback)</code>，该方法会在<code>yield</code>位置处抛出参数所指异常，如果你手动捕捉了异常，程序会继续向下执行一次生成器的<code>next()</code>方法，即执行语句块2，否则意味着用户定义的上下文管理器的退出方法不会被调用，这一点千万注意。不管何种情况，我们总是应该将语句块2写在finally中，并通过是否写except来决定是否将异常抛到with语句块外</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#示例1（来自文献[1]-p73）</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ListTransaction</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,thelist</span>):</span><br><span class="line">        self.thelist=thelist</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__enter__</span>(<span class="params">self</span>):</span><br><span class="line">        self.workingcopy=<span class="built_in">list</span>(self.thelist)</span><br><span class="line">        <span class="keyword">return</span> self.workingcopy</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__exit__</span>(<span class="params">self,<span class="built_in">type</span>,value,tb</span>):</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">type</span> <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line">            self.thelist[:]=self.workingcopy</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">True</span> <span class="comment">#返回True，避免with语句块内的异常继续向上抛给外层</span></span><br><span class="line">        </span><br><span class="line">items=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line"><span class="keyword">with</span> ListTransaction(items) <span class="keyword">as</span> working:</span><br><span class="line">    working.append(<span class="number">6</span>)</span><br><span class="line">    working.append(<span class="number">7</span>)</span><br><span class="line">    <span class="comment">#raise ValueError(&#x27;xxx&#x27;)</span></span><br><span class="line"><span class="built_in">print</span>(items) <span class="comment">#[1, 2, 3, 6, 7]，如果上一行注释取消，则输出[1, 2, 3]</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#示例2</span></span><br><span class="line"><span class="keyword">from</span> contextlib <span class="keyword">import</span> contextmanager</span><br><span class="line"><span class="meta">@contextmanager</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">ListTransaction</span>(<span class="params">thelist</span>):</span><br><span class="line">    workingcopy=<span class="built_in">list</span>(thelist)</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        <span class="keyword">yield</span> workingcopy</span><br><span class="line">    <span class="keyword">except</span> ValueError <span class="keyword">as</span> e:</span><br><span class="line">        <span class="built_in">print</span>(e)</span><br><span class="line">    thelist[:]=workingcopy</span><br><span class="line">    </span><br><span class="line">items=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line"><span class="keyword">with</span> ListTransaction(items) <span class="keyword">as</span> working:</span><br><span class="line">    working.append(<span class="number">6</span>)</span><br><span class="line">    working.append(<span class="number">7</span>)</span><br><span class="line">    <span class="keyword">raise</span> ValueError(<span class="string">&#x27;xxx&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(items)</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">xxx</span></span><br><span class="line"><span class="string">[1, 2, 3, 6, 7]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#示例3</span></span><br><span class="line"><span class="keyword">from</span> contextlib <span class="keyword">import</span> contextmanager</span><br><span class="line"><span class="meta">@contextmanager</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">ListTransaction</span>(<span class="params">thelist</span>):</span><br><span class="line">    workingcopy=<span class="built_in">list</span>(thelist)</span><br><span class="line">    <span class="keyword">yield</span> workingcopy <span class="comment">#对比示例2，如果不在yield位置处捕捉异常，当with语句块中引发异常时候，yield后面的代码将不会被执行（该部分代码是作为上下文管理器的__exit__()方法定义）</span></span><br><span class="line">    thelist[:]=workingcopy</span><br><span class="line">    </span><br><span class="line">items=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    <span class="keyword">with</span> ListTransaction(items) <span class="keyword">as</span> working:</span><br><span class="line">        working.append(<span class="number">6</span>)</span><br><span class="line">        working.append(<span class="number">7</span>)</span><br><span class="line">        <span class="keyword">raise</span> ValueError(<span class="string">&#x27;xxx&#x27;</span>)</span><br><span class="line"><span class="keyword">except</span> ValueError <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(e)</span><br><span class="line"><span class="built_in">print</span>(items)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">xxx</span></span><br><span class="line"><span class="string">[1, 2, 3]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#示例4（2023.5.2 update）</span></span><br><span class="line"><span class="keyword">from</span> contextlib <span class="keyword">import</span> contextmanager</span><br><span class="line"><span class="meta">@contextmanager</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">ListTransaction</span>(<span class="params">thelist</span>):</span><br><span class="line">    workingcopy=<span class="built_in">list</span>(thelist)</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        <span class="keyword">yield</span> workingcopy <span class="comment">#对比示例3，虽然没有except捕捉异常，但是finally确保了thelist[:]=workingcopy的执行</span></span><br><span class="line">    <span class="keyword">finally</span>:</span><br><span class="line">        thelist[:]=workingcopy</span><br><span class="line"></span><br><span class="line">items=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    <span class="keyword">with</span> ListTransaction(items) <span class="keyword">as</span> working:</span><br><span class="line">        working.append(<span class="number">6</span>)</span><br><span class="line">        working.append(<span class="number">7</span>)</span><br><span class="line">        <span class="keyword">raise</span> ValueError(<span class="string">&#x27;xxx&#x27;</span>)</span><br><span class="line"><span class="keyword">except</span> ValueError <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(e)</span><br><span class="line"><span class="built_in">print</span>(items)</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">xxx</span></span><br><span class="line"><span class="string">[1, 2, 3, 6, 7]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="py2-1-5"><p>一般格式为<code>assert expression[, msg]</code>，其中<code>expression</code>为<code>False</code>时，将触发<code>AssertionError</code>异常，<code>msg</code>是可选的自定义错误消息，注意<code>assert</code>不应用于必须执行以确保程序正确的代码，因为如果python运行在最优模式（通过对解释器使用<code>-O</code>选项进入该模式），断言语句将不会执行，那么何时使用<code>assert</code>呢？<code>assert</code>语句用于检查应该始终为真的内容</p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="函数式编程">函数式编程</h2><div class="tabs" id="py2-2"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#py2-2-1">函数</button></li><li class="tab"><button type="button" data-href="#py2-2-2">装饰器</button></li><li class="tab"><button type="button" data-href="#py2-2-3">偏函数</button></li><li class="tab"><button type="button" data-href="#py2-2-4"><code>yield</code>表达式与协程</button></li><li class="tab"><button type="button" data-href="#py2-2-5">生成式</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="py2-2-1"><p>函数定义使用<code>def</code>关键字（另外可以使用<code>lambda</code>关键字创建表达式形式的匿名函数，形如<code>lambda *args, **kwargs : expression</code>），通常函数的第一条语句会使用文档字符串来描述函数的用途，可以在查看函数帮助时获取到该文档（<code>help(func)</code>），譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>():</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;This is a demo.</span></span><br><span class="line"><span class="string">       Author: muggledy</span></span><br><span class="line"><span class="string">    &#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">help</span>(f))</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">Help on function f in module __main__:</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">f()</span></span><br><span class="line"><span class="string">    This is a demo.</span></span><br><span class="line"><span class="string">    Author: muggledy</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>函数作为对象也具有属性，譬如上述文档字符串就存储于函数对象的<code>__doc__</code>属性中，函数名存储在<code>__name__</code>属性中，事实上，可以给函数对象绑定任意属性，这些新增属性保存在函数对象的<code>__dict__</code>属性中，要查看对象的所有属性，则使用<code>dir(obj)</code>函数，或者通过<code>getattr(obj,attr)</code>获取对象的指定属性（另<code>hasattr(obj,attr)</code>检查对象是否具有名为<code>attr</code>的属性，<code>setattr(obj,attr,value)</code>为对象设置属性），函数都是可调用的（<code>callable(func)</code>返回<code>True</code>）</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">class</span> <span class="title class_">A</span>: <span class="keyword">pass</span></span><br><span class="line">...</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=A()</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">setattr</span>(a,<span class="string">&#x27;can\&#x27;t be touched&#x27;</span>,<span class="string">&#x27;zj&#x27;</span>) <span class="comment">#setattr()相当逆天，你可以通过该方法为对象设置一些不能够通过属性访问符.号访问的属性</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.__dict__</span><br><span class="line">&#123;<span class="string">&quot;can&#x27;t be touched&quot;</span>: <span class="string">&#x27;zj&#x27;</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.can<span class="string">&#x27;t be touched</span></span><br><span class="line"><span class="string">  File &quot;&lt;stdin&gt;&quot;, line 1</span></span><br><span class="line"><span class="string">    a.can&#x27;</span>t be touched</span><br><span class="line">                     ^</span><br><span class="line">SyntaxError: EOL <span class="keyword">while</span> scanning string literal</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">getattr</span>(a,<span class="string">&#x27;can\&#x27;t be touched&#x27;</span>)</span><br><span class="line"><span class="string">&#x27;zj&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">hasattr</span>(a,<span class="string">&#x27;can\&#x27;t be touched&#x27;</span>)</span><br><span class="line"><span class="literal">True</span></span><br></pre></td></tr></table></figure><p>要调用函数，只要使用函数名加上用圆括号括起来的参数即可（函数名和括号之间允许有空格），python中函数传参的形式主要有五种，分别为位置传递、关键字传递、默认传递、包裹传递和解包裹传递（后两种在前一章节已经说过了，就不重复了），看示例：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#位置传递</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>(<span class="params">x,y,z</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;x&#125;</span>+<span class="subst">&#123;y&#125;</span>+<span class="subst">&#123;z&#125;</span>=<span class="subst">&#123;x+y+z&#125;</span>&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">f1(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>) <span class="comment">#1+2+3=6 #即不具名传递，仅凭位置上的一一对应</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#关键字传递</span></span><br><span class="line">f1(<span class="number">4</span>,z=<span class="number">6</span>,y=<span class="number">5</span>) <span class="comment">#给所传递的参数值具名的一种传递方式，明确告诉某一参数值是交由函数的哪一个参数变量接收的，如此我们就不需要按照位置参数的固定位置序号排列，可以在函数定义中定义命名关键字参数或者可变字典参数，这两种参数都必须以键值对形式传递，见后</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#默认传递</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">x,y,z=<span class="number">6</span></span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;x&#125;</span>+<span class="subst">&#123;y&#125;</span>+<span class="subst">&#123;z&#125;</span>=<span class="subst">&#123;x+y+z&#125;</span>&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">f2(<span class="number">2</span>,<span class="number">3</span>) <span class="comment">#默认参数传递即隐式传递，具有默认值的参数在函数调用时可以不明确给出</span></span><br></pre></td></tr></table></figure><p>若按照参数类型划分，则可分为位置参数、默认参数、可变参数和命名关键字参数，其中默认参数又分为默认位置参数和默认关键字参数（且只有命名关键字参数可以有默认值，其他关键字参数没有或者说没法设置默认值），可变（长）参数又分为可变元组参数和可变关键字参数（或可变字典参数），这里只单说一下“命名关键字参数”，函数参数定义中位于<code>*</code>或<code>*args</code>（可变元组参数）之后以及可变关键字参数之前（假设存在的话）的就是命名关键字参数，在调用时其必须具名传递，命名关键字参数可以有默认值，也可以没有，譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">x,*,y=<span class="number">1</span>,z</span>): <span class="comment">#x为位置参数，y和z是命名关键字参数，前者有默认值</span></span><br><span class="line">    <span class="built_in">print</span>(x,y,z)</span><br><span class="line"></span><br><span class="line">f3(<span class="number">1</span>,z=<span class="number">3</span>) <span class="comment">#如果调用f3(1,1,3)将报错TypeError: f3() takes 1 positional argument but 3 were given</span></span><br></pre></td></tr></table></figure><p>不同类型参数的组合使用（定义和调用时注意顺序，基本原则是，位置参数在前，关键字参数在后）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#示例1</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">a,b,c=<span class="number">3</span>,*args</span>): <span class="comment">#位置参数+带默认值的位置参数+可变元组参数</span></span><br><span class="line">    <span class="built_in">print</span>(a,b,c,*args)</span><br><span class="line">    </span><br><span class="line">f(<span class="number">1</span>,<span class="number">2</span>,c=<span class="number">3</span>) <span class="comment">#1 2 3</span></span><br><span class="line">f(a=<span class="number">1</span>,b=<span class="number">2</span>,c=<span class="number">3</span>) <span class="comment">#1 2 3</span></span><br><span class="line"><span class="comment">#f(a=3,b=2,c=1,0) #SyntaxError: positional argument follows keyword argument</span></span><br><span class="line">f(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>) <span class="comment">#1 2 3 4 5 6 7</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#示例2</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">a,b,*,x,y,**kwargs</span>): <span class="comment">#位置参数+命名关键字参数+可变字典参数</span></span><br><span class="line">    <span class="built_in">print</span>(a,b,x,y,kwargs)</span><br><span class="line">    </span><br><span class="line">f(<span class="number">1</span>,<span class="number">2</span>,x=<span class="number">3</span>,y=<span class="number">4</span>,z=<span class="number">5</span>) <span class="comment">#1 2 3 4 &#123;&#x27;z&#x27;: 5&#125;</span></span><br><span class="line"><span class="comment">#f(1,2,x=3,z=4) #TypeError: f() missing 1 required keyword-only argument: &#x27;y&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#示例3</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">a,b,c=<span class="number">3</span>,*args,x=<span class="number">4</span>,y,**kwargs</span>): <span class="comment">#最全组合：位置参数+带默认值的位置参数+可变元组参数+（带默认值的，可带可不带）命名关键字参数+可变关键字参数</span></span><br><span class="line">    <span class="built_in">print</span>(a,b,c,args,x,y,kwargs)</span><br><span class="line">    </span><br><span class="line">f(<span class="number">1</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">3</span>,x=<span class="number">5</span>,y=<span class="number">6</span>,z=<span class="number">7</span>) <span class="comment">#1 2 4 (3,) 5 6 &#123;&#x27;z&#x27;: 7&#125;</span></span><br><span class="line">f(<span class="number">1</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">3</span>,y=<span class="number">6</span>,z=<span class="number">7</span>) <span class="comment">#1 2 4 (3,) 4 6 &#123;&#x27;z&#x27;: 7&#125;</span></span><br><span class="line"><span class="comment">#f(b=2,a=1,3,4,y=6,x=5,z=7) #SyntaxError: positional argument follows keyword argument</span></span><br></pre></td></tr></table></figure><p>在编程时，尽量避免传递可变对象（如列表、字典等），因为在函数内部对可变对象的修改将反映在原始对象中，若无法避免，则应在函数中使用可变对象的拷贝，另外函数可以不显式写<code>return</code>语句，在运行结束时候，会默认返回<code>None</code></p><p>关于函数的作用域问题（<code>lambda</code>表达式遵循与函数相同的作用域规则），python中只有函数、类、模块会产生作用域（在作用域内定义的变量仅此作用域可见，但注意不同的作用域可能是包含关系，如全局作用域的范围包含局部作用域，全局作用域定义的变量在局部作用域也可访问），代码块不会产生作用域（如<code>for</code>循环变量会直接覆写外部的同名变量，或者说<code>for</code>循环变量可以在外部使用，而不仅限于<code>for</code>循环内部），每执行一个函数，就会创建新的局部命名空间，包含了函数参数名称和在函数体内定义的变量名称，在函数内访问变量首先会在局部空间中查找，找不到再去全局空间查找，具体的，python中有四种作用域：Local（局部作用域）、Enclosing（嵌套作用域）、Global（全局作用域）、Built-in（内置作用域），且变量的查找遵循“LEGB”规则，以内层嵌套函数为例，其首先搜索自己的局部命名空间，没有找到将由内而外在外层函数的局部命名空间中一层层地寻找（因为可以多层函数嵌套），仍没有找到，才会到全局命名空间和内置命名空间查找，如果还没有，则引发<code>NameError</code>异常</p><!-- 所谓作用域，即是在该区域范围之内定义的变量是随处可访问的（当然是要在变量定义后面的区域），或者称作用域为变量的可见区域（如函数的局部作用域，即函数内部定义的变量仅函数内部可见，函数外不可见）。嵌套作用域，指的是嵌套函数的外层函数中所定义的变量空间，为什么要单拎出来，虽然嵌套作用域和外层函数的局部作用域感觉没什么差别，但是嵌套作用域空间的生命周期和外层函数局部空间是不一样的，局部空间生命周期随函数调用产生的栈帧的产生和消亡，而嵌套作用域空间将作为嵌套函数的执行环境和嵌套函数打包在一起，即__closure__属性 --><p>可以在函数内部使用<code>global</code>关键字将（局部）变量动态声明为全局变量，使其位于全局命名空间，影响全局作用域，如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>():</span><br><span class="line">    <span class="keyword">global</span> x <span class="comment">#global语句可以放在函数内任意行或重复使用</span></span><br><span class="line">    x=<span class="number">8</span> <span class="comment">#如果外层已经存在此变量，则函数内部的修改将体现在外层空间</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;局部命名空间:&#x27;</span>,<span class="built_in">locals</span>()) <span class="comment">#空，此函数未创建任何局部变量</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;全局命名空间:&#x27;</span>,<span class="built_in">globals</span>()) <span class="comment">#上面创建的变量x位于全局命名空间</span></span><br><span class="line"></span><br><span class="line">f()</span><br><span class="line"><span class="built_in">print</span>(x) <span class="comment">#8</span></span><br></pre></td></tr></table></figure><p>类似的，对于嵌套函数，尽管它可以访问到嵌套作用域中的变量，一旦尝试对其执行如赋值等操作（如果是可变对象，则可以修改之，且无需声明<code>nonlocal</code>），实际会在嵌套函数的局部命名空间中新建一个同名变量，python3提供了<code>nonlocal</code>关键字，该声明会将名称动态绑定为外层函数中首次访问到的同名变量（多层嵌套时，可能多个外层函数都定义了同一变量，具体绑定哪个就看谁最靠内最先被访问到），于是可以在嵌套函数中修改并体现在外层，譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>():</span><br><span class="line">    i=<span class="number">4</span></span><br><span class="line">    j=<span class="number">7</span></span><br><span class="line">    k=<span class="number">13</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">inner1</span>():</span><br><span class="line">        <span class="keyword">nonlocal</span> i</span><br><span class="line">        j=<span class="number">70</span></span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">inner2</span>():</span><br><span class="line">            <span class="keyword">nonlocal</span> i,j <span class="comment">#nonlocal限定于python3且嵌套函数使用，用于绑定至外层函数的局部变量，当声明为nonlocal变量时，该变量必须能在嵌套作用域中查获（见__closure__属性），否则报错，具体的，此处i绑定为f中的变量i，j绑定在inner1中的变量j</span></span><br><span class="line">            i=<span class="number">6</span></span><br><span class="line">            <span class="built_in">print</span>(j) <span class="comment">#70</span></span><br><span class="line">            j=<span class="number">8</span></span><br><span class="line">            <span class="built_in">print</span>(k) <span class="comment">#13</span></span><br><span class="line">        i=<span class="number">5</span></span><br><span class="line">        <span class="built_in">print</span>(i) <span class="comment">#5</span></span><br><span class="line">        inner2()</span><br><span class="line">        <span class="built_in">print</span>(i) <span class="comment">#6</span></span><br><span class="line">    inner1()</span><br><span class="line">    <span class="built_in">print</span>(j) <span class="comment">#7</span></span><br><span class="line">    </span><br><span class="line">f()</span><br></pre></td></tr></table></figure><p>变量必须先赋值或定义才能使用：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">i=<span class="number">3</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>():</span><br><span class="line">    <span class="built_in">print</span>(i) <span class="comment">#i实际是局部变量，打印前需先赋值</span></span><br><span class="line">    i+=<span class="number">3</span> <span class="comment">#尽管函数内部可以访问全局命名空间中的变量，一旦对其进行赋值等操作（可变对象则可以随意修改，而无需声明`global`），将会在函数内部创建一个同名的局部变量</span></span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line">    </span><br><span class="line">f()</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">Traceback (most recent call last):</span></span><br><span class="line"><span class="string">  File &quot;C:\Users\muggledy\Desktop\ttt2.py&quot;, line 7, in &lt;module&gt;</span></span><br><span class="line"><span class="string">    f()</span></span><br><span class="line"><span class="string">  File &quot;C:\Users\muggledy\Desktop\ttt2.py&quot;, line 3, in f</span></span><br><span class="line"><span class="string">    print(i)</span></span><br><span class="line"><span class="string">UnboundLocalError: local variable &#x27;i&#x27; referenced before assignment</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>函数作为第一类对象（所谓第一类对象的特性是，对象可以赋值给变量、对象可以被当做参数传递、对象可以被当做函数的返回值返回、对象可以作为元素被添加到容器类型中），在下面的例子中，函数接受另一个函数作为输入并调用它：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#定义于文件foo.py，示例来自文献[1]-p79</span></span><br><span class="line">x=<span class="number">6</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">callf</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">return</span> func()</span><br></pre></td></tr></table></figure><p>下面的例子使用了上述函数：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> foo</span><br><span class="line">x=<span class="number">8</span> <span class="comment">#如果注释掉此句，将报错NameError: name &#x27;x&#x27; is not defined</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">helloworld</span>():</span><br><span class="line">    <span class="keyword">return</span> <span class="string">f&#x27;Hello World. x is <span class="subst">&#123;x&#125;</span>&#x27;</span></span><br><span class="line">    </span><br><span class="line"><span class="built_in">print</span>(foo.callf(helloworld)) <span class="comment">#Hello World. x is 8</span></span><br></pre></td></tr></table></figure><p>注意<code>helloworld()</code>使用的<code>x</code>的值是在与它相同的环境中定义的，事实上，解释器会将函数及其所在执行环境整个打包在一起，得到的函数对象称为“闭包函数”，每个函数都拥有一个指向定义该函数的全局命名空间的<code>__globals__</code>属性，对于嵌套函数，闭包同样将捕捉嵌套函数执行所需的整个环境，因此除了<code>__globals__</code>属性，还有一个指向定义该函数的嵌套作用域空间的<code>__closure__</code>属性，示例如下：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">greeting_conf</span>(<span class="params">prefix</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">greeting</span>(<span class="params">name</span>):</span><br><span class="line">        <span class="built_in">print</span> (prefix+<span class="string">&#x27; &#x27;</span>+name) <span class="comment">#greeting函数访问了外部定义的局部变量prefix，事实上在greeting_conf返回后，对greeting_conf可见的局部命名空间已经随着栈帧的销毁而销毁了，即locals()不可再获得，但是嵌套函数greeting会保存所需的执行环境，也就是说greeting_conf中定义的部分（为内层函数所使用到的）局部变量会继续存在于greeting的__closure__属性中</span></span><br><span class="line">    <span class="keyword">return</span> greeting</span><br><span class="line">    </span><br><span class="line">mGreeting=greeting_conf(<span class="string">&#x27;Good Morning&#x27;</span>)</span><br><span class="line">aGreeting=greeting_conf(<span class="string">&#x27;Good Afternoon&#x27;</span>) <span class="comment">#绑定了不同__closure__属性的闭包函数aGreeting和mGreeting是两个不同的函数对象，两者具有不同的执行环境，体现在两者id的不同</span></span><br><span class="line">mGreeting(<span class="string">&#x27;dy&#x27;</span>)</span><br><span class="line">mGreeting(<span class="string">&#x27;zj&#x27;</span>)</span><br><span class="line">aGreeting(<span class="string">&#x27;dxd&#x27;</span>)</span><br><span class="line">aGreeting(<span class="string">&#x27;zj&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(mGreeting.__closure__,mGreeting.__closure__[<span class="number">0</span>].cell_contents)</span><br><span class="line"><span class="built_in">print</span>(aGreeting.__closure__,aGreeting.__closure__[<span class="number">0</span>].cell_contents)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">Good Morning dy</span></span><br><span class="line"><span class="string">Good Morning zj</span></span><br><span class="line"><span class="string">Good Afternoon dxd</span></span><br><span class="line"><span class="string">Good Afternoon zj</span></span><br><span class="line"><span class="string">(&lt;cell at 0x000002A9B0E97288: str object at 0x000002A9B10DA170&gt;,) Good Morning</span></span><br><span class="line"><span class="string">(&lt;cell at 0x000002A9B10687C8: str object at 0x000002A9B10DA1B0&gt;,) Good Afternoon</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><!-- 有时间看一下python3的类型注解 https://docs.python.org/zh-cn/3/library/typing.html --><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="py2-2-2"><p>在开发过程中很可能需要对一些已有的函数进行改进，假设有一个用户注册函数<code>register()</code>，需要提交手机号码、用户名和注册邮箱信息，其中手机号码是数据库主键，具有唯一性，有天上司要求用户名也必须唯一，出于某些原因还不能破坏原有代码，怎么办？使用装饰器可以轻松完成这一工作，只需要编写一个检测是否存在相同用户名的装饰器函数<code>if_unique_username()</code>，然后在原有的<code>register()</code>函数定义前添加一行语句<code>@if_unique_username</code>就ok了，等价于执行<code>register=if_unique_username(register)</code>，<code>@</code>就是简化该操作的语法糖：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">if_unique_username</span>(<span class="params">func</span>): <span class="comment">#装饰器函数</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">_</span>(<span class="params">name,phone,email</span>):</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;DOC: 检测用户名唯一性函数&#x27;&#x27;&#x27;</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;用户姓名唯一性检测&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> func(name,phone,email)</span><br><span class="line">    <span class="comment">#_.__doc__=func.__doc__ #如果借助functools模块，可以将此句替换为functools.update_wrapper(_,func)，效果等同于使用@functools.wraps(func)修饰_()函数</span></span><br><span class="line">    <span class="keyword">return</span> _</span><br><span class="line"></span><br><span class="line"><span class="meta">@if_unique_username </span><span class="comment">#装饰器的实现原理依据闭包函数可以访问其执行环境变量或者说可以访问其嵌套作用域空间变量，这个嵌套作用域空间是绑定在函数对象上的（__closure__）</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">register</span>(<span class="params">name,phone,email</span>): <span class="comment">#被装饰函数</span></span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;DOC: 用户注册函数&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;手机号唯一性检测&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;...&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;用户(<span class="subst">&#123;name&#125;</span>,<span class="subst">&#123;phone&#125;</span>,<span class="subst">&#123;email&#125;</span>)注册成功&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">register(<span class="string">&#x27;dy&#x27;</span>,<span class="string">&#x27;152618xxxxx&#x27;</span>,<span class="string">&#x27;31012xxxxx@qq.com&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">用户姓名唯一性检测</span></span><br><span class="line"><span class="string">手机号唯一性检测</span></span><br><span class="line"><span class="string">...</span></span><br><span class="line"><span class="string">用户(dy,152618xxxxx,31012xxxxx@qq.com)注册成功</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>有时候被装饰函数带有多种类型参数，譬如上述示例中装饰器<code>if_unique_username()</code>内层函数也需要定义和被装饰函数<code>register</code>一模一样的参数，其实没必要这样麻烦，可以用<code>(*args,**kwargs)</code>参数组合来接收任意数量的位置或关键字参数，因此实现一个通用装饰器如下：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">decorator</span>(<span class="params">func</span>):</span><br><span class="line"><span class="meta">    @wraps(<span class="params">func</span>) </span><span class="comment">#更简易使用我的改进版@wraps_fix，后面会详细介绍</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">wrapper</span>(<span class="params">*args,**kwds</span>): <span class="comment">#即使没有参数也可以这样写</span></span><br><span class="line">        <span class="comment">#其他操作...</span></span><br><span class="line">        ret=func(*args,**kwds)</span><br><span class="line">        <span class="comment">#其他操作...</span></span><br><span class="line">        <span class="keyword">return</span> ret</span><br><span class="line">    <span class="keyword">return</span> wrapper</span><br></pre></td></tr></table></figure><p>由于数据量太大，上司决定将用户数据分地区存储在不同的数据库里，在登陆的时候根据用户的所在地来选择相应的数据库，我们希望能够给装饰器指定不同的（地区）参数，最终效果大概是：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@select_database(<span class="params">area=<span class="string">&#x27;江苏&#x27;</span></span>) </span><span class="comment">#等同于执行：register=select_database(area=&#x27;江苏&#x27;)(register)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">register</span>():</span><br><span class="line">    <span class="comment">#用户注册操作</span></span><br><span class="line">    <span class="keyword">pass</span></span><br></pre></td></tr></table></figure><p>依据装饰器的原理，该功能其实不难实现，只需要定义一个三层嵌套的装饰器函数：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">select_database</span>(<span class="params">area</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">_1</span>(<span class="params">func</span>):</span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">_2</span>(<span class="params">*args,**kwargs</span>):</span><br><span class="line">            <span class="string">&#x27;&#x27;&#x27;DOC: 选择地区数据库函数&#x27;&#x27;&#x27;</span></span><br><span class="line">            <span class="built_in">print</span>(<span class="string">f&#x27;选择<span class="subst">&#123;area&#125;</span>地区数据库&#x27;</span>)</span><br><span class="line">            <span class="keyword">return</span> func(*args,**kwargs)</span><br><span class="line">        <span class="comment">#_2.__doc__=func.__doc__ #如果借助functools模块，可以将此句替换为functools.update_wrapper(_2,func)，效果等同于使用@functools.wraps(func)修饰_2()函数</span></span><br><span class="line">        <span class="keyword">return</span> _2</span><br><span class="line">    <span class="keyword">return</span> _1</span><br><span class="line"></span><br><span class="line"><span class="meta">@select_database(<span class="params"><span class="string">&#x27;江苏&#x27;</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">register</span>(<span class="params">name,phone,email</span>):</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;DOC: 用户注册函数&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;手机号唯一性检测&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;...&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;用户(<span class="subst">&#123;name&#125;</span>,<span class="subst">&#123;phone&#125;</span>,<span class="subst">&#123;email&#125;</span>)注册成功&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">register(<span class="string">&#x27;dy&#x27;</span>,<span class="string">&#x27;152618xxxxx&#x27;</span>,<span class="string">&#x27;31012xxxxx@qq.com&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">选择江苏地区数据库</span></span><br><span class="line"><span class="string">手机号唯一性检测</span></span><br><span class="line"><span class="string">...</span></span><br><span class="line"><span class="string">用户(dy,152618xxxxx,31012xxxxx@qq.com)注册成功</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>实际上，我们可以堆砌多个装饰器（装饰器链）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@select_database(<span class="params"><span class="string">&#x27;江苏&#x27;</span></span>)</span></span><br><span class="line"><span class="meta">@if_unique_username</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">register</span>(<span class="params">name,phone,email</span>): <span class="comment">#等同于执行register=select_database(&#x27;江苏&#x27;)(if_unique_username(register))</span></span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;DOC: 用户注册函数&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;手机号唯一性检测&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;...&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;用户(<span class="subst">&#123;name&#125;</span>,<span class="subst">&#123;phone&#125;</span>,<span class="subst">&#123;email&#125;</span>)注册成功&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">register(<span class="string">&#x27;dy&#x27;</span>,<span class="string">&#x27;152618xxxxx&#x27;</span>,<span class="string">&#x27;31012xxxxx@qq.com&#x27;</span>)</span><br></pre></td></tr></table></figure><p>现在有一个问题，假设你查看经过修饰后的<code>register()</code>函数文档<code>register.__doc__</code>，会输出<code>DOC: 选择地区数据库函数</code>，这不符合预期，但是原因也很明显，变量名称<code>register</code>最终已实际指向<code>select_database()</code>中的内层嵌套函数<code>_2()</code>，解决这个问题也很容易，只要改一下<code>_2()</code>的函数文档就好了，于是在<code>_2()</code>函数定义后写一句<code>_2.__doc__=func.__doc__</code>、同时在<code>if_unique_username()</code>中的内层嵌套函数<code>_()</code>定义后写一句<code>_.__doc__=func.__doc__</code>即可，当然不只是<code>__doc__</code>属性，<code>__name__</code>等函数属性也发生了变化，另外，上述操作还可以通过装饰器来实现以简化调用（见下我自定义的<code>wraps()</code>函数，然后分别在<code>_2()</code>函数和<code>_()</code>函数定义上方写上一句<code>@wraps(func)</code>即可）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">wraps</span>(<span class="params">foo</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">_1</span>(<span class="params">func</span>):</span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">_2</span>(<span class="params">*args,**kwargs</span>):</span><br><span class="line">            <span class="keyword">return</span> func(*args,**kwargs)</span><br><span class="line">        _2.__name__=foo.__name__ <span class="comment">#此处只修改了__name__和__doc__属性，仅作为demo展示</span></span><br><span class="line">        _2.__doc__=foo.__doc__</span><br><span class="line">        <span class="keyword">return</span> _2</span><br><span class="line">    <span class="keyword">return</span> _1</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">decorator</span>(<span class="params">func</span>):</span><br><span class="line"><span class="meta">    @wraps(<span class="params">func</span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">wrapper</span>(): <span class="comment">#修饰后的wrapper变量名称实际指向wraps()中的内层嵌套函数_2()，于是原始被装饰函数foo变量名称也是指向_2()函数，因此要将foo()的函数文档赋给_2.__doc__即可</span></span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;wrapper function&#x27;&#x27;&#x27;</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;功能扩展&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> func()</span><br><span class="line">    <span class="keyword">return</span> wrapper</span><br><span class="line"></span><br><span class="line"><span class="meta">@decorator </span><span class="comment">#等同于执行：foo=decorator(foo)=wraps(foo)(wrapper)，于是foo变量名实际指向wraps()中的_2()函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">foo</span>():</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;foo function&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;原函数&#x27;</span>)</span><br><span class="line">    </span><br><span class="line"><span class="built_in">print</span>(foo.__name__) <span class="comment">#foo</span></span><br><span class="line"><span class="built_in">print</span>(foo.__doc__) <span class="comment">#foo function</span></span><br></pre></td></tr></table></figure><p>不过标准的解决方案还是调用<code>functools</code>模块的<code>@wraps</code>装饰器，用法同上，官方实现如下（借助偏函数）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">WRAPPER_ASSIGNMENTS = (<span class="string">&#x27;__module__&#x27;</span>, <span class="string">&#x27;__name__&#x27;</span>, <span class="string">&#x27;__qualname__&#x27;</span>, <span class="string">&#x27;__doc__&#x27;</span>, <span class="string">&#x27;__annotations__&#x27;</span>)</span><br><span class="line">WRAPPER_UPDATES = (<span class="string">&#x27;__dict__&#x27;</span>,)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">update_wrapper</span>(<span class="params">wrapper,</span></span><br><span class="line"><span class="params">                   wrapped,</span></span><br><span class="line"><span class="params">                   assigned = WRAPPER_ASSIGNMENTS,</span></span><br><span class="line"><span class="params">                   updated = WRAPPER_UPDATES</span>):</span><br><span class="line">    <span class="keyword">for</span> attr <span class="keyword">in</span> assigned:</span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            value = <span class="built_in">getattr</span>(wrapped, attr)</span><br><span class="line">        <span class="keyword">except</span> AttributeError:</span><br><span class="line">            <span class="keyword">pass</span></span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="built_in">setattr</span>(wrapper, attr, value)</span><br><span class="line">    <span class="keyword">for</span> attr <span class="keyword">in</span> updated:</span><br><span class="line">        <span class="built_in">getattr</span>(wrapper, attr).update(<span class="built_in">getattr</span>(wrapped, attr, &#123;&#125;))</span><br><span class="line">    wrapper.__wrapped__ = wrapped</span><br><span class="line">    <span class="keyword">return</span> wrapper</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">wraps</span>(<span class="params">wrapped,</span></span><br><span class="line"><span class="params">          assigned = WRAPPER_ASSIGNMENTS,</span></span><br><span class="line"><span class="params">          updated = WRAPPER_UPDATES</span>):</span><br><span class="line">    <span class="keyword">return</span> partial(update_wrapper, wrapped=wrapped,</span><br><span class="line">                   assigned=assigned, updated=updated)</span><br></pre></td></tr></table></figure><p>根据上述源码，除了使用<code>@wraps</code>修饰外，还有一种用法（直接调用<code>update_wrapper()</code>函数）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> update_wrapper</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">decorator</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">wrapper</span>():</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;wrapper function&#x27;&#x27;&#x27;</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;功能扩展&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> func()</span><br><span class="line">    update_wrapper(wrapper,func)</span><br><span class="line">    <span class="keyword">return</span> wrapper</span><br><span class="line"></span><br><span class="line"><span class="meta">@decorator</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">foo</span>():</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;foo function&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;原函数&#x27;</span>)</span><br><span class="line">    </span><br><span class="line"><span class="built_in">print</span>(foo.__name__) <span class="comment">#foo</span></span><br><span class="line"><span class="built_in">print</span>(foo.__doc__) <span class="comment">#foo function</span></span><br></pre></td></tr></table></figure><p>另外还可以通过<code>foo=foo.__wrapped__</code>方便地将被装饰函数恢复为原函数（即“解除装饰器”），如果没有使用<code>@functools.wraps</code>，那么<code>__wrapped__</code>属性是不可获得的，需要注意的是，这仅仅适用于单个装饰器的情况，假设你堆砌了多个装饰函数，那么访问<code>__wrapped__</code>属性获取到的就不再是原函数了：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> wraps</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">decorator1</span>(<span class="params">func</span>):</span><br><span class="line"><span class="meta">    @wraps(<span class="params">func</span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">wrapper1</span>():</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;wrapper1 function&#x27;&#x27;&#x27;</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;功能扩展1&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> func()</span><br><span class="line">    <span class="keyword">return</span> wrapper1</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">decorator2</span>(<span class="params">func</span>):</span><br><span class="line"><span class="meta">    @wraps(<span class="params">func</span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">wrapper2</span>():</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;wrapper2 function&#x27;&#x27;&#x27;</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;功能扩展2&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> func()</span><br><span class="line">    <span class="keyword">return</span> wrapper2</span><br><span class="line"></span><br><span class="line"><span class="meta">@decorator2</span></span><br><span class="line"><span class="meta">@decorator1</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">foo</span>():</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;foo function&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;原函数&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">foo.__wrapped__() <span class="comment">#结果指向decorator1()中的内层函数wrapper1()，而非希望的foo()，原因也很明显，上面对foo()的修饰，等同于执行了foo=decorator2(decorator1(foo))，具体的，第一步执行temp=decorator1(foo)时，根据functools.wraps原理，于是wrapper1.__wrapped__属性被赋值为foo，即指向foo()函数，第二步执行decorator2(temp)时，于是wrapper2.__wrapped__属性被赋值为temp，而temp变量实际指向wrapper1()函数，另修饰后的foo变量实际指向wrapper2()函数，于是foo.__wrapped__返回的是wrapper1()（闭包）函数，不过这时你也发现了，要获取到原函数，只要再迈出一步，即调用foo.__wrapped__.__wrapped__，返回的就是原始的foo()函数了</span></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">功能扩展1</span></span><br><span class="line"><span class="string">原函数</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>要想实现多层装饰器的解除，可以稍稍修改<code>update_wrapper()</code>函数源码：</p><figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">def update_wrapper(wrapper,</span><br><span class="line">                   wrapped,</span><br><span class="line">                   assigned = WRAPPER_ASSIGNMENTS,</span><br><span class="line">                   updated = WRAPPER_UPDATES):</span><br><span class="line">    for attr in assigned:</span><br><span class="line">        try:</span><br><span class="line">            value = getattr(wrapped, attr)</span><br><span class="line">        except AttributeError:</span><br><span class="line">            pass</span><br><span class="line">        else:</span><br><span class="line">            setattr(wrapper, attr, value)</span><br><span class="line">    for attr in updated:</span><br><span class="line">        getattr(wrapper, attr).update(getattr(wrapped, attr, &#123;&#125;))</span><br><span class="line"><span class="deletion">-   wrapper.__wrapped__ = wrapped</span></span><br><span class="line"><span class="addition">+   if hasattr(wrapped, &#x27;__wrapped__&#x27;):</span></span><br><span class="line"><span class="addition">+       wrapper.__wrapped__ = getattr(wrapped, &#x27;__wrapped__&#x27;)</span></span><br><span class="line"><span class="addition">+   else:</span></span><br><span class="line"><span class="addition">+       wrapper.__wrapped__ = wrapped</span></span><br><span class="line">    return wrapper</span><br></pre></td></tr></table></figure><p>如果不想修改源码，可以这样改：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> wraps</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">decorator1</span>(<span class="params">func</span>):</span><br><span class="line"><span class="meta">    @wraps(<span class="params">func</span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">wrapper1</span>():</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;wrapper1 function&#x27;&#x27;&#x27;</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;功能扩展1&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> func()</span><br><span class="line">    <span class="comment">###额外添加的代码</span></span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">hasattr</span>(func,<span class="string">&#x27;__wrapped__&#x27;</span>):</span><br><span class="line">        wrapper1.__wrapped__=<span class="built_in">getattr</span>(func,<span class="string">&#x27;__wrapped__&#x27;</span>)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        wrapper1.__wrapped__=func</span><br><span class="line">    <span class="comment">###以实现多装饰器的正常解除</span></span><br><span class="line">    <span class="keyword">return</span> wrapper1</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">decorator2</span>(<span class="params">func</span>):</span><br><span class="line"><span class="meta">    @wraps(<span class="params">func</span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">wrapper2</span>():</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;wrapper2 function&#x27;&#x27;&#x27;</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;功能扩展2&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> func()</span><br><span class="line">    <span class="comment">###额外添加的代码</span></span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">hasattr</span>(func,<span class="string">&#x27;__wrapped__&#x27;</span>):</span><br><span class="line">        wrapper2.__wrapped__=<span class="built_in">getattr</span>(func,<span class="string">&#x27;__wrapped__&#x27;</span>)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        wrapper2.__wrapped__=func</span><br><span class="line">    <span class="comment">###以实现多装饰器的正常解除</span></span><br><span class="line">    <span class="keyword">return</span> wrapper2</span><br><span class="line"></span><br><span class="line"><span class="meta">@decorator2</span></span><br><span class="line"><span class="meta">@decorator1</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">foo</span>():</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;foo function&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;原函数&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">foo.__wrapped__() <span class="comment">#原函数</span></span><br></pre></td></tr></table></figure><p>代码很简单，缺点是代码重复编写，此处我再给出一种解决方案💡：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> wraps</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">wraps_fix</span>(<span class="params">f1</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">_1</span>(<span class="params">f2</span>):</span><br><span class="line"><span class="meta">        @wraps(<span class="params">f1</span>)</span></span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">_2</span>(<span class="params">*args,**kwds</span>):</span><br><span class="line">            <span class="keyword">return</span> f2(*args,**kwds)</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">hasattr</span>(f1,<span class="string">&#x27;__wrapped__&#x27;</span>):</span><br><span class="line">            _2.__wrapped__=<span class="built_in">getattr</span>(f1,<span class="string">&#x27;__wrapped__&#x27;</span>)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            _2.__wrapped__=f1</span><br><span class="line">        <span class="keyword">return</span> _2</span><br><span class="line">    <span class="keyword">return</span> _1</span><br><span class="line">    </span><br><span class="line"><span class="keyword">def</span> <span class="title function_">decorator1</span>(<span class="params">func</span>):</span><br><span class="line"><span class="meta">    @wraps_fix(<span class="params">func</span>) </span><span class="comment">#完美！</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">wrapper1</span>():</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;wrapper1 function&#x27;&#x27;&#x27;</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;功能扩展1&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> func()</span><br><span class="line">    <span class="keyword">return</span> wrapper1</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">decorator2</span>(<span class="params">func</span>):</span><br><span class="line"><span class="meta">    @wraps_fix(<span class="params">func</span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">wrapper2</span>():</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;wrapper2 function&#x27;&#x27;&#x27;</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;功能扩展2&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> func()</span><br><span class="line">    <span class="keyword">return</span> wrapper2</span><br><span class="line"></span><br><span class="line"><span class="meta">@decorator2</span></span><br><span class="line"><span class="meta">@decorator1</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">foo</span>():</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;foo function&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;原函数&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">foo.__wrapped__() <span class="comment">#原函数</span></span><br></pre></td></tr></table></figure><p>除了使用三层嵌套函数实现带参数的装饰器，还可以借助偏函数实现，仍以选择地区数据库注册用户为例：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> wraps,partial</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">select_database2</span>(<span class="params">area,func=<span class="literal">None</span></span>):</span><br><span class="line">    <span class="keyword">if</span> func <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line">        <span class="keyword">return</span> partial(select_database2,area)</span><br><span class="line"><span class="meta">    @wraps(<span class="params">func</span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">wrapper</span>(<span class="params">*args,**kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;选择<span class="subst">&#123;area&#125;</span>地区数据库&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> func(*args,**kwargs)</span><br><span class="line">    <span class="keyword">return</span> wrapper</span><br><span class="line"></span><br><span class="line"><span class="meta">@select_database2(<span class="params"><span class="string">&#x27;江苏&#x27;</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">register</span>(<span class="params">name,phone,email</span>):</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;DOC: 用户注册函数&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;手机号唯一性检测&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;...&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;用户(<span class="subst">&#123;name&#125;</span>,<span class="subst">&#123;phone&#125;</span>,<span class="subst">&#123;email&#125;</span>)注册成功&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">register(<span class="string">&#x27;dy&#x27;</span>,<span class="string">&#x27;152618xxxxx&#x27;</span>,<span class="string">&#x27;31012xxxxx@qq.com&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">选择江苏地区数据库</span></span><br><span class="line"><span class="string">手机号唯一性检测</span></span><br><span class="line"><span class="string">...</span></span><br><span class="line"><span class="string">用户(dy,152618xxxxx,31012xxxxx@qq.com)注册成功</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>网上看到一种通过类实现带参装饰器的方法，核心是借助于特殊函数<code>__call__()</code>使类实例变得可调用，此时上述案例可以这样写：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">select_database3</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,area</span>):</span><br><span class="line">        self.area=area</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__call__</span>(<span class="params">self,func</span>):</span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">wrapper</span>(<span class="params">*args,**kwargs</span>):</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">f&#x27;选择<span class="subst">&#123;self.area&#125;</span>地区数据库&#x27;</span>)</span><br><span class="line">            <span class="keyword">return</span> func(*args,**kwargs)</span><br><span class="line">        <span class="keyword">return</span> wrapper</span><br><span class="line"></span><br><span class="line"><span class="meta">@select_database3(<span class="params"><span class="string">&#x27;江苏&#x27;</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">register</span>(<span class="params">name,phone,email</span>):</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;DOC: 用户注册函数&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;手机号唯一性检测&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;...&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;用户(<span class="subst">&#123;name&#125;</span>,<span class="subst">&#123;phone&#125;</span>,<span class="subst">&#123;email&#125;</span>)注册成功&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">register(<span class="string">&#x27;dy&#x27;</span>,<span class="string">&#x27;152618xxxxx&#x27;</span>,<span class="string">&#x27;31012xxxxx@qq.com&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">选择江苏地区数据库</span></span><br><span class="line"><span class="string">手机号唯一性检测</span></span><br><span class="line"><span class="string">...</span></span><br><span class="line"><span class="string">用户(dy,152618xxxxx,31012xxxxx@qq.com)注册成功</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>不带参数的通用的基于类实现的装饰器：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> update_wrapper</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">decorator</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,func</span>):</span><br><span class="line">        self.func=func</span><br><span class="line">        update_wrapper(self,self.func)</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__call__</span>(<span class="params">self,*args,**kwargs</span>):</span><br><span class="line">        <span class="comment">#其他操作...</span></span><br><span class="line">        ret=self.func(*args,**kwargs)</span><br><span class="line">        <span class="comment">#其他操作...</span></span><br><span class="line">        <span class="keyword">return</span> ret</span><br></pre></td></tr></table></figure><p>最后再看几个装饰器实现的案例，一是<code>@singledispatch</code>，被<code>@singledispatch</code>装饰的普通函数会变为泛函数，即根据第一个参数的类型以不同方式执行重载函数，称为单分派（而根据多个参数选择指定的函数，称为多分派，顾名思义<code>singledispatch</code>是单分派），如下：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> singledispatch</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">cattle</span>:</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;牛&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&#x27;cattle&#x27;</span></span><br><span class="line">    </span><br><span class="line"><span class="keyword">class</span> <span class="title class_">fish</span>:</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;鱼&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&#x27;fish&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="meta">@singledispatch</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">eat</span>(<span class="params">obj</span>): <span class="comment">#(1) #eat是泛函数，任意类对象只要没有“注册”都将调用该方法，对于注册了的譬如cattle和fish类，则调用对应的重载函数</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="built_in">str</span>(obj)+<span class="string">&#x27; eats something&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="meta">@eat.register(<span class="params">cattle</span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">_</span>(<span class="params">obj</span>): <span class="comment">#(2) #_是一个无意义名字，当然也可取名为cattle_eat</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="built_in">str</span>(obj)+<span class="string">&#x27; eats grass&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="meta">@eat.register(<span class="params">fish</span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">_</span>(<span class="params">obj</span>): <span class="comment">#(3)</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="built_in">str</span>(obj)+<span class="string">&#x27; eats shrimp&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">eat(cattle()) <span class="comment">#cattle eats grass</span></span><br><span class="line">eat(fish()) <span class="comment">#fish eats shrimp</span></span><br><span class="line">eat(<span class="string">&#x27;muggledy&#x27;</span>) <span class="comment">#muggledy eats something</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#动物都需要进食，但是不同对象“吃”的行为却各不相同，牛吃草、小鱼吃虾米等等，如果用面向对象继承方式实现，基类“吃”的方法就是上述代码中的(1)，牛继承基类并重载“吃”的方法，见(2)，同理，小鱼的“吃”见(3)</span></span><br></pre></td></tr></table></figure><p>二是带记忆装置的斐波那契数项计算，上一章我们讨论过了使用递归计算斐波那契数项的问题，代码很容易理解，但是性能却十分差，要改进它，一个合理的想法是为其配备“记忆装置”，对于计算过了的值我们直接从中获取以免重复计算造成资源浪费，利用装饰器我们不需要破坏原有代码，十分优美：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">memory</span>(<span class="params">func</span>):</span><br><span class="line">    m=&#123;&#125;</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">wrapper</span>(<span class="params">n</span>):</span><br><span class="line">        <span class="keyword">if</span> m.get(n) <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line">            m[n]=func(n)</span><br><span class="line">        <span class="keyword">return</span> m[n]</span><br><span class="line">    <span class="keyword">return</span> wrapper</span><br><span class="line"></span><br><span class="line"><span class="meta">@memory</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">Fibonacci</span>(<span class="params">n=<span class="number">6</span></span>):</span><br><span class="line">    <span class="keyword">if</span> n <span class="keyword">in</span> [<span class="number">1</span>,<span class="number">2</span>]:</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">return</span> Fibonacci(n-<span class="number">2</span>)+Fibonacci(n-<span class="number">1</span>)</span><br><span class="line">        </span><br><span class="line"><span class="built_in">print</span>(Fibonacci(<span class="number">35</span>))</span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>@lru_cache</code></span></div>    <div class="hide-content"><p>由于计算机内存有限，记忆装置的缓存大小也应受限，但我们要做的不仅仅是限制缓存大小，还要基于LRU（Least Recently Used）“最近最少使用”思想来移除缓存中的过时数据，该算法的核心思想是，如果一个数据最近被访问过，则有理由相信它在将来被访问的概率也很高，反之，如果一个数据最近未被访问过，则可以认为它在将来被访问的概率也很低，实现它的最佳方式是使用“基于LRU的有序字典”来实现（按照访问频率高低按序排列，这就需要一个线性表，但是线性表查找时间复杂度为O(n)，考虑到字典查找时间复杂度为O(1)，因此可以通过next指针将字典中的元素依次串联起来，构成一个有序字典），官方文档<code>collections.OrderedDict</code>中基于<code>OrderedDict</code>实现了这样一个LRU字典，代码简洁明了（最后用下述<code>LRU</code>替换我上面写的<code>memory</code>装饰器函数中的变量<code>m</code>即可）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">LRU</span>(<span class="title class_ inherited__">OrderedDict</span>):</span><br><span class="line">    <span class="string">&#x27;Limit size, evicting the least recently looked-up key when full&#x27;</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, maxsize=<span class="number">128</span>, *args, **kwds</span>):</span><br><span class="line">        self.maxsize = maxsize</span><br><span class="line">        <span class="built_in">super</span>().__init__(*args, **kwds)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__getitem__</span>(<span class="params">self, key</span>):</span><br><span class="line">        value = <span class="built_in">super</span>().__getitem__(key)</span><br><span class="line">        self.move_to_end(key)</span><br><span class="line">        <span class="keyword">return</span> value</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__setitem__</span>(<span class="params">self, key, value</span>): <span class="comment">#这个有序字典从头到尾的使用频率是增高的，新增（__setitem__()）的自然在最右边，如果访问（__getitem__()）某元素则将其移动到末尾</span></span><br><span class="line">        <span class="built_in">super</span>().__setitem__(key, value)</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">len</span>(self) &gt; self.maxsize:</span><br><span class="line">            oldest = <span class="built_in">next</span>(<span class="built_in">iter</span>(self))</span><br><span class="line">            <span class="keyword">del</span> self[oldest]</span><br></pre></td></tr></table></figure><p>下面进入正题，看看<code>@lru_cache</code>的具体使用，首先导入：<code>from functools import lru_cache</code>，然后用于装饰你希望被装饰的递归函数：<code>@lru_cache(maxsize=128, typed=False)</code>，待缓存条目是被装饰函数的输入（作为缓存项的键）和输出（作为缓存项的值），如果<code>maxsize</code>参数设为<code>None</code>，那么缓存可以无限制增长，而当<code>maxsize</code>是2的次幂时，LRU功能表现最佳，如果<code>typed</code>参数设为<code>True</code>，那么同一数值但类型不同的函数参数调用将对应不同的缓存项（须知，对于被装饰函数，相同输入必须具有相同输出，假设输出不具有确定性，譬如受制于随机性函数，则<code>@lru_cache</code>失效，无法达到节省时间的效果）<br><img src="https://i.loli.net/2021/11/01/vep4NJ6RVuUsFx5.png" alt=""></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> lru_cache</span><br><span class="line"></span><br><span class="line"><span class="meta">@lru_cache(<span class="params">maxsize=<span class="number">128</span>, typed=<span class="literal">False</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">Fibonacci</span>(<span class="params">n=<span class="number">6</span></span>):</span><br><span class="line">    <span class="keyword">if</span> n <span class="keyword">in</span> [<span class="number">1</span>,<span class="number">2</span>]:</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">return</span> Fibonacci(n-<span class="number">2</span>)+Fibonacci(n-<span class="number">1</span>)</span><br><span class="line">        </span><br><span class="line"><span class="built_in">print</span>(Fibonacci(<span class="number">35</span>)) <span class="comment">#9227465</span></span><br></pre></td></tr></table></figure><p>装饰器<code>@lru_cache</code>提供了<code>cache_clear()</code>方法用于清除缓存或使缓存无效。一般说来，当我们使用装饰器之后，将“丢失”被装饰函数，被装饰函数的名字总是指向装饰函数，但<code>@lru_cache</code>类似<code>@wraps</code>也提供了<code>__wrapped__</code>属性，指向原始被装饰函数</p></div></div>三是使用<a href="https://www.jianshu.com/p/30a8e723efdc">装饰器修饰类对象</a>，变相地执行继承，已知有一个限定了实例属性的类，要扩展一个额外的属性，但是不允许破坏原有代码，显然解决办法是继承这个类，并使新类代替旧类，该过程可以通过装饰器实现，比较新奇：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">addLength</span>(<span class="params">oldcls</span>):</span><br><span class="line">    <span class="keyword">class</span> <span class="title class_">NewClass</span>(<span class="title class_ inherited__">oldcls</span>):</span><br><span class="line">        __slots__=[<span class="string">&#x27;_length&#x27;</span>]</span><br><span class="line">        </span><br><span class="line"><span class="meta">        @property</span></span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">length</span>(<span class="params">self</span>):</span><br><span class="line">            <span class="keyword">if</span> <span class="built_in">hasattr</span>(self, <span class="string">&#x27;__len__&#x27;</span>):</span><br><span class="line">                self._length = <span class="built_in">len</span>(self)</span><br><span class="line">            <span class="keyword">return</span> self._length</span><br><span class="line">        </span><br><span class="line"><span class="meta">        @length.setter</span></span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">length</span>(<span class="params">self, value</span>):</span><br><span class="line">            self._length = value</span><br><span class="line">    <span class="keyword">return</span> NewClass <span class="comment">#返回继承自（oldcls）旧类Tool的新类</span></span><br><span class="line"></span><br><span class="line"><span class="meta">@addLength</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Tool</span>: <span class="comment">#Tool=addLength(Tool)，变量名称Tool指向继承Tool的新类NewClass</span></span><br><span class="line">    __slots__=[<span class="string">&#x27;width&#x27;</span>,<span class="string">&#x27;height&#x27;</span>]</span><br><span class="line"></span><br><span class="line">t = Tool()</span><br><span class="line">t.width=<span class="number">8</span></span><br><span class="line">t.height=<span class="number">9</span></span><br><span class="line">t.length = <span class="number">10</span> <span class="comment">#新增属性</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="py2-2-3"><p>还是以用户注册功能函数<code>register()</code>为例，设其接收两个参数，用户所属国家<code>country</code>和姓名<code>name</code>，对于某一地区，绝大部分人的国家属性相同，那么理应给<code>country</code>参数设置一个默认值，从而简化调用，具体的，定义一个参数配置函数<code>configure()</code>，接收原函数<code>register</code>地址和要设置的参数<code>country</code>值，并返回一个闭包函数（称为原函数的“偏函数”），当调用此闭包函数时，只需要再传入剩下的<code>name</code>参数，闭包函数内部会根据之前保存的<code>country</code>参数和刚传入的<code>name</code>参数去执行原函数<code>register()</code>实现用户注册</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">register</span>(<span class="params">country,name</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;[<span class="subst">&#123;country&#125;</span>]<span class="subst">&#123;name&#125;</span>用户注册&#x27;</span>)</span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line">    </span><br><span class="line">register(<span class="string">&#x27;中国&#x27;</span>,<span class="string">&#x27;muggle&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">configure</span>(<span class="params">func,country</span>): <span class="comment">#python内置的实现相同功能的函数名称叫做partial</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">_</span>(<span class="params">name</span>):</span><br><span class="line">        <span class="keyword">return</span> func(country,name)</span><br><span class="line">    <span class="keyword">return</span> _</span><br><span class="line">    </span><br><span class="line">register_china=configure(register,<span class="string">&#x27;中国&#x27;</span>)</span><br><span class="line">register_china(<span class="string">&#x27;msy&#x27;</span>)</span><br><span class="line">register_china(<span class="string">&#x27;xiaodong&#x27;</span>)</span><br><span class="line"></span><br><span class="line">register_japan=configure(register,<span class="string">&#x27;日本&#x27;</span>)</span><br><span class="line">register_japan(<span class="string">&#x27;艹&#x27;</span>)</span><br><span class="line">register_japan(<span class="string">&#x27;SB&#x27;</span>)</span><br></pre></td></tr></table></figure><p>通用的配置函数形式：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">configure</span>(<span class="params">func,*args1,**kwargs1</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">_</span>(<span class="params">*args2,**kwargs2</span>):</span><br><span class="line">        <span class="keyword">return</span> func(*args1,*args2,**kwargs1,**kwargs2)</span><br><span class="line">    <span class="keyword">return</span> _</span><br></pre></td></tr></table></figure><p>所谓偏函数（或者翻译成局部应用），即是固定住原函数的部分参数（设为<code>k</code>个），以实现简化调用的目的（设原函数共有<code>n</code>个参数，局部应用将一个<code>n</code>元函数转换成一个<code>n-k</code>元函数），另有一个概念叫做“柯里化”，是一种将接受多个参数的函数转变成接受一个单一参数的函数，并且返回接受余下的参数且返回结果的新函数的技术（柯里化将一个<code>n</code>元函数转换成<code>n</code>个一元函数），可能不太好理解，直接看示例，一个实现三个数相加的加法操作：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">a,b,c</span>):</span><br><span class="line">    <span class="keyword">return</span> a+b+c</span><br></pre></td></tr></table></figure><p>其柯里化版本为：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">a</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">_f1</span>(<span class="params">b</span>):</span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">_f2</span>(<span class="params">c</span>):</span><br><span class="line">            <span class="keyword">return</span> a+b+c</span><br><span class="line">        <span class="keyword">return</span> _f2</span><br><span class="line">    <span class="keyword">return</span> _f1</span><br><span class="line"></span><br><span class="line">add(<span class="number">1</span>)(<span class="number">2</span>)(<span class="number">3</span>) <span class="comment">#6</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#可化简形式：</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">a</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">lambda</span> b:<span class="keyword">lambda</span> c: a+b+c</span><br><span class="line"></span><br><span class="line"><span class="comment">#或者：</span></span><br><span class="line">add=<span class="keyword">lambda</span> a:<span class="keyword">lambda</span> b:<span class="keyword">lambda</span> c:a+b+c</span><br><span class="line">add(<span class="number">1</span>)(<span class="number">2</span>)(<span class="number">3</span>) <span class="comment">#6</span></span><br></pre></td></tr></table></figure><p>显然，我们不可能每次都花这么大的功夫为一个函数特别定制其柯里化版本，为此，定义了一个转换函数<code>curry()</code>，能够接收一个函数对象作为参数，并将其转换为柯里化版本：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#这是一个更具通用性的curry()，随后你除了可以这样调用add(1)(2)(3)，还可以add(1)(2,3)或add(1,2)(3)</span></span><br><span class="line"><span class="comment">#改进版本参见：https://github.com/muggledy/myworld/blob/master/src/_base/decorator.py</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">curry</span>(<span class="params">func</span>):</span><br><span class="line">    argsnum=func.__code__.co_argcount</span><br><span class="line">    allargs=[]</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">curried</span>(<span class="params">*args</span>):</span><br><span class="line">        <span class="keyword">nonlocal</span> allargs</span><br><span class="line">        allargs+=<span class="built_in">list</span>(args)</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">len</span>(allargs)&gt;=argsnum:</span><br><span class="line">            ret=func(*allargs[:argsnum])</span><br><span class="line">            allargs=[]</span><br><span class="line">            <span class="keyword">return</span> ret</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">return</span> curried</span><br><span class="line">    <span class="keyword">return</span> curried</span><br><span class="line">    </span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;设计思路</span></span><br><span class="line"><span class="string">1.curry实现对一个函数的柯里化，因此只接收一个函数参数func，返回一个新的函数curried，其为func的柯里化版本</span></span><br><span class="line"><span class="string">2.每次curried被传递进参数并调用，curried都会检查是否已接收了足够的参数（使用allargs存储），当其个数大于或等于原函数参数func定义的参数个数（由argsnum记录），此时立即计算最终结果并返回，否则继续返回curried以接收更多参数</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line">curriedAdd=curry(add) <span class="comment">#curriedAdd是原函数add的柯里化版本，如果需要覆盖原函数，就直接add=curry(add)，而这正好可以使用装饰器的语法糖@来完成，更优美</span></span><br><span class="line"><span class="built_in">print</span>(curriedAdd(<span class="number">1</span>)(<span class="number">2</span>)(<span class="number">3</span>)) <span class="comment">#6</span></span><br><span class="line"><span class="built_in">print</span>(curriedAdd(<span class="number">1</span>)(<span class="number">2</span>,<span class="number">3</span>)) <span class="comment">#6</span></span><br><span class="line"><span class="built_in">print</span>(curriedAdd(<span class="number">1</span>,<span class="number">2</span>)(<span class="number">3</span>)) <span class="comment">#6</span></span><br><span class="line"><span class="built_in">print</span>(curriedAdd(<span class="number">1</span>,<span class="number">2</span>)(<span class="number">3</span>,<span class="number">4</span>)) <span class="comment">#6</span></span><br><span class="line"><span class="comment">#curriedAdd(1,2,3)(4) #TypeError: &#x27;int&#x27; object is not callable，由于curriedAdd(1,2,3)已经返回了正确结果6，整数显然是不可调用的，因此报错，对于curriedAdd(1,2)(3,4)，curriedAdd(1,2)返回的是一个函数，还能继续接收参数，但是只需要再接收一个就能正确计算，因此4被忽略（当然你也可以根据参数数量不一致raise报错），最终仍返回6</span></span><br></pre></td></tr></table></figure><p>除了上述通用的配置函数实现，我在<a href="https://www.python.org/dev/peps/pep-0309/">PEP</a>文档中找到了一个利用<code>__call__()</code>实现的类版本：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">partial</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">*args, **kw</span>):</span><br><span class="line">        self = args[<span class="number">0</span>] <span class="comment">#__init__()的第一个参数是self对象</span></span><br><span class="line">        self.fn, self.args, self.kw = (args[<span class="number">1</span>], args[<span class="number">2</span>:], kw) <span class="comment">#args[1]是原函数，剩下的就是要预先固定的参数</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__call__</span>(<span class="params">self, *args, **kw</span>):</span><br><span class="line">        <span class="keyword">if</span> kw <span class="keyword">and</span> self.kw:</span><br><span class="line">            d = self.kw.copy()</span><br><span class="line">            d.update(kw)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            d = kw <span class="keyword">or</span> self.kw</span><br><span class="line">        <span class="keyword">return</span> self.fn(*(self.args + args), **d)</span><br></pre></td></tr></table></figure><p>最后要说的是，python中实现偏函数的标准方法是通过<code>from functools import partial</code>，另外，除了为函数预设部分参数值构成偏函数，实际上任何可以通过<code>()</code>调用的都可以进行“偏应用”，譬如类、类实例、类/实例方法都可以通过<code>()</code>调用：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> partial</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,m,n</span>):</span><br><span class="line">        self.m=m</span><br><span class="line">        self.n=n</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__call__</span>(<span class="params">self,k,flag</span>): <span class="comment"># k为乘积系数，flag表示是否输出结果</span></span><br><span class="line">        <span class="keyword">if</span> flag:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&#x27;m*k:&#x27;</span>,self.m*k,<span class="string">&#x27;\nn*k:&#x27;</span>,self.n*k)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">pass</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">hello</span>(<span class="params">self,f1,f2</span>): <span class="comment"># 如果两个参数都是True，那么输出hello world，否则输出screw it</span></span><br><span class="line">        <span class="keyword">if</span> f1 <span class="keyword">and</span> f2:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&#x27;hello,world!&#x27;</span>)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&#x27;screw it!&#x27;</span>)</span><br><span class="line">            </span><br><span class="line"><span class="comment">#1.类A的参数m既定为3，那么我们就通过偏函数为类A的构造函数固定住这个参数m，其值为3</span></span><br><span class="line">A_m=partial(A,<span class="number">3</span>) <span class="comment"># 偏应用的类A</span></span><br><span class="line">obj_1=A_m(<span class="number">4</span>)</span><br><span class="line"><span class="built_in">print</span>(obj_1.m,obj_1.n) <span class="comment"># 3 4</span></span><br><span class="line">obj_2=A_m(<span class="number">5</span>)</span><br><span class="line"><span class="built_in">print</span>(obj_2.m,obj_2.n) <span class="comment"># 3 5</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#2.当类实现了__call__方法后，类实例对象将可以像函数一样被()调用，既然如此，我们为其固定住flag参数为True</span></span><br><span class="line">obj=A(<span class="number">7</span>,<span class="number">8</span>)</span><br><span class="line">obj_true=partial(obj,flag=<span class="literal">True</span>)</span><br><span class="line">obj_true(<span class="number">2</span>) <span class="comment"># m*k: 14 \nn*k: 16</span></span><br><span class="line">obj_true(<span class="number">3</span>) <span class="comment"># m*k: 21 \nn*k: 24</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#3.实例方法，本质就是函数对象，我们将hello方法的f2参数置为True，是否输出问候语只需要f1参数</span></span><br><span class="line">obj_hello=partial(obj.hello,f2=<span class="literal">True</span>) <span class="comment">#事实上，实例属性方法访问返回的也是一个固定了self参数的偏应用</span></span><br><span class="line">obj_hello(<span class="literal">True</span>) <span class="comment"># hello,world!</span></span><br><span class="line">obj_hello(<span class="literal">False</span>) <span class="comment"># screw it!</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="py2-2-4"><p>在函数内，<code>yield</code>语句还可以用作出现在赋值运算右边的表达式，例如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">receiver</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;Ready to receive&#x27;</span>)</span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        n=(<span class="keyword">yield</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;Got <span class="subst">&#123;n&#125;</span>&#x27;</span>)</span><br></pre></td></tr></table></figure><p>以这种方式使用<code>yield</code>语句的函数称为“协程”（协程反映了程序逻辑的一种需求：可重入（子程序/函数的）能力。协程能保留上一次调用时的状态，每次重入时，就相当于进入上一次调用的状态），它的执行是为了响应发送给它的值，其行为也类似于生成器：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>r=receiver() <span class="comment">#此时函数尚未执行</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>r.__next__() <span class="comment">#首次调用next()方法以向前执行到第一条yield语句处并暂停</span></span><br><span class="line">Ready to receive</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>r.send(<span class="number">1</span>) <span class="comment">#发送值到yield处，且发送的值将被直接赋给yield赋值号左边的变量，然后继续向前直至再次遇到yield并暂停</span></span><br><span class="line">Got <span class="number">1</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">print</span>(r.send(<span class="string">&#x27;Hello&#x27;</span>))</span><br><span class="line">Got Hello</span><br><span class="line"><span class="literal">None</span></span><br></pre></td></tr></table></figure><p>上述示例中在执行发送前需要先调用一次<code>next()</code>方法，不太方便，可以定义一个装饰器以自动调用：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">coroutine</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">_</span>(<span class="params">*args,**kwargs</span>):</span><br><span class="line">        g=func(*args,**kwargs)</span><br><span class="line">        <span class="built_in">next</span>(g) <span class="comment">#next()返回第一个遇到的yield语句中的表达式值（yield [expression]），假设expression缺省，则返回None</span></span><br><span class="line">        <span class="keyword">return</span> g</span><br><span class="line">    <span class="keyword">return</span> _</span><br><span class="line">    </span><br><span class="line"><span class="meta">@coroutine</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">receiver</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;Ready to receive&#x27;</span>)</span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        n=(<span class="keyword">yield</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;Got <span class="subst">&#123;n&#125;</span>&#x27;</span>)</span><br><span class="line">        </span><br><span class="line">r=receiver()</span><br><span class="line">r.send(<span class="number">1</span>)</span><br><span class="line">r.send(<span class="string">&#x27;Hello&#x27;</span>)</span><br></pre></td></tr></table></figure><p>协程的运行一般是无限期的，除非它被显式关闭（调用<code>close()</code>方法）或者自己退出，关闭后如果继续给协程发送值，将会引发<code>StopIteration</code>异常，正如之前在关于生成器的内容中所讲，<code>close()</code>操作将会在协程内部<code>yield</code>位置处引发<code>GenaratorExit</code>异常，你可以选择捕捉它。另外调用<code>throw(exctype[,value[,tb]])</code>方法也会在协程内部<code>yield</code>位置处引发异常，异常的类型、值和跟踪对象分别由<code>exctype</code>、<code>value</code>和<code>tb</code>参数指定</p><p>如果赋值号右边的<code>yield</code>语句本身含有表达式（不同于上面的<code>var=yield</code>，而是<code>var=yield expression</code>的形式），这个表达式的值将作为<code>send()</code>方法的返回值，此时协程可以使用<code>yield</code>语句同时接收和发出返回值，下面看一个生产者和消费者的示例：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line"><span class="meta">@coroutine</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">consumer</span>():</span><br><span class="line">    r = <span class="literal">None</span></span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        n = <span class="keyword">yield</span> r</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;[CONSUMER] Consuming %s...&#x27;</span> % n)</span><br><span class="line">        time.sleep(<span class="number">1</span>)</span><br><span class="line">        r = <span class="string">&#x27;200 OK&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">producer</span>(<span class="params">c</span>):</span><br><span class="line">    n = <span class="number">0</span></span><br><span class="line">    <span class="keyword">while</span> n &lt; <span class="number">5</span>:</span><br><span class="line">        n += <span class="number">1</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;[PRODUCER] Producing %s...&#x27;</span> % n)</span><br><span class="line">        r = c.send(n) <span class="comment">#将生产值发送给消费者，并接收消费者的反馈</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;[PRODUCER] Consumer return: %s&#x27;</span> % r)</span><br><span class="line">    c.close() <span class="comment">#生产结束后关闭消费者，当然也可以在外面关闭</span></span><br><span class="line">    </span><br><span class="line">c = consumer()</span><br><span class="line">producer(c)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">[PRODUCER] Producing 1...</span></span><br><span class="line"><span class="string">[CONSUMER] Consuming 1...</span></span><br><span class="line"><span class="string">[PRODUCER] Consumer return: 200 OK</span></span><br><span class="line"><span class="string">[PRODUCER] Producing 2...</span></span><br><span class="line"><span class="string">[CONSUMER] Consuming 2...</span></span><br><span class="line"><span class="string">[PRODUCER] Consumer return: 200 OK</span></span><br><span class="line"><span class="string">[PRODUCER] Producing 3...</span></span><br><span class="line"><span class="string">[CONSUMER] Consuming 3...</span></span><br><span class="line"><span class="string">[PRODUCER] Consumer return: 200 OK</span></span><br><span class="line"><span class="string">[PRODUCER] Producing 4...</span></span><br><span class="line"><span class="string">[CONSUMER] Consuming 4...</span></span><br><span class="line"><span class="string">[PRODUCER] Consumer return: 200 OK</span></span><br><span class="line"><span class="string">[PRODUCER] Producing 5...</span></span><br><span class="line"><span class="string">[CONSUMER] Consuming 5...</span></span><br><span class="line"><span class="string">[PRODUCER] Consumer return: 200 OK</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>需要注意的是，最开始的<code>next()</code>调用只会执行到赋值号右边的<code>(yield [expression])</code>处（且直到执行<code>send()</code>时才会完成赋值），并返回<code>yield</code>中的表达式<code>expression</code>值，在接下来的<code>send()</code>调用中，协程将从暂停处继起，直到再次遇到<code>(yield [expression])</code>暂停，并将此时计算得到的<code>expression</code>作为<code>send()</code>方法的返回值</p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="py2-2-5"><ul><li><p>列表生成式</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>ret=[x * x <span class="keyword">for</span> x <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>)]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>ret</span><br><span class="line">[<span class="number">0</span>, <span class="number">1</span>, <span class="number">4</span>, <span class="number">9</span>, <span class="number">16</span>, <span class="number">25</span>, <span class="number">36</span>, <span class="number">49</span>, <span class="number">64</span>, <span class="number">81</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">type</span>(_)</span><br><span class="line">&lt;<span class="keyword">class</span> <span class="string">&#x27;list&#x27;</span>&gt;</span><br></pre></td></tr></table></figure></li><li><p>集合生成式</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>ret=&#123;x * x <span class="keyword">for</span> x <span class="keyword">in</span> [-<span class="number">5</span>,-<span class="number">3</span>,-<span class="number">1</span>,<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>]&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>ret</span><br><span class="line">&#123;<span class="number">25</span>, <span class="number">9</span>, <span class="number">1</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">type</span>(_)</span><br><span class="line">&lt;<span class="keyword">class</span> <span class="string">&#x27;set&#x27;</span>&gt;</span><br></pre></td></tr></table></figure></li><li><p>字典生成式</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>ret=&#123;x:x <span class="keyword">for</span> x <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">5</span>)&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>ret</span><br><span class="line">&#123;<span class="number">0</span>: <span class="number">0</span>, <span class="number">1</span>: <span class="number">1</span>, <span class="number">2</span>: <span class="number">2</span>, <span class="number">3</span>: <span class="number">3</span>, <span class="number">4</span>: <span class="number">4</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">type</span>(_)</span><br><span class="line">&lt;<span class="keyword">class</span> <span class="string">&#x27;dict&#x27;</span>&gt;</span><br></pre></td></tr></table></figure></li><li><p>生成器表达式</p><p>和列表生成式几乎一样，只不过将中括号<code>[]</code>替换成<code>()</code>即可，返回的是生成器对象</p></li></ul><p>注1，以上所有的生成式都支持多重<code>for</code>循环，如：<code>[(i,j,k) for i in range(4) for j in range(3) for k in range(2)]</code>（注意<code>for</code>循环的顺序是从左至右的，即左边<code>for</code>循环的迭代变量可以出现在右边<code>for</code>循环中但是反之不可以），譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>ret=((x,y) <span class="keyword">for</span> x <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">5</span>) <span class="keyword">for</span> y <span class="keyword">in</span> <span class="built_in">range</span>(x))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>ret</span><br><span class="line">&lt;generator <span class="built_in">object</span> &lt;genexpr&gt; at <span class="number">0x0000024BBAABBF10</span>&gt;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">list</span>(_)</span><br><span class="line">[(<span class="number">1</span>, <span class="number">0</span>), (<span class="number">2</span>, <span class="number">0</span>), (<span class="number">2</span>, <span class="number">1</span>), (<span class="number">3</span>, <span class="number">0</span>), (<span class="number">3</span>, <span class="number">1</span>), (<span class="number">3</span>, <span class="number">2</span>), (<span class="number">4</span>, <span class="number">0</span>), (<span class="number">4</span>, <span class="number">1</span>), (<span class="number">4</span>, <span class="number">2</span>), (<span class="number">4</span>, <span class="number">3</span>)]</span><br></pre></td></tr></table></figure><p>注2，以上所有的生成式都可以搭配<code>if</code>条件判断（没有<code>else</code>），以列表生成式为例：<code>[expression for i in iterable if condition]</code>（条件判断的作用同<code>filter()</code>函数，用于过滤序列中的部分元素），由于<code>expression</code>本身也可以是一个条件表达式，因此还可以写成：<code>[expression1 if condition else expression2 for i in iterable]</code>，示例：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>[i <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>) <span class="keyword">if</span> i%<span class="number">3</span>==<span class="number">0</span>] <span class="comment">#从0-9的序列中筛选出3的整数倍</span></span><br><span class="line">[<span class="number">0</span>, <span class="number">3</span>, <span class="number">6</span>, <span class="number">9</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>[(<span class="number">1</span> <span class="keyword">if</span> i%<span class="number">3</span>==<span class="number">0</span> <span class="keyword">else</span> <span class="number">0</span>) <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>)] <span class="comment">#如果是3的整数倍，则置为1否则置为0</span></span><br><span class="line">[<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>[<span class="string">&#x27;3+&#x27;</span> <span class="keyword">if</span> i&gt;<span class="number">3</span> <span class="keyword">else</span> <span class="built_in">str</span>(i) <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>) <span class="keyword">if</span> i%<span class="number">3</span>==<span class="number">0</span>] <span class="comment">#从0-9的序列中筛选出3的整数倍，且是字符串形式，进一步，如果大于6，则置为&#x27;3+&#x27;</span></span><br><span class="line">[<span class="string">&#x27;0&#x27;</span>, <span class="string">&#x27;3&#x27;</span>, <span class="string">&#x27;3+&#x27;</span>, <span class="string">&#x27;3+&#x27;</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>[(i,j) <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">5</span>) <span class="keyword">if</span> i&gt;<span class="number">2</span> <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">3</span>)]</span><br><span class="line">[(<span class="number">3</span>, <span class="number">0</span>), (<span class="number">3</span>, <span class="number">1</span>), (<span class="number">3</span>, <span class="number">2</span>), (<span class="number">4</span>, <span class="number">0</span>), (<span class="number">4</span>, <span class="number">1</span>), (<span class="number">4</span>, <span class="number">2</span>)]</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><!-- 真心感觉我的能力还不如两年前呢，难道真的是因为我撸多了，真身心俱疲 --><div class="tip fas fa-quote-left"><p>[1] <a href="https://pan.baidu.com/s/17r__wNMxIXTMWhglf3wyuw" title="密码：1y2r" target="_blank"><span style="color:red">Python参考手册</span> 第4版 修订版 [美] 大卫·M.比兹利（David M.Beazley）著，谢俊，杨越，高伟 译</a></p></div>]]></content>
      
      
      <categories>
          
          <category> 计算机基础 </category>
          
          <category> 编程语言 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> Python </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>Python基础 - 类型和对象</title>
      <link href="posts/5311/"/>
      <url>posts/5311/</url>
      
        <content type="html"><![CDATA[<div class="note green icon flat"><i class="note-icon fas fa-rocket"></i><p>📚 文档目录 <!--说实话后几章节普遍写得不太满意，主要是为面试公开，第三篇尚有待完善--><br>🎃 类型和对象 - 🎈 <a href="/posts/176/"><span style="color:#3a96dd">程序结构与函数编程</span></a> - 🎏 <a href="/posts/22901/"><span style="color:#3a96dd">面向对象编程</span></a></p></div><div class="note warning simple"><p>由于页面中的某些内容嵌套在了多重标签插件下，使得宽度变得过于狭窄，特别是手机端体验会很差，建议在电脑端阅读<!--，后面我会注意避免该问题--></p></div><div style="display:none;"><div class="note danger simple"><p>该笔记内容可能存在一些错误，如果您能够帮助指正，鄙人将非常感谢</p></div></div><h2 id="对象的身份与类型">对象的身份与类型</h2><p>Python中<span class="inline-tag red">一切皆对象</span>，包括一些常见的基础数据类型，如数字、字符串、列表、字典等，还有用户所自定义的对象（对象也称为类型的“实例”）。对象具有三大特征：</p><ol><li>身份（id），可以理解为在内存中的地址，具有唯一性，可以通过<code>id(obj)</code>查看</li><li>类型（type），对象都是由类实例化产生的，对象所属类型可通过<code>type(obj)</code>或<code>obj.__class__</code>查看</li><li>值（value），不同对象具有不同值（体现在“属性”和“方法”的不同上），这也是其存在的现实意义</li></ol><div class="note simple"><p>对象被创建后，其身份和类型就不可改变，根据其值是否可变，可以区分为“可变对象”与“不可变对象”</p></div><p>从身份、类型和值三个不同的角度分别比较对象：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">compare</span>(<span class="params">a, b</span>):</span><br><span class="line">    <span class="keyword">if</span> a <span class="keyword">is</span> b:</span><br><span class="line">        <span class="keyword">pass</span> <span class="comment">#a和b是同一个对象，或者说a和b指向同一内存地址</span></span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">type</span>(a) <span class="keyword">is</span> <span class="built_in">type</span>(b):</span><br><span class="line">        <span class="keyword">pass</span> <span class="comment">#a和b属于同一类型</span></span><br><span class="line">    <span class="keyword">if</span> a == b:</span><br><span class="line">        <span class="keyword">pass</span> <span class="comment">#a和b具有相同值</span></span><br></pre></td></tr></table></figure><div class="note warning flat"><p>当使用<code>==</code>运算符时，请务必确保<code>a==b</code>中的左值对象<code>a</code>所属类型已重载了<code>__eq__</code>方法（特别提醒用户自定义对象，python中已有的基础对象类型都已经重载了该方法），否则比较是无实际意义的，须知<code>a==b</code>等同于执行<code>a.__eq__(b)</code>，而一切对象继承自<code>object</code>类型，<code>object</code>类型的<code>__eq__</code>方法其实比较的是身份（<code>return a is b</code>）。一般来说<code>is</code>用得较少，因为在实际场景中，要比较两个对象是否相等，并不是通过内存地址来判断的，而是应该通过这两个对象的部分属性值，或者全部属性值来对比判断的<br>注：在描述时，<code>obj</code>泛指的是任意python对象，而<code>object</code>则特指万物始祖之基类</p></div><div class="note info flat"><p>Python中全部8种比较运算：<code>&gt;</code>（对应<code>__gt__()</code>）, <code>&gt;=</code>（对应<code>__ge__()</code>）, <code>&lt;</code>（对应<code>__lt__()</code>）, <code>&lt;=</code>（对应<code>__le__()</code>）, <code>==</code>, <code>!==</code>（对应<code>__ne__()</code>）, <code>is</code>, <code>is not</code>。其他就不说了，<code>is</code>用在什么地方？<br>或许你已知道<code>==None</code>是不推荐使用的，应替换为<code>is None</code>，这基于两点理由：1）<code>None</code>在python中是一个单例对象（<code>None</code>作为对象也具有自己的类型，但是你无法用这个类型创造出另一个<code>None</code>对象），其内存地址唯一，而身份比较的一个好处就是速度快，因为无需对将要比较的对象本身进行检查，<code>is</code>操作符只需对对象所在的内存地址进行比较，因此采用<code>is None</code>速度更快，2）由于<code>==</code>是可重载的，导致某些非<code>None</code>对象也可能“等于”<code>None</code>，从而致使程序出错，譬如当重载定义为<code>def __eq__(self,other): return True</code>时</p></div><h2 id="类型的类型">类型的类型</h2><p>既然一切皆对象，类型本身作为对象又是谁的实例呢？答：<code>type</code>类。上结论：</p><ul><li>一切类的类都是<code>type</code>，即一切类（包括<code>type</code>自身）都是<code>type</code>类的实例</li><li><code>object</code>是最顶层基类，一切类（除了<code>object</code>自身）追本溯源都继承自<code>object</code></li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>(<span class="built_in">object</span>)) <span class="comment">#&lt;class &#x27;type&#x27;&gt; #基类object作为对象，它的类型是type</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>(<span class="built_in">type</span>)) <span class="comment">#&lt;class &#x27;type&#x27;&gt; #type的类型是其自身</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">object</span>.__base__) <span class="comment">#None #object无父类</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>.__base__) <span class="comment">#&lt;class &#x27;object&#x27;&gt; #type作为类，直接继承自object</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>.__base__) <span class="comment">#&lt;class &#x27;object&#x27;&gt; #list、tuple、dict等以及自定义类都继承自object，类型为type</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>(<span class="built_in">list</span>)) <span class="comment">#&lt;class &#x27;type&#x27;&gt;</span></span><br></pre></td></tr></table></figure><div class="img-wrap"><div class="img-bg"><img class="img" src="https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210425185857.png" alt="图1.&nbsp;object类和type类：图中虚线是实例关系、实线是继承关系[3]" onerror="this.onerror=null,this.src='https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210328224519.jpg'" /></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>isinstance()</code>类型判断</span></div>    <div class="hide-content"><p>早先在书上偶然看到一行代码<code>isinstance(A,object) #返回True</code>，其中<code>A</code>是一个自定义类，突然很不理解，没回过味来，还在<a href="https://segmentfault.com/q/1010000019754936">SegmentFault</a>上提问，好蠢/(ㄒoㄒ)/~~</p><p>根据帮助文档（<code>help(isinstance)</code>）可知：<code>isinstance(obj, class_or_tuple)</code>判断对象<code>obj</code>是否是<code>class_or_tuple</code>中某个类的实例或者其子类的实例。假设<code>A</code>继承自<code>B</code>，<code>a=A()</code>，那么显然<code>isinstance(a,A)</code>返回<code>True</code>，由于<code>B</code>是<code>A</code>的父类，所以<code>B</code>是<code>a</code>所属的更大的类的范畴，所以<code>isinstance(a,B)</code>也返回<code>True</code>，即<code>a</code>是<code>B</code>的实例。根据上面<code>object</code>类和<code>type</code>类之间的关系很容易推知：一切类（包括<code>object</code>和<code>type</code>）都是<code>object</code>的实例</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">class</span> <span class="title class_">A</span>: <span class="keyword">pass</span></span><br><span class="line">...</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">isinstance</span>(A(),<span class="built_in">object</span>)</span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">isinstance</span>(A,<span class="built_in">object</span>)</span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">isinstance</span>(<span class="built_in">object</span>,<span class="built_in">object</span>)</span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">isinstance</span>(<span class="built_in">type</span>,<span class="built_in">object</span>)</span><br><span class="line"><span class="literal">True</span></span><br></pre></td></tr></table></figure><p>官方建议当我们需要判断一个对象类型的时候应当使用<code>isinstance()</code>，虽然可以使用<code>type()</code>做“简单”类型判断，“简单”的原因在于，它无法判断一个对象是否属于其基类这一更大的范畴，譬如无法判断一只鹦鹉个体是否属于鸟类（谬论一），而只能判断它是鹦鹉类别</p><p>鹦鹉不是鸟：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">class</span> <span class="title class_">Bird</span>: <span class="keyword">pass</span></span><br><span class="line">...</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">class</span> <span class="title class_">Parrot</span>(<span class="title class_ inherited__">Bird</span>): <span class="keyword">pass</span></span><br><span class="line">...</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=Parrot()</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">type</span>(a) <span class="keyword">is</span> Parrot</span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">type</span>(a) <span class="keyword">is</span> Bird</span><br><span class="line"><span class="literal">False</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">isinstance</span>(a,Bird)</span><br><span class="line"><span class="literal">True</span></span><br></pre></td></tr></table></figure><p>另外在旧式类（完全没必要了解）中<code>type()</code>还具有一个缺陷，譬如两个完全不同的类实例竟然能得出“类型相同”的结果（谬论二），狗和猫是同类？示例如下（python2环境）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">class</span> <span class="title class_">Dog</span>: <span class="keyword">pass</span></span><br><span class="line">...</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">class</span> <span class="title class_">Cat</span>: <span class="keyword">pass</span></span><br><span class="line">...</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d=Dog()</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>c=Cat()</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">type</span>(d) <span class="keyword">is</span> <span class="built_in">type</span>(c)</span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">type</span>(d)</span><br><span class="line">&lt;<span class="built_in">type</span> <span class="string">&#x27;instance&#x27;</span>&gt;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">isinstance</span>(d,Cat)</span><br><span class="line"><span class="literal">False</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">class</span> <span class="title class_">Shiba</span>(<span class="title class_ inherited__">Dog</span>): <span class="keyword">pass</span></span><br><span class="line">...</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">type</span>(Shiba())</span><br><span class="line">&lt;<span class="built_in">type</span> <span class="string">&#x27;instance&#x27;</span>&gt;</span><br></pre></td></tr></table></figure><p>对于新式类来说，实例化后的对象类型就是该类，这不容置疑，但是旧式类中没有基类<code>object</code>，实例化后的对象类型都是<code>instance</code><br><a href="https://segmentfault.com/q/1010000000127305">补充</a>：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">from</span> collections <span class="keyword">import</span> Iterator</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">class</span> <span class="title class_">A</span>:</span><br><span class="line"><span class="meta">... </span>    <span class="keyword">def</span> <span class="title function_">__iter__</span>(<span class="params">self</span>):</span><br><span class="line"><span class="meta">... </span>        ...</span><br><span class="line"><span class="meta">... </span>    <span class="keyword">def</span> <span class="title function_">__next__</span>(<span class="params">self</span>):</span><br><span class="line"><span class="meta">... </span>        ...</span><br><span class="line">...</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">isinstance</span>(A(), Iterator)</span><br><span class="line"><span class="literal">True</span></span><br></pre></td></tr></table></figure><p>由此可见，python是根据“鸭子类型”的思想来进行类型判断的，即当看到一只鸟走起来像鸭子、游泳起来像鸭子、声音叫起来也像鸭子，那么这只鸟就可以被认为是鸭子，上述示例尽管<code>A</code>直接继承自<code>object</code>，但由于它实现了<code>__iter__()</code>和<code>__next__()</code>，因而<code>A()</code>被认为是一个迭代器对象</p></div></div><h2 id="对象的引用与复制">对象的引用与复制</h2><p>在程序进行像<code>a=b</code>这样的赋值时，就会创建一个对<code>b</code>的新引用，对于像数字和字符串这样的不可变对象，这种赋值实际上创建了<code>b</code>的一个副本，修改<code>b</code>并不影响<code>a</code>，然而，对于可变对象（如列表和字典），行为则完全不同，譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b = a <span class="comment">#b和a指向内存中同一位置的对象</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b <span class="keyword">is</span> a <span class="comment">#id(a)==id(b)</span></span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b[<span class="number">2</span>] = -<span class="number">100</span> <span class="comment">#修改容器b中一个元素</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a <span class="comment">#此时a仍指向b所指向的对象，所以a的内容也相应改变</span></span><br><span class="line">[<span class="number">1</span>, <span class="number">2</span>, -<span class="number">100</span>, <span class="number">4</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>c = d = <span class="number">12</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>c = <span class="number">13</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d</span><br><span class="line"><span class="number">12</span></span><br></pre></td></tr></table></figure><p>也就是说当两个变量引用指向同一个可变对象时，修改其中任意一个变量都会影响到另一个，为了避免这种情况，必须创建对象的副本而不是新引用。事实上对于像列表和字典这样的容器对象，存在两种复制操作：浅复制和深复制。浅复制虽然创建了一个新对象（体现在id变化），但它包含的还是对原始对象中所包含的元素（假设这个元素是可变对象的话）的引用，譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=[<span class="number">1</span>,<span class="number">2</span>,[<span class="number">3</span>,<span class="number">4</span>]] <span class="comment">#a中第三个元素是可变对象（所谓可变对象就是对象的值变了，但其在内存中的地址仍保持不变，而改变不可变对象的值，将会在内存中新开辟一块内存存放修改后的对象）</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=<span class="built_in">list</span>(a) <span class="comment">#list工厂函数属于浅复制，还有切片操作也是浅复制</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">[<span class="number">1</span>, <span class="number">2</span>, [<span class="number">3</span>, <span class="number">4</span>]]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">0</span>]=<span class="number">8</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">[<span class="number">1</span>, <span class="number">2</span>, [<span class="number">3</span>, <span class="number">4</span>]]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">2</span>][<span class="number">0</span>]=<span class="number">30</span> <span class="comment">#b中第三个元素其实是对a中第三个元素的引用，当a中第三个元素的值发生变化，b中第三个元素也将相应改变</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">[<span class="number">1</span>, <span class="number">2</span>, [<span class="number">30</span>, <span class="number">4</span>]]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">2</span>].append(<span class="number">5</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">[<span class="number">1</span>, <span class="number">2</span>, [<span class="number">30</span>, <span class="number">4</span>, <span class="number">5</span>]]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">2</span>]=[<span class="number">11</span>,<span class="number">12</span>] <span class="comment">#该赋值使得a中第三个元素指向了内存中另一个区域的（一个列表）对象，从而对列表[30,4,5]的引用计数减1，还剩下b中第三个元素对它的唯一引用</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">[<span class="number">1</span>, <span class="number">2</span>, [<span class="number">30</span>, <span class="number">4</span>, <span class="number">5</span>]]</span><br></pre></td></tr></table></figure><p>深复制也将创建一个新对象，且会递归地遍历它所包含的所有对象并创建其副本，需借助标准库中的<code>copy.deepcopy()</code>函数完成此操作</p><h2 id="基础数据类型">基础数据类型</h2><div class="tabs" id="dytab1"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#dytab1-1">None</button></li><li class="tab"><button type="button" data-href="#dytab1-2">数字</button></li><li class="tab"><button type="button" data-href="#dytab1-3">序列</button></li><li class="tab"><button type="button" data-href="#dytab1-4">映射</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="dytab1-1"><p><code>None</code>类型表示一个空对象，如果一个函数没有显式地返回值，则返回该对象。<code>None</code>经常用作可选参数的默认值，以便让函数检测调用者是否为该参数实际传递了值。<code>None</code>没有任何属性，在布尔表达式中求值时为<code>False</code></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="dytab1-2"><p>Python内置了5种数字类型（都是不可变对象）：布尔型（<code>bool</code>）、整型（<code>int</code>）、长整型（<code>long</code>，目前好像没有<code>long</code>这一类型了，并入<code>int</code>）、浮点型（<code>float</code>）以及复数型（<code>complex</code>）。布尔值包括<code>True</code>和<code>False</code>两个值（参与数值运算时分别映射为数值1和0）。整数表示范围在-2147483648和2147483647（对应<span class="hide-inline"><button type="button" class="hide-button button--animated" style="">32位二进制数<br></button><span class="hide-content">0111,1111,1111,1111,1111,1111,1111,1111</span></span>，其最高位为符号位）之间的所有整数。浮点型是用机器上浮点数的本机双精度（64bit）表示的，提供大约17位数的精度和范围从-308到308的指数。复数使用一对浮点数表示（<code>complex(1,2)</code>），复数的实部和虚部分别使用<code>.real</code>和<code>.imag</code>访问，<code>.conjugate()</code>用于计算复共轭（a+bj的共轭是a-bj）</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>d=&#123;&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d[<span class="literal">True</span>] = <span class="string">&quot;JavaScript&quot;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d[<span class="number">1</span>] = <span class="string">&quot;Ruby&quot;</span> <span class="comment">#根据字典的原理，首先计算键1的哈希，于是找到了键True的存储位置，又发现True==1，于是认为这两个键是同一对象，于是直接将新值&#x27;Ruby&#x27;替换旧值&#x27;JavaScript&#x27;完事儿，于是现在字典中的数据变成了&#123;True:&#x27;Ruby&#x27;&#125;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d[<span class="number">1.0</span>] = <span class="string">&quot;Python&quot;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d.keys()</span><br><span class="line">dict_keys([<span class="literal">True</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d[<span class="literal">True</span>]</span><br><span class="line"><span class="string">&#x27;Python&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d[<span class="number">1.0</span>]</span><br><span class="line"><span class="string">&#x27;Python&#x27;</span></span><br></pre></td></tr></table></figure><div class="note info simple"><p><a href="https://github.com/leisurelicht/wtfpython-cn#-whats-wrong-with-booleans%E5%B8%83%E5%B0%94%E4%BD%A0%E5%92%8B%E4%BA%86">布尔类型</a>是<code>int</code>类型的子类（如<code>isinstance(True,int)</code>为<code>True</code>），其满足<code>True == 1 == 1.0 and False == 0 == 0.0</code>为<code>True</code>的条件，换句话说，<code>True</code>、<code>1</code>、<code>1.0</code>这三个对象具有相同的哈希（同样<code>False</code>、<code>0</code>、<code>0.0</code>也是如此），在将其用作字典的键时，将映射到同一个值</p></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>进制转换</span></div>    <div class="hide-content"><p>先说一下<code>int(x, base)</code>方法，其根据给定的进制<code>base</code>（取值为0、2~36，为什么最高是36？因为26个英文字母加上10个数字总计36，譬如有一个16进制数：<code>e1</code>，其十进制结果为225）将数字字符串<code>x</code>转换为十进制整数，也可用于将一个浮点数转换为整型（非字符串时不能传递<code>base</code>参数）。特别的，<code>base</code>取值为0时，将按照字符串的字面意思进行解释，譬如给定的字符串为<code>0o16</code>，此时不必明确告知<code>base=8</code>，因为<code>0o</code>打头的就表示这是一个八进制数。默认的<code>base</code>值为10，即默认将一个十进制数字字符串转换为十进制整型（<code>int('1314')=1314</code>）</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#2、8、16进制转为10进制</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">int</span>(<span class="string">&#x27;10010&#x27;</span>,<span class="number">2</span>) <span class="comment">#int(&#x27;0b10010&#x27;,0)</span></span><br><span class="line"><span class="number">18</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">int</span>(<span class="string">&#x27;32&#x27;</span>,<span class="number">8</span>) <span class="comment">#int(&#x27;0o32&#x27;,0)</span></span><br><span class="line"><span class="number">26</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">int</span>(<span class="string">&#x27;e1&#x27;</span>,<span class="number">16</span>) <span class="comment">#int(&#x27;0xe1&#x27;,0)</span></span><br><span class="line"><span class="number">225</span></span><br></pre></td></tr></table></figure><p>总而言之，<code>int()</code>只能用于将2~36进制的数（且为字符串类型）转换为10进制，如果你要将一个10进制数转换为2进制、8进制转为2进制、2进制转为8进制等等那它就无能为力了，下面介绍<code>bin()</code>、<code>oct()</code>以及<code>hex()</code>，分别用于将一个整数（这个整数可以是10进制的，也可以是2进制、8进制和16进制的）转换为2进制、8进制以及16进制：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#10进制转2进制</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">bin</span>(<span class="number">18</span>)</span><br><span class="line"><span class="string">&#x27;0b10010&#x27;</span></span><br><span class="line"><span class="comment">#8进制转2进制</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">bin</span>(<span class="number">0o22</span>)</span><br><span class="line"><span class="string">&#x27;0b10010&#x27;</span></span><br><span class="line"><span class="comment">#16进制转2进制</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">bin</span>(<span class="number">0x12</span>)</span><br><span class="line"><span class="string">&#x27;0b10010&#x27;</span></span><br><span class="line"><span class="comment">#10进制转8进制</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">oct</span>(<span class="number">26</span>)</span><br><span class="line"><span class="string">&#x27;0o32&#x27;</span></span><br><span class="line"><span class="comment">#2进制转8进制</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">oct</span>(<span class="number">0b11010</span>)</span><br><span class="line"><span class="string">&#x27;0o32&#x27;</span></span><br><span class="line"><span class="comment">#16进制转8进制</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">oct</span>(<span class="number">0x1a</span>)</span><br><span class="line"><span class="string">&#x27;0o32&#x27;</span></span><br><span class="line"><span class="comment">#10进制转16进制</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">hex</span>(<span class="number">225</span>)</span><br><span class="line"><span class="string">&#x27;0xe1&#x27;</span></span><br><span class="line"><span class="comment">#2进制转16进制</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">hex</span>(<span class="number">0b11100001</span>)</span><br><span class="line"><span class="string">&#x27;0xe1&#x27;</span></span><br><span class="line"><span class="comment">#8进制转16进制</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">hex</span>(<span class="number">0o341</span>)</span><br><span class="line"><span class="string">&#x27;0xe1&#x27;</span></span><br></pre></td></tr></table></figure><p>以上描述了2、8、10、16进制数之间的相互转换，那么任意进制（2~36）之间如何相互转换呢，可以借助10进制数作为中间状态，代码如下：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> partial</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">transform</span>(<span class="params">x,base=<span class="literal">None</span>,to=<span class="literal">None</span></span>):</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;将base进制整数x转换为to进制数y，函数返回y</span></span><br><span class="line"><span class="string">        合法的进制范围为2~36，</span></span><br><span class="line"><span class="string">        x是一个字符串，是为了通用性考虑，因为整</span></span><br><span class="line"><span class="string">        数类型只涵盖了2、8、10、16进制，譬如16：</span></span><br><span class="line"><span class="string">        0b10000、0o20、16、0x10，但是其36进制为</span></span><br><span class="line"><span class="string">        g，只能以字符串形式表示，特别的，输入允</span></span><br><span class="line"><span class="string">        许以&#x27;0b&#x27;、&#x27;0o&#x27;、&#x27;0x&#x27;打头(此时base可以不</span></span><br><span class="line"><span class="string">        给或任意)，也可以不是，但</span></span><br><span class="line"><span class="string">        是作为输出的2、8、16进制数字字符串一律不</span></span><br><span class="line"><span class="string">        会以&#x27;0b&#x27;、&#x27;0o&#x27;、&#x27;0x&#x27;打头。</span></span><br><span class="line"><span class="string">        转换原理是，将base进制先转换为10进制，再</span></span><br><span class="line"><span class="string">        将这个10进制转换为to进制</span></span><br><span class="line"><span class="string">    &#x27;&#x27;&#x27;</span></span><br><span class="line">    x=x.lower()</span><br><span class="line">    x_10=<span class="number">0</span></span><br><span class="line">    <span class="keyword">if</span> x[:<span class="number">2</span>] <span class="keyword">in</span> [<span class="string">&#x27;0b&#x27;</span>,<span class="string">&#x27;0o&#x27;</span>,<span class="string">&#x27;0x&#x27;</span>]:</span><br><span class="line">        x_10=<span class="built_in">int</span>(x,<span class="number">0</span>)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">for</span> i,e <span class="keyword">in</span> <span class="built_in">enumerate</span>(x[::-<span class="number">1</span>]):</span><br><span class="line">            x_10+=(<span class="built_in">pow</span>(base,i)*(<span class="built_in">ord</span>(e)-<span class="built_in">ord</span>(<span class="string">&#x27;a&#x27;</span>)+<span class="number">10</span> <span class="keyword">if</span> <span class="string">&#x27;a&#x27;</span>&lt;=e&lt;=<span class="string">&#x27;z&#x27;</span> <span class="keyword">else</span> <span class="built_in">int</span>(e)))</span><br><span class="line">    y=<span class="string">&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">while</span> x_10&gt;<span class="number">0</span>:</span><br><span class="line">        t=x_10%to</span><br><span class="line">        y+=(<span class="built_in">chr</span>(<span class="built_in">ord</span>(<span class="string">&#x27;a&#x27;</span>)+t-<span class="number">10</span>) <span class="keyword">if</span> t&gt;<span class="number">9</span> <span class="keyword">else</span> <span class="built_in">str</span>(t))</span><br><span class="line">        x_10//=to</span><br><span class="line">    <span class="keyword">return</span> y[::-<span class="number">1</span>] <span class="keyword">if</span> y!=<span class="string">&#x27;&#x27;</span> <span class="keyword">else</span> <span class="string">&#x27;0&#x27;</span></span><br><span class="line">    </span><br><span class="line">transform(<span class="string">&#x27;16&#x27;</span>,base=<span class="number">10</span>,to=<span class="number">36</span>) <span class="comment">#g</span></span><br><span class="line">f2t16=partial(transform,base=<span class="number">2</span>,to=<span class="number">16</span>) <span class="comment">#from 2 to 16</span></span><br><span class="line">f2t16(<span class="string">&#x27;11100001&#x27;</span>) <span class="comment">#e1</span></span><br></pre></td></tr></table></figure><p>上述代码中十进制转任意进制部分，有人给出了<a href="https://www.zhihu.com/answer/1878284306">递归</a>写法（我用的循环）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">transform_10_to_any</span>(<span class="params">n,base</span>):</span><br><span class="line">    string=<span class="string">&#x27;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ&#x27;</span> <span class="comment">#&#x27;&#x27;.join([*[str(i) for i in range(10)],*[chr(ord(&#x27;A&#x27;)+i) for i in range(26)]])</span></span><br><span class="line">    <span class="keyword">if</span> n&lt;base:</span><br><span class="line">        <span class="keyword">return</span> string[n]</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">return</span> transform_10_to_any(n//base,base)+string[n%base]</span><br><span class="line">        </span><br><span class="line"><span class="built_in">print</span>(transform_10_to_any(<span class="number">28</span>,<span class="number">16</span>)) <span class="comment">#1C</span></span><br><span class="line"><span class="built_in">print</span>(transform_10_to_any(<span class="number">28</span>**<span class="number">690</span>,<span class="number">10</span>)) <span class="comment">#RecursionError: maximum recursion depth exceeded in comparison</span></span><br></pre></td></tr></table></figure><p>由于存在递归深度限制，我将其改造成了尾递归版本，并使用<code>@tail_call_optimized</code>（见后，序列三大操作函数之<code>reduce()</code>案例3）进行修饰：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@tail_call_optimized</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">transform_10_to_any</span>(<span class="params">n,base,temp=<span class="string">&#x27;&#x27;</span></span>):</span><br><span class="line">    string=<span class="string">&#x27;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ&#x27;</span></span><br><span class="line">    <span class="keyword">if</span> n&lt;base:</span><br><span class="line">        <span class="keyword">return</span> string[n]+temp</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">return</span> transform_10_to_any(n//base,base,string[n%base]+temp)</span><br><span class="line">        </span><br><span class="line"><span class="built_in">print</span>(transform_10_to_any(<span class="number">28</span>**<span class="number">690</span>,<span class="number">10</span>))</span><br></pre></td></tr></table></figure><p>注，任意进制转10进制的办法：<emp>按权相加</emp>，例如，将8进制数字 53627 转换成10进制：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0</mn><mi>o</mi><mn>53627</mn><mo>=</mo><mn>5</mn><mo>×</mo><msup><mn>8</mn><mn>4</mn></msup><mo>+</mo><mn>3</mn><mo>×</mo><msup><mn>8</mn><mn>3</mn></msup><mo>+</mo><mn>6</mn><mo>×</mo><msup><mn>8</mn><mn>2</mn></msup><mo>+</mo><mn>2</mn><mo>×</mo><msup><mn>8</mn><mn>1</mn></msup><mo>+</mo><mn>7</mn><mo>×</mo><msup><mn>8</mn><mn>0</mn></msup><mo>=</mo><mn>22423</mn></mrow><annotation encoding="application/x-tex">0o53627 = 5×8^4 + 3×8^3 + 6×8^2 + 2×8^1 + 7×8^0 = 22423</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span><span class="mord mathnormal">o</span><span class="mord">5</span><span class="mord">3</span><span class="mord">6</span><span class="mord">2</span><span class="mord">7</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">5</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">8</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">3</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">8</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">6</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">8</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">8</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">7</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">8</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span><span class="mord">2</span><span class="mord">4</span><span class="mord">2</span><span class="mord">3</span></span></span></span> (十进制)。所谓“权”（即位权），对于一个8进制数，从左往右看，第1位的位权为 8<sup>0</sup>=1，第2位的位权为 8<sup>1</sup>=8，第3位的位权为 8<sup>2</sup>=64，第4位的位权为 8<sup>3</sup>=512，第5位的位权为 8<sup>4</sup>=4096 …… 第n位的位权就为 8<sup>n-1</sup>，将各个位的数字乘以位权，然后再相加，就得到了十进制数值</p><p>将十进制转为任意N进制的办法，<emp>除N取余，逆序排列</emp>，例如将一个10进制数转换为8进制（36926 → 110076）：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">36926/8 = 4615(除数) ··· 6(余数)</span><br><span class="line">4615  /8 = 576              ··· 7</span><br><span class="line">576    /8 = 72                ··· 0</span><br><span class="line">72      /8 = 9                  ··· 0</span><br><span class="line">9        /8 = 1                  ··· 1</span><br><span class="line">1        /8 = 0                  ··· 1(除数为0时停止)</span><br></pre></td></tr></table></figure><p>以上说的都是整数，那么如何对小数部分进行进制转换呢？例如将一个浮点数从8进制转换为10进制（还是<emp>按权相加</emp>）：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>423.5176</mn></mrow><annotation encoding="application/x-tex">423.5176</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span><span class="mord">2</span><span class="mord">3</span><span class="mord">.</span><span class="mord">5</span><span class="mord">1</span><span class="mord">7</span><span class="mord">6</span></span></span></span> (八进制) <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>=</mo><mn>4</mn><mo>×</mo><msup><mn>8</mn><mn>2</mn></msup><mo>+</mo><mn>2</mn><mo>×</mo><msup><mn>8</mn><mn>1</mn></msup><mo>+</mo><mn>3</mn><mo>×</mo><msup><mn>8</mn><mn>0</mn></msup><mo>+</mo><mn>5</mn><mo>×</mo><msup><mn>8</mn><mrow><mo>−</mo><mn>1</mn></mrow></msup><mo>+</mo><mn>1</mn><mo>×</mo><msup><mn>8</mn><mrow><mo>−</mo><mn>2</mn></mrow></msup><mo>+</mo><mn>7</mn><mo>×</mo><msup><mn>8</mn><mrow><mo>−</mo><mn>3</mn></mrow></msup><mo>+</mo><mn>6</mn><mo>×</mo><msup><mn>8</mn><mrow><mo>−</mo><mn>4</mn></mrow></msup><mo>=</mo><mn>275.65576171875</mn></mrow><annotation encoding="application/x-tex">= 4×8^2 + 2×8^1 + 3×8^0 + 5×8^{-1} + 1×8^{-2} + 7×8^{-3} + 6×8^{-4} = 275.65576171875</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.36687em;vertical-align:0em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">8</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">8</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">3</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">8</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">5</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">8</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">8</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">7</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">8</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">3</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">6</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">8</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">4</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span><span class="mord">7</span><span class="mord">5</span><span class="mord">.</span><span class="mord">6</span><span class="mord">5</span><span class="mord">5</span><span class="mord">7</span><span class="mord">6</span><span class="mord">1</span><span class="mord">7</span><span class="mord">1</span><span class="mord">8</span><span class="mord">7</span><span class="mord">5</span></span></span></span> (十进制)。即小数部分和整数部分情况相反，要从左往右看，第1（小数）位的位权为 8<sup>-1</sup>=1/8，第2位的位权为 8<sup>-2</sup>=1/64，第3位的位权为 8<sup>-3</sup>=1/512，第4位的位权为 8<sup>-4</sup>=1/4096 …… 第m位的位权就为 8<sup>-m</sup></p><p>另外如何将一个浮点数从10进制转换为8进制呢？规则为：<emp>乘N取整，顺序排列</emp>，示例如下（0.930908203125 → 7345）：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">0.930908203125×8 = 7.447265625 → 7(取整)</span><br><span class="line">0.447265625      ×8 = 3.578125       → 3</span><br><span class="line">0.578125            ×8 = 4.625             → 4</span><br><span class="line">0.625                  ×8 = 5.0                 → 5(乘数结果小数部分为0时停止)</span><br></pre></td></tr></table></figure><div class="note warning flat"><p>由于浮点计算的不精确性，无法在程序中判断小数点后是否为0，小数进制转换代码就不写了，可能需要借助<a href="https://docs.sympy.org/latest/index.html">Sympy</a>符号运算库？</p></div></div></div><div class="note info flat"><p>日常生活中逗号常见于大整数的表示中，如<code>10,000,000</code>，从python3.6开始支持整数中使用<code>_</code>标记，作用同逗号：<code>a=10_000_000</code>，也适用于十六进制或二进制等：<code>b=0b1_010_101</code></p></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="dytab1-3"><p>Python内置序列对象包括字符串、列表和元组，字符串是字符的序列，而列表和元组是任意对象的序列。字符串和元组均属于不可变对象，而列表支持插入、删除、替换元素操作。所有序列都支持迭代（见可迭代对象）</p><div class="tabs" id="dytab1-1"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#dytab1-1-1">字符串</button></li><li class="tab"><button type="button" data-href="#dytab1-1-2">列表</button></li><li class="tab"><button type="button" data-href="#dytab1-1-3">元组</button></li><li class="tab"><button type="button" data-href="#dytab1-1-4">⭐可迭代对象</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="dytab1-1-1"><p>字符串的方法太多，请参阅文献[1]-p34</p><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>格式化字符串</span></div>    <div class="hide-content"><p>有两种格式化方式：占位符(<code>%</code>)和<code>format()</code>方法</p><ol><li>占位符(<code>%</code>)<br><div class="tabs" id="dy_test_str1"><ul class="nav-tabs"><li class="tab"><button type="button" data-href="#dy_test_str1-1">说明</button></li><li class="tab"><button type="button" data-href="#dy_test_str1-2">示例</button></li></ul><div class="tab-contents"><div class="tab-item-content" id="dy_test_str1-1"><p>取模运算符（<code>s % d</code>）也被用于生成格式化的字符串，其中<code>s</code>是一个格式字符串，而<code>d</code>是一个元组或映射对象（字典），格式字符串包含两种类型：普通字符和转换字符（总是以<code>%</code>打头），格式化程序会根据转换字符将相关元组或映射中的元素转换为对应的输出格式并替换原始的转换字符。如果<code>d</code>是一个元组，转换字符的个数必须与<code>d</code>中对象的个数保持一致，如果<code>d</code>是一个映射，每个转换字符都必须与映射中的一个有效键名相关联</p><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>转换字符</span></div>    <div class="hide-content"><div class="dytable"><table><thead><tr><th style="text-align:center">转换字符</th><th style="text-align:center">输出格式</th></tr></thead><tbody><tr><td style="text-align:center">%c</td><td style="text-align:center">单个字符</td></tr><tr><td style="text-align:center">%s</td><td style="text-align:center">字符串,格式化对象时用str()生成字符串</td></tr><tr><td style="text-align:center">%r</td><td style="text-align:center">字符串,格式化对象时用repr()生成字符串</td></tr><tr><td style="text-align:center">%d,%i</td><td style="text-align:center">(长)整数(十进制)</td></tr><tr><td style="text-align:center">%u</td><td style="text-align:center">无符号(长)整数(十进制)</td></tr><tr><td style="text-align:center">%o</td><td style="text-align:center">(长)整数(八进制)</td></tr><tr><td style="text-align:center">%x</td><td style="text-align:center">(长)整数(十六进制)</td></tr><tr><td style="text-align:center">%X</td><td style="text-align:center">(长)整数(十六进制,大写字母)</td></tr><tr><td style="text-align:center">%e</td><td style="text-align:center">浮点数(科学计数法,如[-]m.dddddde±xx)</td></tr><tr><td style="text-align:center">%E</td><td style="text-align:center">浮点数(科学计数法,如[-]m.ddddddE±xx)</td></tr><tr><td style="text-align:center">%f</td><td style="text-align:center">浮点数(如[-]m.dddddd)</td></tr><tr><td style="text-align:center">%g,%G</td><td style="text-align:center">指数小于-4或更高精度时使用%e或%E,否则使用%f</td></tr><tr><td style="text-align:center">%p</td><td style="text-align:center">指针(用十六进制表示对象的内存地址)</td></tr><tr><td style="text-align:center">%%</td><td style="text-align:center">字面量百分号</td></tr></tbody></table></div></div></div><p>在<code>%</code>和转换字符之间可以出现以下修饰符，并且只能按照下述顺序出现：</p><ol><li>位于括号中的一个键名，用于从映射对象中选出一个具体项，如果不存在此键，则引发<code>KeyError</code>异常</li><li>下面所列的一个或多个<ul><li><code>-</code>，左对齐标志，默认为右对齐</li><li><code>+</code>，表示应该包含数字符号（即使为正值也是如此）</li><li><code>0</code>，表示零填充（仅用于数字类型，如<code>%d</code>、<code>%f</code>）</li></ul></li><li>一个指定最小宽度的数字，转换后的值将被打印在至少为这个宽度的字段中，并且在左边填充至满字段宽（如果指定了<code>-</code>标志，则填充在右边）</li><li>一个小数点，用于按照精度分割字段宽度</li><li>一个数字，指定要打印字符串中的最大字符个数，或者浮点数中小数点之后的位数，或者整数的最小位数</li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="dy_test_str1-2"><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">&#x27;my name is %s%c%c, my age is %d&#x27;</span> % (<span class="string">&#x27;muggle&#x27;</span>,<span class="string">&#x27;d&#x27;</span>,<span class="number">121</span>,<span class="number">23</span>) <span class="comment">#%c还可以接受整数（具体参见ASCII码表，或通过ord()、chr()转换）并转换为对应字符</span></span><br><span class="line"><span class="string">&#x27;my name is muggledy, my age is 23&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d=&#123;<span class="string">&#x27;x&#x27;</span>:<span class="number">13</span>, <span class="string">&#x27;y&#x27;</span>:<span class="number">1.54321</span>, <span class="string">&#x27;z&#x27;</span>:<span class="string">&#x27;hello world&#x27;</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">&#x27;%.5s&#x27;</span> % d[<span class="string">&#x27;z&#x27;</span>]</span><br><span class="line"><span class="string">&#x27;hello&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">&#x27;%(x)05d, %(y).2f&#x27;</span> % d</span><br><span class="line"><span class="string">&#x27;00013, 1.54&#x27;</span></span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>ord()</code>和<code>chr()</code></span></div>    <div class="hide-content"><p>有些论坛不允许新人帖包含url链接，最简单的办法之一是将链接的每个字符转换成ASCII码，其他人再将ASCII转为字符。具体使用<code>ord()</code>函数返回单个字符的ASCII（0-255）以及<code>chr()</code>函数返回一个整数（0-255）对应的字符</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>s=<span class="string">&#x27;http://www.paperpass.com/&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>[<span class="built_in">ord</span>(i) <span class="keyword">for</span> i <span class="keyword">in</span> s] <span class="comment">#编码</span></span><br><span class="line">[<span class="number">104</span>, <span class="number">116</span>, <span class="number">116</span>, <span class="number">112</span>, <span class="number">58</span>, <span class="number">47</span>, <span class="number">47</span>, <span class="number">119</span>, <span class="number">119</span>, <span class="number">119</span>, <span class="number">46</span>, <span class="number">112</span>, <span class="number">97</span>, <span class="number">112</span>, <span class="number">101</span>, <span class="number">114</span>, <span class="number">112</span>, <span class="number">97</span>, <span class="number">115</span>, <span class="number">115</span>, <span class="number">46</span>, <span class="number">99</span>, <span class="number">111</span>, <span class="number">109</span>, <span class="number">47</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">&#x27;&#x27;</span>.join([<span class="built_in">chr</span>(i) <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">eval</span>(<span class="string">&#x27;[104,116,116,112,58,47,47,119,119,119,46,112,97,112,101,114,112,97,115,115,46,99,111,109,47]&#x27;</span>)]) <span class="comment">#解码</span></span><br><span class="line"><span class="string">&#x27;http://www.paperpass.com/&#x27;</span></span><br></pre></td></tr></table></figure></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div></li><li><code>format()</code>方法<br><p>高级字符串格式化，调用字符串<code>s</code>的<code>format()</code>方法：<code>s.format(*args,**kwargs)</code>，其接受位置参数和关键字参数的任意组合，并使用它们的值来替换<code>s</code>中嵌入的占位符，形式为<code>&#123;n&#125;</code>的占位符（<code>n</code>为数字，某些情况下可以省略）将被<code>format()</code>方法的第<code>n</code>个位置参数替换，而形式为<code>&#123;name&#125;</code>的占位符将被名为<code>name</code>的关键字参数值替换，如果要输出一个<code>&#123;</code>或<code>&#125;</code>，必须使用<code>&#123;&#123;</code>或<code>&#125;&#125;</code>的形式</p><p>使用占位符还可以对位置参数或关键字参数进行数值或键索引，如<code>&#123;name[n]&#125;</code>（<code>n</code>为索引数字，对应<code>name</code>是列表）、<code>&#123;name[key]&#125;</code>（<code>key</code>为非数字字符串，对应<code>name</code>是字典），譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">&#x27;my name is &#123;1&#125;, &#123;0[0]&#125;+&#123;0[1]&#125;=&#123;0[2]&#125;, &#123;2[x]&#125;&#123;2[y]&#125;&#123;2[z]&#125;, &#123;d&#125;, &#123;e[0]&#125;, &#123;e[1]&#125;&#x27;</span>.<span class="built_in">format</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],<span class="string">&#x27;dy&#x27;</span>,&#123;<span class="string">&#x27;x&#x27;</span>:<span class="string">&#x27;a&#x27;</span>,<span class="string">&#x27;y&#x27;</span>:<span class="string">&#x27;b&#x27;</span>,<span class="string">&#x27;z&#x27;</span>:<span class="string">&#x27;c&#x27;</span>&#125;,d=<span class="number">4</span>,e=[<span class="number">5</span>,<span class="string">&#x27;msy&#x27;</span>])</span><br><span class="line"><span class="string">&#x27;my name is dy, 1+2=3, abc, 4, 5, msy&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">&#x27;&#123;d&#125;, &#123;&#125;,&#123;&#125;, &#123;e&#125;, &#123;&#125;&#x27;</span>.<span class="built_in">format</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],<span class="string">&#x27;dy&#x27;</span>,&#123;<span class="string">&#x27;x&#x27;</span>:<span class="string">&#x27;a&#x27;</span>,<span class="string">&#x27;y&#x27;</span>:<span class="string">&#x27;b&#x27;</span>,<span class="string">&#x27;z&#x27;</span>:<span class="string">&#x27;c&#x27;</span>&#125;,d=<span class="number">4</span>,e=[<span class="number">5</span>,<span class="string">&#x27;msy&#x27;</span>]) <span class="comment">#使用缺省的&#123;&#125;占位符，将和位置参数从左至右一一对应</span></span><br><span class="line"><span class="string">&quot;4, [1, 2, 3],dy, [5, &#x27;msy&#x27;], &#123;&#x27;x&#x27;: &#x27;a&#x27;, &#x27;y&#x27;: &#x27;b&#x27;, &#x27;z&#x27;: &#x27;c&#x27;&#125;&quot;</span></span><br></pre></td></tr></table></figure><p>使用占位符还可以对位置参数或关键字参数进行属性查找，如<code>&#123;name.attr&#125;</code>：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">&#x27;&#123;0.real&#125; &#123;0.imag&#125;&#x27;</span>.<span class="built_in">format</span>(x)</span><br><span class="line"><span class="string">&#x27;1.0 2.0&#x27;</span></span><br></pre></td></tr></table></figure><p>另外，还可以指定格式说明符，对输出进行更加精确的控制，具体是用一个冒号（<code>:</code>）给每个占位符添加可选的格式说明符，形如<code>&#123;place:format_spec&#125;</code>，使用这种说明符可以指定列宽、小数位和对齐方式，一般格式是<code>[[fill]align][sign][0][width][.precision][type]</code>（<code>[]</code>中的每个部分都是可选的，特别地，当给定<code>fill</code>时，也必须同时给定<code>align</code>），<code>width</code>说明符指定要使用的最小字段宽度，<code>align</code>说明符的可取值为<code>&lt;</code>、<code>&gt;</code>或<code>^</code>（分别代表左对齐、右对齐和居中对齐），<code>fill</code>是一个可选的填充字符，默认用空格填充，<code>type</code>说明符表示数据的类型，可以不提供，默认值分别是<code>s</code>（字符串）、<code>d</code>（整数）、<code>e</code>（浮点数，科学计数），<code>sign</code>说明符可取值为<code>+</code>、<code>-</code>或空格，用于在数值类型前加上符号，<code>precision</code>说明符指定十进制数的精度位数，另外如果在<code>width</code>前面加上一个<code>0</code>，就会使用<code>0</code>来填充数字前面的空白，看个例子：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">&#x27;|&#123;:#^10&#125;|&#123;age:^+10.2f&#125;|&#x27;</span>.<span class="built_in">format</span>(<span class="string">&#x27;dy&#x27;</span>,age=<span class="number">25.54321</span>,)</span><br><span class="line"><span class="string">&#x27;|####dy####|  +25.54  |&#x27;</span></span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>Formatted string literals(f-string)</span></div>    <div class="hide-content"><div class="note info simple"><p><a href="https://realpython.com/python-f-strings/">F-string</a>是python3.6引入的<a href="https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals">新特性</a>，使用方式形如：<code>f’字符串’</code>或<code>F’字符串’</code>，字符串中使用大括号作为占位符标识要替换的字段，本质上f-string并非常量字符串，它将在运行时对其中的字段求值，f-string在设计上用于替代<code>%</code>和<code>format()</code>这两种传统格式化方法，性能优于二者且形式更加简便</p></div><ul><li>简单使用：<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>name = <span class="string">&quot;Eric&quot;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>age = <span class="number">74</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">f&quot;Hello, <span class="subst">&#123;name&#125;</span>. You are <span class="subst">&#123;age&#125;</span>.&quot;</span></span><br><span class="line"><span class="string">&#x27;Hello, Eric. You are 74.&#x27;</span></span><br></pre></td></tr></table></figure></li><li>表达式求值和函数调用：<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">f&quot;<span class="subst">&#123;<span class="number">2</span> * <span class="number">37</span>&#125;</span>&quot;</span> <span class="comment">#表达式求值</span></span><br><span class="line"><span class="string">&#x27;74&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">def</span> <span class="title function_">to_lowercase</span>(<span class="params"><span class="built_in">input</span></span>):</span><br><span class="line">. . .         <span class="keyword">return</span> <span class="built_in">input</span>.lower()</span><br><span class="line">. . .</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>name = <span class="string">&quot;Eric Idle&quot;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">f&quot;<span class="subst">&#123;to_lowercase(name)&#125;</span> is funny.&quot;</span> <span class="comment">#函数调用</span></span><br><span class="line"><span class="string">&#x27;eric idle is funny.&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">f&quot;<span class="subst">&#123;name.lower()&#125;</span> is funny.&quot;</span> <span class="comment">#调用对象方法</span></span><br><span class="line"><span class="string">&#x27;eric idle is funny.&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">import</span> math</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">f&#x27;The answer is <span class="subst">&#123;math.log(math.pi)&#125;</span>&#x27;</span></span><br><span class="line"><span class="string">&#x27;The answer is 1.1447298858494002&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>comedian = &#123;<span class="string">&#x27;name&#x27;</span>: <span class="string">&#x27;Eric Idle&#x27;</span>, <span class="string">&#x27;age&#x27;</span>: <span class="number">74</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">f&quot;The comedian is <span class="subst">&#123;comedian[<span class="string">&#x27;name&#x27;</span>]&#125;</span>, aged <span class="subst">&#123;comedian[<span class="string">&#x27;age&#x27;</span>]&#125;</span>.&quot;</span></span><br><span class="line">The comedian <span class="keyword">is</span> Eric Idle, aged <span class="number">74.</span></span><br></pre></td></tr></table></figure><p>注：如果占位符<code>&#123;...&#125;</code>中的对象非字符串，那么将调用对象的<code>__str__()</code>方法（和<code>__repr__()</code>方法相比，前者面向人类，后者面向计算机，一般来说，你甚至可以通过执行（调用<code>eval()</code>函数）<code>repr()</code>返回的字符串重新生成对象，如果只实现<code>__repr__()</code>，那么<code>str()</code>还是会调用对象的<code>__repr__()</code>方法），并以返回的字符串替换占位符（如果同时也定义了<code>__repr__()</code>方法，且希望格式化时使用该方法返回的字符串，则写成<code>&#123;...!r&#125;</code>），看个例子：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Comedian</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, first_name, last_name, age</span>):</span><br><span class="line">        self.first_name = first_name</span><br><span class="line">        self.last_name = last_name</span><br><span class="line">        self.age = age</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="string">f&quot;<span class="subst">&#123;self.first_name&#125;</span> <span class="subst">&#123;self.last_name&#125;</span> is <span class="subst">&#123;self.age&#125;</span>.&quot;</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__repr__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="string">f&quot;<span class="subst">&#123;self.first_name&#125;</span> <span class="subst">&#123;self.last_name&#125;</span> is <span class="subst">&#123;self.age&#125;</span>. Surprise!&quot;</span></span><br><span class="line"></span><br><span class="line">new_comedian = Comedian(<span class="string">&quot;Eric&quot;</span>, <span class="string">&quot;Idle&quot;</span>, <span class="string">&quot;74&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;new_comedian&#125;</span>&#x27;</span>) <span class="comment">#Eric Idle is 74.</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;Comedian(<span class="string">&quot;Yang&quot;</span>,<span class="string">&quot;Dai&quot;</span>,<span class="number">25</span>)&#125;</span>&#x27;</span>) <span class="comment">#Yang Dai is 25.</span></span><br><span class="line"><span class="built_in">print</span>(&gt;&gt;&gt; <span class="string">f&quot;<span class="subst">&#123;new_comedian!r&#125;</span>&quot;</span>) <span class="comment">#&#x27;Eric Idle is 74. Surprise!&#x27;</span></span><br></pre></td></tr></table></figure>注1：字符串内的引号不能和字符串外的引号定界符冲突，可根据情况灵活切换<code>'</code>和<code>"</code>（单引号和双引号），必要的时候，还可以使用三引号<code>'''</code>或者<code>"""</code>，再不行，还可以使用斜杠<code>\</code>对特殊字符进行转义，譬如<code>'i\'m dy.'</code>，但是f-string大括号内部不能使用斜杠<code>\</code>转义甚至说根本就不能出现任何斜杠</p><p>注2，支持多重大括号写法，譬如双重大括号，<code>f'&#123;&#123;5&#125;&#125;'</code>将打印出字符串<code>'&#123;5&#125;'</code>，此时双重大括号中的内容是被当作普通字符串，再譬如：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">f&#x27;<span class="subst">&#123;temp_a&#125;</span>&#x27;</span> <span class="comment">#temp_a从未定义，没有这个变量</span></span><br><span class="line">Traceback (most recent call last):</span><br><span class="line">  File <span class="string">&quot;&lt;stdin&gt;&quot;</span>, line <span class="number">1</span>, <span class="keyword">in</span> &lt;module&gt;</span><br><span class="line">NameError: name <span class="string">&#x27;temp_a&#x27;</span> <span class="keyword">is</span> <span class="keyword">not</span> defined</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">f&#x27;&#123;&#123;temp_a&#125;&#125;&#x27;</span></span><br><span class="line"><span class="string">&#x27;&#123;temp_a&#125;&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">f&#x27;&#123;&#123;70 + 4&#125;&#125;&#x27;</span></span><br><span class="line"><span class="string">&#x27;&#123;70 + 4&#125;&#x27;</span></span><br></pre></td></tr></table></figure><p>要当作变量或表达式或函数调用，则再加一层大括号，即三重大括号：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">f&#x27;&#123;&#123;<span class="subst">&#123;<span class="number">70</span> + <span class="number">4</span>&#125;</span>&#125;&#125;&#x27;</span></span><br><span class="line"><span class="string">&#x27;&#123;74&#125;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#如果是四重大括号（规律也很明显了）：</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">f&#x27;&#123;&#123;&#123;&#123;70 + 4&#125;&#125;&#125;&#125;&#x27;</span></span><br><span class="line"><span class="string">&#x27;&#123;&#123;70 + 4&#125;&#125;&#x27;</span></span><br></pre></td></tr></table></figure></p></li><li>多行f-strings：<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">name = <span class="string">&quot;Eric&quot;</span></span><br><span class="line">profession = <span class="string">&quot;comedian&quot;</span></span><br><span class="line">affiliation = <span class="string">&quot;Monty Python&quot;</span></span><br><span class="line">message = (</span><br><span class="line">    <span class="string">f&quot;Hi <span class="subst">&#123;name&#125;</span>. &quot;</span></span><br><span class="line">    <span class="string">f&quot;You are a <span class="subst">&#123;profession&#125;</span>. &quot;</span></span><br><span class="line">    <span class="string">f&quot;You were in <span class="subst">&#123;affiliation&#125;</span>.&quot;</span></span><br><span class="line">)</span><br><span class="line"><span class="built_in">print</span>(message) <span class="comment">#Hi Eric. You are a comedian. You were in Monty Python.</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#上述写法需要在每一行首部添加标识f或F，如果不像这样可以使用三引号实现多行字符串（但注意下面会输出三行）：</span></span><br><span class="line">message = <span class="string">f&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">    Hi <span class="subst">&#123;name&#125;</span>. </span></span><br><span class="line"><span class="string">    You are a <span class="subst">&#123;profession&#125;</span>. </span></span><br><span class="line"><span class="string">    You were in <span class="subst">&#123;affiliation&#125;</span>.</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure><p>注，多个（位于同一行的）独立字符串之间不需要使用任何连接符（如果不在同一行，需要在行末加上斜杠表示换行（任意语句如果太长，你都可以在一行结尾处使用斜杠，然后就可以在下一行继续书写上一条语句剩余的内容，且不受python正常的缩进规则限制），如果不想写斜杠，也可以在所有独立字符串的左右两端裹上小括号），它们同样会被自动拼接：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">s=<span class="string">&quot;Hello&quot;</span> <span class="string">&quot; world!&quot;</span></span><br><span class="line"><span class="built_in">print</span>(s) <span class="comment">#Hello world!</span></span><br><span class="line"></span><br><span class="line">s=<span class="string">&quot;dy &quot;</span> <span class="string">&quot;is &quot;</span> \</span><br><span class="line"><span class="string">&#x27;a&#x27;</span>   <span class="string">&#x27; &#x27;</span> \</span><br><span class="line"><span class="string">&#x27;muggle&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(s) <span class="comment">#dy is a muggle</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#等同于：</span></span><br><span class="line">s=(<span class="string">&quot;dy &quot;</span> <span class="string">&quot;is &quot;</span></span><br><span class="line"><span class="string">&#x27;a&#x27;</span>   <span class="string">&#x27; &#x27;</span></span><br><span class="line"><span class="string">&#x27;muggle&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(s) <span class="comment">#dy is a muggle</span></span><br></pre></td></tr></table></figure><p>且多个独立字符串作为函数参数时，不论是否在同一行，都无需斜杠作为换行符：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">a,b</span>):</span><br><span class="line">    <span class="built_in">print</span>(a)</span><br><span class="line">    <span class="built_in">print</span>(b)</span><br><span class="line"></span><br><span class="line">f(<span class="string">&quot;muggle&quot;</span></span><br><span class="line"><span class="string">&quot;dy&quot;</span>,<span class="string">&quot;dai&quot;</span> \</span><br><span class="line"><span class="string">&quot;xiao&quot;</span><span class="string">&quot;dong&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">muggledy</span></span><br><span class="line"><span class="string">daixiaodong</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></li><li>格式精确控制（对齐、宽度、符号、补零、精度、进制等）：<br>类似<code>format()</code>，f-string使用形如<code>&#123;content:format_spec&#125;</code>进行格式的精确控制，其中<code>content</code>可以是变量、表达式或函数等，<code>format_spec</code>是格式描述符，采用默认格式时，则省略<code>:format_spec</code>，格式描述的使用顺序要注意，具体请参阅文章[2]相关部分</li></ul><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>print()</code>函数</span></div>    <div class="hide-content"><p>当使用<code>print()</code>打印对象的时候，实际上是调用了标准输出并向其中写入字符串：<code>sys.stdout.write(str(obj)+'\n')</code>，<code>sys.stdout</code>就是标准输出对象，默认是写入到控制台设备并追加一个换行符（可以通过指定<code>print()</code>函数的<code>end</code>参数修改所追加的字符或字符串），当然你也可以修改<code>sys.stdout</code>的值，以实现输出重定向，譬如将输出重定向至某个文件：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>__console__ = sys.stdout <span class="comment">#将控制台对象引用保存下来以便于恢复</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>file = <span class="built_in">open</span>(<span class="string">&#x27;redir_print.txt&#x27;</span>, <span class="string">&#x27;w&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>sys.stdout = file</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">print</span>(<span class="string">&#x27;Hello,World!&#x27;</span>) <span class="comment">#此时等同于：file.write(...)</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>file.flush() <span class="comment">#打印的内容首先存在于缓冲区flush中，直到下一次打印时上次的打印（内容）才被写到文件中，使用flush()强制刷新缓冲区将其写进文件</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>sys.stdout = __console__</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>file.close()</span><br></pre></td></tr></table></figure><p>在python3中不需要像上面这样繁琐，指定<code>print()</code>函数的<code>file</code>参数和<code>flush</code>参数即可：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">print</span>(<span class="string">&#x27;Hello,World!&#x27;</span>, file = file, flush = <span class="literal">True</span>)</span><br></pre></td></tr></table></figure><p>实际上你可以往<code>print()</code>中传递任意数量的任意对象且是以位置参数的形式，因为<code>__str__()</code>具有默认实现，其返回一个尖括号包裹的字符串，包含类名和内存地址信息，不同对象的输出字符串会自动连接且以单个空格作为间隔符：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">class</span> <span class="title class_">A</span>: <span class="keyword">pass</span></span><br><span class="line">...</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">print</span>(<span class="string">&#x27;muggledy&#x27;</span>,<span class="string">&#x27;+&#x27;</span>,...,<span class="string">&#x27;zj&#x27;</span>,A())</span><br><span class="line">muggledy + <span class="literal">Ellipsis</span> zj &lt;__main__.A <span class="built_in">object</span> at <span class="number">0x000001B0358AB7B8</span>&gt;</span><br></pre></td></tr></table></figure></div></div></div></div></li></ol></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="dytab1-1-2"><ol><li> 增加<br>   <ul><li> <code>s.append(x)</code></li>   <li><code>s.extend(t)</code><br>     注：不同于<code>append</code>追加元素，<code>extend</code>将一个新的序列扩展到原始序列中，等同于<code>[*s,*t]</code>（解包）     <div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>解包与装包</span></div>    <div class="hide-content"><p>主要有三种用途：变量赋值，函数传参和简化容器添加</p><ol><li>变量赋值<br><ul><li>将多个值或者说对象（其以逗号间隔）赋值给一个变量时，python会自动将这些值封装成元组，这种特性即称为“装包”：<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>)</span><br></pre></td></tr></table></figure></li><li>特别地，当函数返回多个数值时，也会进行装包：<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">a,b,c</span>):</span><br><span class="line">    <span class="keyword">return</span> a*<span class="number">1</span>,b*<span class="number">2</span>,c*<span class="number">3</span></span><br><span class="line">    </span><br><span class="line">ret=f(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line"><span class="built_in">print</span>(ret,<span class="built_in">type</span>(ret)) <span class="comment">#(1, 4, 9) &lt;class &#x27;tuple&#x27;&gt;</span></span><br></pre></td></tr></table></figure></li><li>将一个（可迭代）对象拆分成多个对象并依次赋值给多个变量，这种特性即称为“解包”，另外还可以用星号<code>*</code>修饰变量，使其接收多个拆解对象的组合（装包为列表类型）：<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x,y,z=a</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x</span><br><span class="line"><span class="number">1</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>y</span><br><span class="line"><span class="number">2</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z</span><br><span class="line"><span class="number">3</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x,*y,z=<span class="built_in">range</span>(<span class="number">10</span>) <span class="comment">#非*修饰变量（x,z）只能接收一个拆解对象</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x</span><br><span class="line"><span class="number">0</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>y</span><br><span class="line">[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z</span><br><span class="line"><span class="number">9</span></span><br></pre></td></tr></table></figure></li><li>可以解包的对象类型包括元组、列表、字典、生成器以及其它可迭代对象：<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>d=&#123;<span class="string">&#x27;a&#x27;</span>:<span class="number">1</span>,<span class="string">&#x27;b&#x27;</span>:<span class="number">2</span>,<span class="string">&#x27;c&#x27;</span>:<span class="number">3</span>&#125; <span class="comment">#字典也是可迭代对象，等同于迭代其键序列，但是要注意键序列其实是“无序”的</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x,y,z=d</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x,y,z</span><br><span class="line">(<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;c&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x,y,z=d.items() <span class="comment">#如果要同时得到字典的键值的话</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x,y,z</span><br><span class="line">((<span class="string">&#x27;a&#x27;</span>, <span class="number">1</span>), (<span class="string">&#x27;b&#x27;</span>, <span class="number">2</span>), (<span class="string">&#x27;c&#x27;</span>, <span class="number">3</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=(i <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">3</span>)) <span class="comment">#生成器也是可迭代对象</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x,y,z=a</span><br></pre></td></tr></table></figure><p>装包和解包常用于“对称性赋值”操作和<code>for</code>循环中的变量拆解：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">x,y=<span class="number">6</span>,<span class="number">8</span></span><br><span class="line">x,y=y,x</span><br><span class="line"><span class="built_in">print</span>(x,y) <span class="comment">#将变量x和y的值对调，不需要像C语言那样借助临时变量实现。等号右边会先进行封装，变成元组(y,x)，然后元组被解包并依次赋值给x和y</span></span><br><span class="line"></span><br><span class="line">d=&#123;<span class="string">&#x27;a&#x27;</span>:<span class="number">1</span>,<span class="string">&#x27;b&#x27;</span>:<span class="number">2</span>,<span class="string">&#x27;c&#x27;</span>:<span class="number">3</span>&#125;</span><br><span class="line"><span class="keyword">for</span> k,v <span class="keyword">in</span> d.items():</span><br><span class="line">   <span class="built_in">print</span>(<span class="string">&#x27;键:&#123;&#125;, 值:&#123;&#125;&#x27;</span>.<span class="built_in">format</span>(k,v))</span><br><span class="line">    </span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">键:a, 值:1</span></span><br><span class="line"><span class="string">键:b, 值:2</span></span><br><span class="line"><span class="string">键:c, 值:3</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></li><li>可以在变量赋值操作中对等号右边的可迭代对象直接使用星号<code>*</code>进行拆解或者说解包：<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=[<span class="string">&#x27;dy&#x27;</span>,<span class="number">88</span>,<span class="literal">True</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>v=<span class="number">1</span>,<span class="number">2</span>,*a,<span class="number">3</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>v</span><br><span class="line">(<span class="number">1</span>, <span class="number">2</span>, <span class="string">&#x27;dy&#x27;</span>, <span class="number">88</span>, <span class="literal">True</span>, <span class="number">3</span>)</span><br></pre></td></tr></table></figure><p>如果不想对右边的对象进行显式拆解，还可以在左边对将要接收的变量裹上一层或多层<code>()</code>或<code>[]</code>，以实现“多级嵌套解包”：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=[<span class="string">&#x27;dy&#x27;</span>,<span class="number">88</span>,<span class="literal">True</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>*_,(x,y,z),_=<span class="number">1</span>,<span class="number">2</span>,a,<span class="number">3</span> <span class="comment">#写成*_,(x,y,z),*_=1,2,a,3是错误的，在同一级不能出现两个及以上的星号，什么意思？譬如写成*_,(x,*y),_=1,2,a,3则是正确的，这两个*不在同一级</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x,y,z</span><br><span class="line">(<span class="string">&#x27;dy&#x27;</span>, <span class="number">88</span>, <span class="literal">True</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_,(a,(b,c),d),_=<span class="number">1</span>,[<span class="number">2</span>,[<span class="number">3</span>,<span class="number">4</span>],<span class="number">5</span>],<span class="number">6</span> <span class="comment">#总之两边结构保持一致即可</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b,c</span><br><span class="line">(<span class="number">3</span>, <span class="number">4</span>)</span><br></pre></td></tr></table></figure><p>简单来说，星号出现在赋值号左边表示装包，出现在赋值号右边表示解包，不管是哪种，星号修饰符都必须位于一个序列中，可能不太好理解，看个例子即可：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>*x=a <span class="comment">#报错</span></span><br><span class="line">  File <span class="string">&quot;&lt;stdin&gt;&quot;</span>, line <span class="number">1</span></span><br><span class="line">SyntaxError: starred assignment target must be <span class="keyword">in</span> a <span class="built_in">list</span> <span class="keyword">or</span> <span class="built_in">tuple</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>*x,=a</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>(*x,)=a</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>[*x]=a <span class="comment">#这三种改法都是正确的</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x=*a <span class="comment">#报错</span></span><br><span class="line">  File <span class="string">&quot;&lt;stdin&gt;&quot;</span>, line <span class="number">1</span></span><br><span class="line">SyntaxError: can<span class="string">&#x27;t use starred expression here</span></span><br><span class="line"><span class="string">&gt;&gt;&gt; x=*a,</span></span><br><span class="line"><span class="string">&gt;&gt;&gt; x=(*a,)</span></span><br><span class="line"><span class="string">&gt;&gt;&gt; x=[*a] #这三种改法都是正确的</span></span><br></pre></td></tr></table></figure></li></ul></li><li>函数传参<br><ul><li>装包传递（分两种，一是位置参数将被装包为一个元组，二是关键字参数将被装包为一个字典）：<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>(<span class="params">*t</span>):</span><br><span class="line">    <span class="built_in">print</span>(t)</span><br><span class="line"></span><br><span class="line">f1(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>) <span class="comment">#(1, 2, 3, 4, 5)</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">**d</span>):</span><br><span class="line">    <span class="built_in">print</span>(d)</span><br><span class="line">    </span><br><span class="line">f2(X=<span class="string">&#x27;a&#x27;</span>,Y=<span class="string">&#x27;b&#x27;</span>,Z=<span class="string">&#x27;c&#x27;</span>) <span class="comment">#&#123;&#x27;X&#x27;: &#x27;a&#x27;, &#x27;Y&#x27;: &#x27;b&#x27;, &#x27;Z&#x27;: &#x27;c&#x27;&#125;</span></span><br></pre></td></tr></table></figure></li><li>解包传递（也分为两种情况，一是元组解包传递给位置参数，二是字典解包传递给关键字参数）：<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">x,y,z</span>):</span><br><span class="line">    <span class="built_in">print</span>(x,y,z)</span><br><span class="line"></span><br><span class="line">t=(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line">f3(*t) <span class="comment">#等同于执行：f3(1,2,3)</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">a,b=<span class="number">22</span>,c=<span class="number">33</span></span>):</span><br><span class="line">    <span class="built_in">print</span>(a,b,c)</span><br><span class="line"></span><br><span class="line">d=&#123;<span class="string">&#x27;a&#x27;</span>:<span class="number">1</span>,<span class="string">&#x27;c&#x27;</span>:<span class="number">3</span>&#125;</span><br><span class="line">f4(**d) <span class="comment">#等同于执行：f4(a=1,c=3)</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#特别地，如果调用f1(*t)或者f2(**d)，将同时完成解包和装包传递</span></span><br></pre></td></tr></table></figure></li></ul></li><li>简化容器添加<br><ul><li>当容器为<code>list</code>、<code>tuple</code>（虽然元组是不可变类型，但是没关系，能解包就行，这也并不涉及元组值的改变）、<code>set</code>类型时，同变量赋值操作中等号右边可迭代对象的拆解，使用单星号进行解包：<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>(*a,<span class="number">4</span>,<span class="number">5</span>) <span class="comment">#创建一个全新的元组</span></span><br><span class="line">(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>&#123;*a,<span class="number">4</span>,<span class="number">5</span>&#125; <span class="comment">#集合</span></span><br><span class="line">&#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>&#125;</span><br></pre></td></tr></table></figure></li><li>当容器对字典时，使用的是双星号<code>**</code>进行解包：<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>d=&#123;<span class="string">&#x27;1&#x27;</span>:<span class="number">1</span>,<span class="string">&#x27;2&#x27;</span>:<span class="number">2</span>,<span class="string">&#x27;3&#x27;</span>:<span class="number">3</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>&#123;**d,<span class="string">&#x27;4&#x27;</span>:<span class="number">4</span>,<span class="string">&#x27;5&#x27;</span>:<span class="number">5</span>&#125;</span><br><span class="line">&#123;<span class="string">&#x27;1&#x27;</span>: <span class="number">1</span>, <span class="string">&#x27;2&#x27;</span>: <span class="number">2</span>, <span class="string">&#x27;3&#x27;</span>: <span class="number">3</span>, <span class="string">&#x27;4&#x27;</span>: <span class="number">4</span>, <span class="string">&#x27;5&#x27;</span>: <span class="number">5</span>&#125;</span><br></pre></td></tr></table></figure><p>但是需要注意的是，这虽然比通过<code>dict.update()</code>扩充字典的形式要简单一点，但须知，<code>dict.update(another_dict)</code>可以明确更新项目，而<code>**</code>字典解包则无法确保，譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>d=&#123;<span class="string">&#x27;a&#x27;</span>:<span class="number">1</span>,<span class="string">&#x27;b&#x27;</span>:<span class="number">2</span>,<span class="string">&#x27;c&#x27;</span>:<span class="number">3</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>&#123;**d,<span class="string">&#x27;c&#x27;</span>:<span class="number">33</span>&#125;</span><br><span class="line">&#123;<span class="string">&#x27;a&#x27;</span>: <span class="number">1</span>, <span class="string">&#x27;b&#x27;</span>: <span class="number">2</span>, <span class="string">&#x27;c&#x27;</span>: <span class="number">33</span>&#125; <span class="comment">#&#x27;c&#x27;键值更新了</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>&#123;<span class="string">&#x27;c&#x27;</span>:<span class="number">33</span>,**d&#125;</span><br><span class="line">&#123;<span class="string">&#x27;c&#x27;</span>: <span class="number">3</span>, <span class="string">&#x27;a&#x27;</span>: <span class="number">1</span>, <span class="string">&#x27;b&#x27;</span>: <span class="number">2</span>&#125; <span class="comment">#&#x27;c&#x27;键值没有更新</span></span><br></pre></td></tr></table></figure><p>另外就是效率问题，用<code>*</code>和<code>**</code>简化容器的添加操作，其性能和容器对象的<code>update()</code>,<code>append()</code>或<code>add()</code>方法相比，谁更优？根据下面的测试，解包比<code>append()</code>方法慢了3倍：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> timeit</span><br><span class="line">t1=timeit.Timer(<span class="string">&#x27;a.append(100)&#x27;</span>,<span class="string">&#x27;a=list(range(100))&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(t1.repeat()) <span class="comment">#[0.0850489117379404, 0.09039714449200119, 0.08290944329400407]</span></span><br><span class="line"></span><br><span class="line">t2=timeit.Timer(<span class="string">&#x27;b=[*a,100]&#x27;</span>,<span class="string">&#x27;a=list(range(100))&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(t2.repeat()) <span class="comment">#[0.2924700997522413, 0.2945020249114667, 0.2961987540175306]</span></span><br></pre></td></tr></table></figure></li></ul></li></ol></div></div>   </li>   <li><code>s.insert(i,x)</code><br></li>   </ul>  </li><li> 删除<br>   <ul><li> <code>s.pop([i])</code><br>     注：函数定义或签名中的<code>[]</code>表示可选参数   </li>   <li> <code>s.remove(x)</code></li>   <li> <code>del s[i]</code>、<code>del s[i:j]</code>、<code>del s[i:j:stride]</code><br>     注：这是可变序列的通用操作   </li></ul>  </li><li> 查找<br>   <ul><li> <code>s.index(x,[,start[,stop]])</code><br>     注：返回满足<code>s[start:stop][i]==x</code>的最小<code>i</code>值，如果找不到，会抛出异常</li>   <li> <code>s[i]</code>、<code>s[i:j]</code>、<code>s[i:j:stride]</code><br>     注：这是序列的通用操作。<code>i:j</code>其实是一个特殊的切片对象<code>slice(i,j,None)</code>，且<code>i</code>、<code>j</code>、<code>stride</code>都是任意可省的，如<code>s[::]</code>   </li></ul></li><li> 修改<br>   <ul>   <li><code>s.reverse()</code><br>     注：这是原址操作，可以通过切片实现<code>s[::-1]</code>（返回一个新对象，上面说过，属于浅复制）   </li>   <li><code>s.sort([key[,reverse]])</code><br>     <div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>sort()</code>方法</span></div>    <div class="hide-content"><div class="note blue icon disabled"><i class="note-icon fas fa-lightbulb"></i><p>基本形式：<code>sorted(iterable[,cmp[,key[,reverse]]])</code>（副本排序）、<code>              iterable.sort(cmp[,key[,reverse]])</code>（原址排序）<p>参数：<code>iterable</code>为可迭代对象，<code>cmp</code>指定排序时进行比较的函数，<code>key</code>也是函数，指定待排序元素将要参与排序的特征，<code>reverse</code>实现降序，默认<code>False</code>为升序<br>注：python3去掉了<code>cmp</code>参数</p></p></div><p>简单示例：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#1.原址排序（对原始的序列对象进行内部排序而不是返回一个新的已排的序列对象）</span></span><br><span class="line">n=[<span class="number">7</span>,<span class="number">4</span>,<span class="number">1</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">8</span>,<span class="number">9</span>]</span><br><span class="line">n.sort()</span><br><span class="line"><span class="built_in">print</span>(n) <span class="comment">#[1, 2, 3, 4, 7, 8, 9]</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#2.副本排序</span></span><br><span class="line"><span class="comment">#两种：创建原始对象的一个副本，然后对副本做原址排序，或者使用sorted方法，其将返回一个类型为列表的副本</span></span><br><span class="line">x=[<span class="number">4</span>,<span class="number">3</span>,<span class="number">5</span>,<span class="number">2</span>,<span class="number">1</span>]</span><br><span class="line">y=x[:] <span class="comment">#对于列表对象来说，创建副本的方式有很多：切片、工厂函数、copy.copy（前三种是浅拷贝）、copy.deepcopy</span></span><br><span class="line">y.sort()</span><br><span class="line"><span class="built_in">print</span>(x,y) <span class="comment">#x未排序，y已排序</span></span><br><span class="line"></span><br><span class="line">m=[<span class="number">3</span>,<span class="number">4</span>,<span class="number">1</span>,<span class="number">7</span>,<span class="number">5</span>,<span class="number">0</span>,<span class="number">2</span>]</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">sorted</span>(m))</span><br><span class="line"><span class="built_in">print</span>(m) <span class="comment">#sorted()不改变原始对象</span></span><br></pre></td></tr></table></figure><p>高级用法：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#1.自定义比较函数cmp(x,y)</span></span><br><span class="line"><span class="comment">#既然python3不支持，就不说了</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#2.自定义待排序元素特征keys（接受一个参数，表示待排序的元素对象）</span></span><br><span class="line"><span class="comment">#之所以在key后面加上s，是因为特征可以有多个，首先按照第一个特征对元素排序，然后在此基础之上，再用第二个特征排序，第一个特征优先级最高。此即为多级排序</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">keys</span>(<span class="params">x</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">len</span>(x)</span><br><span class="line"></span><br><span class="line">array=[<span class="string">&#x27;daiyang&#x27;</span>,<span class="string">&#x27;sb&#x27;</span>,<span class="string">&#x27;miaosiyu&#x27;</span>,<span class="string">&#x27;jianglicheng&#x27;</span>,<span class="string">&#x27;liuhan&#x27;</span>] <span class="comment">#按照字符串的长度进行排序（降）</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">sorted</span>(array,key=keys,reverse=<span class="literal">True</span>)) <span class="comment">#由于取消了cmp比较函数，因此只能通过reverse设定升降顺序</span></span><br><span class="line">array.sort(key=<span class="keyword">lambda</span> x:<span class="built_in">len</span>(x),reverse=<span class="literal">True</span>)</span><br><span class="line"><span class="built_in">print</span>(array) <span class="comment">#[&#x27;jianglicheng&#x27;, &#x27;miaosiyu&#x27;, &#x27;daiyang&#x27;, &#x27;liuhan&#x27;, &#x27;sb&#x27;]</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#3.多级排序</span></span><br><span class="line">arrays_1=[(<span class="number">2</span>,<span class="number">3</span>,<span class="number">10</span>),(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>),(<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>),(<span class="number">2</span>,<span class="number">5</span>,<span class="number">10</span>),(<span class="number">2</span>,<span class="number">4</span>,<span class="number">10</span>)]</span><br><span class="line">arrays_2=[(<span class="string">&#x27;2&#x27;</span>,<span class="string">&#x27;3&#x27;</span>,<span class="string">&#x27;10&#x27;</span>),(<span class="string">&#x27;1&#x27;</span>,<span class="string">&#x27;2&#x27;</span>,<span class="string">&#x27;3&#x27;</span>),(<span class="string">&#x27;5&#x27;</span>,<span class="string">&#x27;6&#x27;</span>,<span class="string">&#x27;7&#x27;</span>),(<span class="string">&#x27;2&#x27;</span>,<span class="string">&#x27;5&#x27;</span>,<span class="string">&#x27;10&#x27;</span>),(<span class="string">&#x27;2&#x27;</span>,<span class="string">&#x27;4&#x27;</span>,<span class="string">&#x27;10&#x27;</span>)]</span><br><span class="line">arrays_1.sort(key=<span class="keyword">lambda</span> x:(x[<span class="number">2</span>],x[<span class="number">1</span>])) <span class="comment">#例1 #[(1, 2, 3), (5, 6, 7), (2, 3, 10), (2, 4, 10), (2, 5, 10)]</span></span><br><span class="line"><span class="built_in">print</span>(arrays_1)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">sorted</span>(arrays_2,key=<span class="keyword">lambda</span> x:<span class="built_in">list</span>(<span class="built_in">map</span>(<span class="built_in">int</span>,(x[<span class="number">2</span>],x[<span class="number">1</span>]))))) <span class="comment">#例2</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#将operator.itemgetter函数用在多级排序中</span></span><br><span class="line"><span class="keyword">from</span> operator <span class="keyword">import</span> itemgetter</span><br><span class="line"><span class="comment">#itemgetter函数用于选择对象的指定维数的数据，注意itemgetter返回的是一个函数对象</span></span><br><span class="line">a=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line">gets=itemgetter(<span class="number">1</span>,<span class="number">2</span>) <span class="comment">#获取“对象[1]”和“对象[2]”，这个对象是广义化的，由你任意指定，如下：</span></span><br><span class="line">ret=gets(a) <span class="comment">#返回一个元组：(a[1],a[2])</span></span><br><span class="line"><span class="built_in">print</span>(ret)</span><br><span class="line"></span><br><span class="line"><span class="comment">#结果同例2:</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">sorted</span>(arrays_2,key=<span class="keyword">lambda</span> x:<span class="built_in">list</span>(<span class="built_in">map</span>(<span class="built_in">int</span>,itemgetter(<span class="number">2</span>,<span class="number">1</span>)(x)))))</span><br><span class="line"><span class="comment">#结果同例1:</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">sorted</span>(arrays_1,key=itemgetter(<span class="number">2</span>,<span class="number">1</span>)))</span><br></pre></td></tr></table></figure><p>注，获取排序后的索引序列：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">argsort</span>(<span class="params">arr</span>):</span><br><span class="line">    <span class="keyword">return</span> [i <span class="keyword">for</span> i,v <span class="keyword">in</span> <span class="built_in">sorted</span>(<span class="built_in">enumerate</span>(arr),key=<span class="keyword">lambda</span> x:x[<span class="number">1</span>])]</span><br><span class="line">    </span><br><span class="line">a=[<span class="number">1</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">9</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">0</span>]</span><br><span class="line">inds=argsort(a)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;sorted-index:<span class="subst">&#123;inds&#125;</span>&#x27;</span>) <span class="comment">#sorted-index:[6, 0, 2, 5, 1, 4, 3]</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;sorted-value:<span class="subst">&#123;[a[ind] <span class="keyword">for</span> ind <span class="keyword">in</span> inds]&#125;</span>&#x27;</span>) <span class="comment">#sorted-value:[0, 1, 2, 2, 3, 4, 9]</span></span><br></pre></td></tr></table></figure></div></div>   </li>   </ul></li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="dytab1-1-3"><p>类似于列表，只不过元组一旦创建不能修改，比列表要省内存</p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="dytab1-1-4"><p>首先新建一个链表类（目前就是一个普通的容器，可以存储数据，但是尚未实现<code>__iter__</code>方法，因此还不是可迭代对象），实现了链表的基本操作，索引、追加、插入、删除：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br></pre></td><td class="code"><pre><span class="line">__all__=[<span class="string">&#x27;Link&#x27;</span>,]</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Node</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,val</span>):</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;节点对象，有数据域和指针域（指向下一元素）&#x27;&#x27;&#x27;</span></span><br><span class="line">        self.data=val</span><br><span class="line">        self.<span class="built_in">next</span>=<span class="literal">None</span></span><br><span class="line">        </span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Link</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;初始化链表，初始化一个头节点，其数据域默认为空，可以添加链表长度等信息&#x27;&#x27;&#x27;</span></span><br><span class="line">        head=Node(<span class="number">0</span>)</span><br><span class="line">        self.pointer=head <span class="comment">#语义：链表指针，指向头节点</span></span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">append</span>(<span class="params">self,val</span>):</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;在链表尾部追加新元素&#x27;&#x27;&#x27;</span></span><br><span class="line">        node=Node(val)</span><br><span class="line">        p=self.pointer    <span class="comment">#语义：工作指针</span></span><br><span class="line">        <span class="keyword">while</span> p.<span class="built_in">next</span>:     <span class="comment">#获取指向最后一个元素的指针</span></span><br><span class="line">            p=p.<span class="built_in">next</span></span><br><span class="line">        p.<span class="built_in">next</span>=node       <span class="comment">#看起来next“指针域”指向了node，因为next中保存的是对node的引用，而不是node的拷贝，这和C中的指针效果是一样的</span></span><br><span class="line">        self.pointer.data+=<span class="number">1</span></span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">printf</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;打印链表中元素&#x27;&#x27;&#x27;</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;[链表] &#x27;</span>,end=<span class="string">&#x27;&#x27;</span>)</span><br><span class="line">        p=self.pointer</span><br><span class="line">        <span class="keyword">while</span> p.<span class="built_in">next</span>:</span><br><span class="line">            <span class="built_in">print</span>(p.<span class="built_in">next</span>.data,end=<span class="string">&#x27;, &#x27;</span>)</span><br><span class="line">            p=p.<span class="built_in">next</span></span><br><span class="line">        <span class="built_in">print</span>()</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">delete</span>(<span class="params">self,index,get=<span class="literal">False</span></span>):</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;删除链表中第index个元素，get参数用于get()函数代码复用，这个参数应该隐藏（譬如作为类属性）而不该放在函数定义中&#x27;&#x27;&#x27;</span></span><br><span class="line">        <span class="keyword">if</span> index&lt;<span class="number">1</span> <span class="keyword">or</span> index&gt;self.<span class="built_in">len</span>:</span><br><span class="line">            <span class="keyword">raise</span> ValueError(<span class="string">&#x27;下标溢出&#x27;</span>)</span><br><span class="line">        p=self.pointer</span><br><span class="line">        i=<span class="number">1</span></span><br><span class="line">        <span class="keyword">while</span> p.<span class="built_in">next</span>:</span><br><span class="line">            <span class="keyword">if</span> i==index:</span><br><span class="line">                <span class="keyword">if</span> <span class="keyword">not</span> get:</span><br><span class="line">                    p.<span class="built_in">next</span>=p.<span class="built_in">next</span>.<span class="built_in">next</span> <span class="comment">#断开的节点无需手动free，因为python有垃圾回收机制</span></span><br><span class="line">                <span class="keyword">else</span>:</span><br><span class="line">                    <span class="keyword">return</span> p.<span class="built_in">next</span></span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">            p=p.<span class="built_in">next</span></span><br><span class="line">            i+=<span class="number">1</span></span><br><span class="line">        self.pointer.data-=<span class="number">1</span></span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">deleteall</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;删除全部元素，即头节点指针域指空&#x27;&#x27;&#x27;</span></span><br><span class="line">        p=self.pointer</span><br><span class="line">        p.<span class="built_in">next</span>=<span class="literal">None</span></span><br><span class="line">        self.pointer.data=<span class="number">0</span></span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">get</span>(<span class="params">self,index</span>):</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;获取第index个节点元素，index取值1~len(Link)&#x27;&#x27;&#x27;</span></span><br><span class="line">        <span class="keyword">return</span> self.delete(index,<span class="literal">True</span>).data</span><br><span class="line">        </span><br><span class="line"><span class="meta">    @property</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">len</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;链表长度，之前我们说头节点有空闲的数据域，我们可以存储链表长度信息，通过实时更新其值，可以避免硬计算&#x27;&#x27;&#x27;</span></span><br><span class="line">        p=self.pointer</span><br><span class="line">        i=<span class="number">0</span></span><br><span class="line">        <span class="keyword">while</span> p.<span class="built_in">next</span>:</span><br><span class="line">            p=p.<span class="built_in">next</span></span><br><span class="line">            i+=<span class="number">1</span> <span class="comment"># 硬计算</span></span><br><span class="line">        <span class="keyword">if</span> self.pointer.data!=i: <span class="comment">#为了避免错误，暂时我仍使用硬计算，并对头节点的数据域中的长度值进行检测</span></span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&#x27;头节点错误&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> i</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">insert</span>(<span class="params">self,index,val</span>):</span><br><span class="line">        <span class="string">&#x27;&#x27;&#x27;插入元素，index合法取值1到len(Link)+1，特别地，当index取值len(Link)+1时，为在尾部追加（特殊插入）&#x27;&#x27;&#x27;</span></span><br><span class="line">        node=Node(val)</span><br><span class="line">        <span class="keyword">if</span> index&lt;<span class="number">1</span> <span class="keyword">or</span> index&gt;self.<span class="built_in">len</span>+<span class="number">1</span>:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&#x27;下标溢出&#x27;</span>)</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        <span class="keyword">if</span> index==self.<span class="built_in">len</span>+<span class="number">1</span>:</span><br><span class="line">            self.append(node)</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        p=self.pointer</span><br><span class="line">        i=<span class="number">1</span></span><br><span class="line">        <span class="keyword">while</span> p.<span class="built_in">next</span>:</span><br><span class="line">            <span class="keyword">if</span> i==index:</span><br><span class="line">                t=p.<span class="built_in">next</span></span><br><span class="line">                p.<span class="built_in">next</span>=node</span><br><span class="line">                node.<span class="built_in">next</span>=t</span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">            p=p.<span class="built_in">next</span></span><br><span class="line">            i+=<span class="number">1</span></span><br><span class="line">        self.pointer.data+=<span class="number">1</span></span><br><span class="line">        </span><br><span class="line"><span class="keyword">if</span> __name__==<span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    L=Link() <span class="comment">#空链表</span></span><br><span class="line">    L.append(<span class="number">1</span>)</span><br><span class="line">    L.append(<span class="number">2</span>)</span><br><span class="line">    L.append(<span class="number">3</span>)</span><br><span class="line">    L.insert(<span class="number">1</span>,<span class="number">0</span>)</span><br><span class="line">    L.printf()</span><br><span class="line">    L.delete(<span class="number">1</span>)</span><br><span class="line">    L.printf()</span><br><span class="line">    L.deleteall()</span><br><span class="line">    L.append(<span class="string">&#x27;muggle&#x27;</span>)</span><br><span class="line">    L.append(<span class="string">&#x27;daiyang&#x27;</span>)</span><br><span class="line">    L.printf()</span><br><span class="line">    <span class="built_in">print</span>(L.get(<span class="number">2</span>))</span><br></pre></td></tr></table></figure><p>凡是可迭代对象都可以用<code>for</code>语句逐一遍历全部元素，这是检查一个对象是否可迭代的标准，要创建一个可迭代对象，必须实现<code>__iter__()</code>方法，其返回一个迭代器，迭代器内部持有一个状态，用于记录当前迭代所在的位置，迭代器必须实现<code>__next__()</code>用于迭代获取下一个元素并更新迭代状态，而迭代器也属于可迭代对象的范畴，因此也必须实现<code>__iter__()</code>方法，具体实现时返回自身即可</p><p>下面我们试着将上述不可迭代的链表对象（Link）转变为可迭代的列表对象（List），并在链表的基础上构建一个迭代器对象：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">List</span>(<span class="title class_ inherited__">Link</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__iter__</span>(<span class="params">self</span>): <span class="comment">#实现了__iter__方法之后，链表变成可迭代对象</span></span><br><span class="line">        <span class="keyword">return</span> ListIteration(self)</span><br><span class="line">        </span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ListIteration</span>: <span class="comment">#简单来说，迭代器就相当于“普通容器+迭代状态”</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,container</span>):</span><br><span class="line">        self.data=container <span class="comment">#迭代器由容器数据和状态构成</span></span><br><span class="line">        self.iterstate=<span class="number">1</span> <span class="comment">#迭代器当前的迭代状态</span></span><br><span class="line">        self.stopstate=self.data.<span class="built_in">len</span> <span class="comment">#终止</span></span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__iter__</span>(<span class="params">self</span>): <span class="comment">#对一个迭代器获取其迭代器，就是其本身</span></span><br><span class="line">        <span class="keyword">return</span> self</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__next__</span>(<span class="params">self</span>): <span class="comment">#根据当前迭代状态迭代下一个元素，并更新状态</span></span><br><span class="line">        <span class="keyword">while</span> self.iterstate&lt;=self.stopstate:</span><br><span class="line">            self.iterstate+=<span class="number">1</span></span><br><span class="line">            <span class="keyword">return</span> self.data.get(self.iterstate-<span class="number">1</span>)</span><br><span class="line">        <span class="keyword">raise</span> StopIteration <span class="comment">#对超出范围的元素迭代需要返回StopIteration，在for语句中该异常将被捕捉</span></span><br><span class="line">        </span><br><span class="line">a=<span class="type">List</span>() <span class="comment">#创建一个列表（可迭代对象）</span></span><br><span class="line">a.append(<span class="number">10</span>)</span><br><span class="line">a.append(<span class="number">12</span>)</span><br><span class="line">a.append(<span class="number">14</span>)</span><br><span class="line">a.append(<span class="number">16</span>)</span><br><span class="line">b=<span class="built_in">iter</span>(a) <span class="comment">#将自动调用a.__iter__()</span></span><br><span class="line"><span class="built_in">print</span>(b.__next__()) <span class="comment">#10 #或者写next(b)</span></span><br><span class="line">c=<span class="built_in">iter</span>(b) <span class="comment">#对迭代器调用iter()，返回自身，因此下面的c都可以替换为b</span></span><br><span class="line"><span class="built_in">print</span>(c.__next__()) <span class="comment">#12</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> c:</span><br><span class="line">    <span class="built_in">print</span>(i) <span class="comment">#14 16</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> a:</span><br><span class="line">    <span class="built_in">print</span>(i) <span class="comment">#10 12 14 16</span></span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>for</code>循环原理</span></div>    <div class="hide-content"><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> x <span class="keyword">in</span> [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]:</span><br><span class="line">    <span class="built_in">print</span>(x)</span><br></pre></td></tr></table></figure><p>等价于：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#1.首先通过iter()获取迭代器对象</span></span><br><span class="line">iterator=<span class="built_in">iter</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line"><span class="comment">#2.在循环中不断调用next方法获取迭代器对象的下一个值直至捕捉到StopIteration异常退出循环</span></span><br><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        x=<span class="built_in">next</span>(iterator)</span><br><span class="line">        <span class="built_in">print</span>(x)</span><br><span class="line">    <span class="keyword">except</span> StopIteration:</span><br><span class="line">        <span class="keyword">break</span></span><br></pre></td></tr></table></figure></div></div><p><code>itertools</code>模块提供了诸多具有特殊用途的迭代器，譬如<code>count()</code>返回一个无限循环的迭代器（既然无限循环为什么不直接使用<code>while</code>？因为<code>count()</code>可以很方便地记录当前迭代次序），再如<code>cycle()</code>从有限序列生成无限序列，用于循环遍历序列，等等，下面是<code>cycle</code>的实现（我随便写的，非官方实现）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">cycle</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,container,start=<span class="number">0</span></span>): <span class="comment">#start指定从序列的哪一个元素开始循环迭代</span></span><br><span class="line">        self.data=container</span><br><span class="line">        self.iterstate=start</span><br><span class="line">        self.<span class="built_in">len</span>=<span class="built_in">len</span>(container)</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__iter__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> self</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__next__</span>(<span class="params">self</span>):</span><br><span class="line">        self.iterstate+=<span class="number">1</span></span><br><span class="line">        <span class="keyword">return</span> self.data[(self.iterstate-<span class="number">1</span>)%self.<span class="built_in">len</span>]</span><br><span class="line">        </span><br><span class="line">a=cycle([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],) <span class="comment">#不同于上面自定义的列表是一个可迭代对象（但非迭代器对象），此处cycle(...)直接就是迭代器对象，当然也就是可迭代对象。再如python几种内置类型list、tuple、dict、set、str等，也都是可迭代对象，但非迭代器对象（为何这样设计？道理很简单，迭代器对象都是用完即扔的，这实在是太浪费资源了，于是你需要不停在内存中创建和回收对象，但重复将可迭代对象转换为迭代器就很便宜了），譬如a=[1,2,3];next(a)将报错：TypeError: &#x27;list&#x27; object is not an iterator</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(a),<span class="built_in">next</span>(a),<span class="built_in">next</span>(a),<span class="built_in">next</span>(a),<span class="built_in">next</span>(a),<span class="built_in">next</span>(a),<span class="built_in">next</span>(a)) <span class="comment">#1 2 3 1 2 3 1</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> a:</span><br><span class="line">    <span class="built_in">print</span>(i) <span class="comment">#无限循环，因为for循环只会在next(迭代器)抛出StopIteration（停止迭代异常）的时候终止</span></span><br></pre></td></tr></table></figure><p>判断是否可迭代以及是否是迭代器：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">import</span> collections</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">isinstance</span>([],collections.Iterable) <span class="comment">#list是可迭代对象吗？</span></span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">isinstance</span>([],collections.Iterator) <span class="comment">#list是迭代器对象吗？</span></span><br><span class="line"><span class="literal">False</span></span><br></pre></td></tr></table></figure><img src="https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210429214739.png" alt="图2. 可迭代对象、迭代器、生成器关系[4]" style="width:540px"><p>再说说生成器，实际上生成器本质就是迭代器（因此生成器也是用完即弃），只要迭代的下一个元素是即时计算（惰性计算）的，那就是生成器，普通迭代器迭代下一个元素，是从某个容器中取出来，所有元素事先已经计算得出，其始终占用着一片内存区域（因此只有生成器才能实现“无限序列”）。在python2中<code>range()</code>就是一个普通迭代器（譬如<code>range(10000)</code>内存中真的就存在10000个数字），<code>xrange()</code>则是生成器（此时内存中就没有10000个数据占用），下面我们自行设计一个生成器版本的<code>range</code>（Range）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Range</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,*args</span>):</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">len</span>(args)==<span class="number">1</span>:</span><br><span class="line">            self.start,self.stop,self.step=<span class="number">0</span>,args[<span class="number">0</span>],<span class="number">1</span></span><br><span class="line">        <span class="keyword">elif</span> <span class="built_in">len</span>(args)==<span class="number">2</span>:</span><br><span class="line">            self.start,self.stop,self.step=*args,<span class="number">1</span></span><br><span class="line">        <span class="keyword">elif</span> <span class="built_in">len</span>(args)==<span class="number">3</span>:</span><br><span class="line">            self.start,self.stop,self.step=args</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">raise</span> ValueError(<span class="string">&#x27;[参数错误] Range(start[,stop[,step]])&#x27;</span>)</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__iter__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> self</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__next__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">while</span> self.start&lt;self.stop:</span><br><span class="line">            self.start+=self.step</span><br><span class="line">            <span class="keyword">return</span> self.start-self.step</span><br><span class="line">        <span class="keyword">raise</span> StopIteration</span><br><span class="line">        </span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> Range(<span class="number">3</span>,<span class="number">9</span>,<span class="number">2</span>):</span><br><span class="line">    <span class="built_in">print</span>(i) <span class="comment">#3, 5, 7</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(Range(<span class="number">5</span>))) <span class="comment">#[0, 1, 2, 3, 4]，工厂函数list自动计算生成器各个元素的值并以列表返回</span></span><br></pre></td></tr></table></figure><p>通常采用<code>yield</code>关键字构造生成器，在函数中使用<code>yield</code>关键字代替<code>return</code>关键字（称为生成器函数），函数调用将返回一个生成器对象，此时函数内部代码不会立即执行，除非对其调用<code>next()</code>方法，函数执行流将在<code>yield</code>位置中止，并返回<code>yield</code>语句中的表达式值，继续调用<code>next()</code>方法，函数执行流将从<code>yield</code>中止处继起并在下一次遇到<code>yield</code>时中止…，<code>yield</code>使得生成器的语法变得相当优雅（我们几乎从不使用上面Range示例的方式编写生成器，python本身也不认为那是一个生成器对象，如<code>isinstance(Range(5),types.GeneratorType)</code>会返回<code>False</code>），简单来说生成器函数就是在一个循环中不断计算并产生新值的过程且只在需要时计算（“惰性计算”，不调用<code>next()</code>方法则不计算），它定义了数据生产的流程，当我们需要将生产和消耗分离的时候，使用生成器可以方便地解耦，任意函数稍作修改便可转换为生成器函数，只需要将<code>return</code>关键字改成<code>yield</code>关键字，现在我们用<code>yield</code>方式重写Range：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">Range</span>(<span class="params">*args</span>):</span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">len</span>(args)==<span class="number">1</span>:</span><br><span class="line">        start,stop,step=<span class="number">0</span>,args[<span class="number">0</span>],<span class="number">1</span></span><br><span class="line">    <span class="keyword">elif</span> <span class="built_in">len</span>(args)==<span class="number">2</span>:</span><br><span class="line">        start,stop,step=*args,<span class="number">1</span></span><br><span class="line">    <span class="keyword">elif</span> <span class="built_in">len</span>(args)==<span class="number">3</span>:</span><br><span class="line">        start,stop,step=args</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">raise</span> ValueError(<span class="string">&#x27;[参数错误] Range(start[,stop[,step]])&#x27;</span>)</span><br><span class="line">    <span class="keyword">while</span> start&lt;stop:</span><br><span class="line">        start+=step</span><br><span class="line">        <span class="keyword">yield</span> start-step</span><br><span class="line">    <span class="keyword">raise</span> StopIteration <span class="comment">#生成器其实没必要在结束位置处显式抛出该异常，因为会自动抛，但是（非生成器的）迭代器必须手动抛出</span></span><br><span class="line">            </span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> Range(<span class="number">3</span>,<span class="number">9</span>,<span class="number">2</span>):</span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line">    </span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(Range(<span class="number">5</span>))) <span class="comment">#[0, 1, 2, 3, 4]</span></span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>惰性计算</span></div>    <div class="hide-content"><p>为了深入了解“惰性计算”，看个<a href="https://segmentfault.com/q/1010000016013187">示例</a>：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">g=(i <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>))</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> [<span class="number">1</span>,<span class="number">10</span>]:</span><br><span class="line">    g=(i+j <span class="keyword">for</span> j <span class="keyword">in</span> g)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(g))</span><br></pre></td></tr></table></figure><p>不少人（包括我）认为结果会是<code>[11,12,13,14]</code>，但是解释器运行结果却是<code>[20, 21, 22, 23]</code>，why？</p><p>对于一个生成器表达式<code>(expression1 for variables in expression2)</code>，<code>expression1</code>只有在调用生成器对象的<code>__next__()</code>方法时才会执行，而<code>for</code>子句则是即时计算的，即<code>expression2</code>是即时计算的（根据<code>for</code>原理<code>expression2</code>应返回一个可迭代对象），另注意，<code>for</code>子句可能是多层<code>for</code>循环嵌套的，只有最左边的<code>for</code>子句才会即时计算，譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">n=<span class="number">2</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">bar</span>():</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">range</span>(n)</span><br><span class="line"></span><br><span class="line">g1=(i <span class="keyword">for</span> i <span class="keyword">in</span> bar()) <span class="comment">#for子句表达式是即时计算的，此处等同于：g1=(i for i in range(2))</span></span><br><span class="line">n=<span class="number">3</span></span><br><span class="line">g2=((i,j) <span class="keyword">for</span> i <span class="keyword">in</span> bar() <span class="keyword">for</span> j <span class="keyword">in</span> bar()) <span class="comment">#只有最左侧的for子句表达式才即时计算，此处等同于：g2=((i,j) for i in range(3) for j in bar())</span></span><br><span class="line">n=<span class="number">4</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(g1))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(g2)) <span class="comment">#list遍历生成器元素，由于最后修改的n值为4，于是此处等同于：g2=((i,j) for i in range(3) for j in range(4))</span></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">[0, 1]</span></span><br><span class="line"><span class="string">[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#如果expression2是一个变量引用，将变量引用指向其他对象不会改变生成器数值，如果变量引用指向一个可变对象，修改该可变对象则会改变生成器数值：</span></span><br><span class="line">a=<span class="built_in">range</span>(<span class="number">2</span>)</span><br><span class="line">g=(i <span class="keyword">for</span> i <span class="keyword">in</span> a)</span><br><span class="line">a=<span class="built_in">range</span>(<span class="number">10</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(g)) <span class="comment">#[0, 1]</span></span><br><span class="line"></span><br><span class="line">a=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>]</span><br><span class="line">g=(i <span class="keyword">for</span> i <span class="keyword">in</span> a)</span><br><span class="line">a.append(<span class="number">5</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(g)) <span class="comment">#[1, 2, 3, 4, 5]</span></span><br></pre></td></tr></table></figure><p>回到最初的问题，第一次循环，生成器<code>g</code>中的值其实就是<code>[i+0,i+1,i+2,i+3]</code>（尚未计算），第二次循环，<code>g</code>变成<code>[i+(i+0),i+(i+1),i+(i+2),i+(i+3)]</code>（尚未计算），最后通过<code>list(g)</code>遍历时，<code>i=10</code>，于是输出<code>[20,21,22,23]</code>。将其用生成器函数改写一下同时展开<code>for</code>循环，其执行过程相当于：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">gen1</span>():</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">        <span class="keyword">yield</span> i</span><br><span class="line"></span><br><span class="line">i=<span class="number">1</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">gen2</span>():</span><br><span class="line">    <span class="keyword">for</span> j <span class="keyword">in</span> gen1():</span><br><span class="line">        <span class="keyword">yield</span> i+j</span><br><span class="line"></span><br><span class="line">i=<span class="number">10</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">gen3</span>():</span><br><span class="line">    <span class="keyword">for</span> j <span class="keyword">in</span> gen2():</span><br><span class="line">        <span class="keyword">yield</span> i+j</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(gen3())) <span class="comment">#[20, 21, 22, 23]</span></span><br></pre></td></tr></table></figure><p>这就很明了了，或者再改写一下得到：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">i=<span class="number">1</span></span><br><span class="line"></span><br><span class="line">i=<span class="number">10</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">gen3</span>():</span><br><span class="line">    <span class="keyword">for</span> k <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">        <span class="keyword">yield</span> i+i+k</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(gen3())) <span class="comment">#[20, 21, 22, 23]</span></span><br></pre></td></tr></table></figure><p>另外如果不是通过<code>list(g)</code>输出生成器序列元素，而是用<code>for</code>循环替换之：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> g:</span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">20</span></span><br><span class="line"><span class="string">41</span></span><br><span class="line"><span class="string">84</span></span><br><span class="line"><span class="string">171</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#破解之法就是替换for循环变量</span></span><br><span class="line"><span class="keyword">for</span> k <span class="keyword">in</span> g:</span><br><span class="line">    <span class="built_in">print</span>(k)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">20</span></span><br><span class="line"><span class="string">21</span></span><br><span class="line"><span class="string">22</span></span><br><span class="line"><span class="string">23</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>要注意迭代变量的使用，如果使用<code>i</code>作为迭代变量，结果将会发生变化，这仍是惰性计算导致的，结合<code>for</code>循环原理原因就很清楚了（每次循环都会执行<code>i=next(g)</code>，而<code>i</code>将影响生成器序列的数值计算）</p></div></div><p><code>GeneratorExit</code>异常标志着生成器迭代过程的非正常终止，相反，正常终止不会引发该异常：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">n</span>): <span class="comment">#不断生产数据</span></span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        <span class="keyword">while</span> n&gt;<span class="number">0</span>:</span><br><span class="line">            <span class="keyword">yield</span> n</span><br><span class="line">            n-=<span class="number">1</span></span><br><span class="line">    <span class="keyword">except</span> GeneratorExit:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;exiting...&#x27;</span>)</span><br><span class="line">        </span><br><span class="line">g=f(<span class="number">3</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> g: <span class="comment">#每产生一个数据就消耗一个数据，如果使用while循环是无法分离生产和消耗两个部分的，它们势必混合在一起</span></span><br><span class="line">    <span class="built_in">print</span>(i) <span class="comment">#3 2 1</span></span><br></pre></td></tr></table></figure><p>如果生成器仅被部分使用，将在<code>yield</code>处引发<code>GeneratorExit</code>异常（但一般不用人为捕获），并自动调用<code>close()</code>方法关闭生成器，如果再次调用<code>next()</code>方法将引发<code>StopIteration</code>异常，它已不能继续产生新值了：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">g=f(<span class="number">3</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> g:</span><br><span class="line">    <span class="keyword">if</span> i&gt;<span class="number">1</span>:</span><br><span class="line">        <span class="built_in">print</span>(i) <span class="comment">#3 2 exiting...</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line">g.__next__() <span class="comment">#出现StopIteration异常，不要再期望输出1</span></span><br></pre></td></tr></table></figure><p>注：<code>for</code>语句能判断生成器函数是否全部完成，如果你是通过<code>while</code>和<code>next</code>进行迭代是无法判断的（只有在整个程序终止时才会引发该异常），这个时候就需要显式关闭（但这不是必须的），鉴于你通常会忘记，一般我们只使用<code>for</code>循环来迭代生成器</p><p>手动执行<code>close()</code>方法亦将在<code>yield</code>处引发<code>GeneratorExit</code>异常（假设生成器已被使用过的话）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">g=f(<span class="number">3</span>)</span><br><span class="line"><span class="built_in">print</span>(g.__next__()) <span class="comment">#3</span></span><br><span class="line">g.close() <span class="comment">#exiting...</span></span><br></pre></td></tr></table></figure><p>删除生成器对象也会引发该异常：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">g=f(<span class="number">3</span>)</span><br><span class="line"><span class="built_in">print</span>(g.__next__()) <span class="comment">#3</span></span><br><span class="line"><span class="keyword">del</span> g <span class="comment">#exiting...</span></span><br></pre></td></tr></table></figure><p>小结一下：</p><ol><li>生成器在<code>close()</code>方法后就无法再进行迭代，再调用<code>next()</code>方法就会抛出<code>StopIteration</code>异常</li><li>生成器调用<code>close()</code>方法会在<code>yield</code>处抛出<code>GeneratorExit</code>异常，但前提是至少调用一次生成器的<code>next()</code>方法才会产生<code>GeneratorExit</code>异常，如果生成器没有启动则不会抛出异常</li><li>生成器内捕捉<code>GeneratorExit</code>异常后，可以继续执行剩余的代码，但剩余的代码中不能再包含<code>yield</code>语句，否则抛出<code>RuntimeError</code>异常</li><li><code>GeneratorExit</code>异常不能通过<code>Exception</code>捕捉，因为其直接继承自所有异常的基类<code>BaseException</code></li></ol><p>上面我们说了为什么内置的类型如<code>list</code>、<code>tuple</code>、<code>dict</code>、<code>set</code>、<code>str</code>都被设计为可迭代对象而非迭代器（迭代器是“一次性”的），原因不止一条，譬如<code>in</code>关键字就不能用于迭代器对象，<code>x in y</code>语句的工作原理是，首先调用对象<code>y</code>上的<code>iter()</code>方法，然后不断执行<code>next()</code>方法获取下一个元素，直至<code>x==next(y)</code>，返回<code>True</code>，否则返回<code>False</code>，表示容器<code>y</code>中不存在<code>x</code>，看一个错误范例就明了了：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">y=(i <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">5</span>))</span><br><span class="line">x=<span class="number">1</span></span><br><span class="line"><span class="built_in">print</span>(x <span class="keyword">in</span> y) <span class="comment">#True</span></span><br><span class="line"><span class="built_in">print</span>(x <span class="keyword">in</span> y) <span class="comment">#False</span></span><br></pre></td></tr></table></figure><p>第一次执行<code>x in y</code>时候，<code>iter(y)</code>返回<code>y</code>自身，执行两次<code>next(y)</code>，生成器<code>y</code>中的前两个元素0和1被消耗（发现<code>x</code>存在于<code>y</code>中），结果返回<code>True</code>，第二次执行<code>x in y</code>的时候，<code>iter(y)</code>仍旧返回被部分消耗的<code>y</code>自身，继续调用<code>next()</code>方法，显然后面的元素2、3、4中不存在1，因此返回<code>False</code>。这种情况下如果要进行存在性判断，可以先将生成器转换为列表（<code>list(y)</code>），一个可迭代对象（而<code>iter(可迭代对象)</code>总是返回一个全新的迭代器对象）</p><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>yield</code>与递归混用</span></div>    <div class="hide-content"><p>将<code>yield</code>与递归混用时要小心，很容易出错，先来看一个示例，遍历一个嵌套的列表（展平操作）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">flatten</span>(<span class="params">lists</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> lists:</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">isinstance</span>(i,<span class="built_in">list</span>):</span><br><span class="line">            flatten(i)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="built_in">print</span>(i)</span><br><span class="line"></span><br><span class="line">a=[<span class="number">0</span>,[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">4</span>,<span class="number">5</span>,[<span class="number">6</span>,<span class="number">7</span>]],[<span class="number">8</span>,<span class="number">9</span>,<span class="number">10</span>]]</span><br><span class="line">flatten(a) <span class="comment">#0 1 2 3 4 5 6 7 8 9 10</span></span><br></pre></td></tr></table></figure><p>改写为生成器（这个改写是错误的）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">flatten</span>(<span class="params">lists</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> lists:</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">isinstance</span>(i,<span class="built_in">list</span>):</span><br><span class="line">            flatten(i) <span class="comment">#位置2</span></span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">yield</span> i <span class="comment">#位置1</span></span><br><span class="line">            </span><br><span class="line">a=[<span class="number">0</span>,[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">4</span>,<span class="number">5</span>,[<span class="number">6</span>,<span class="number">7</span>]],[<span class="number">8</span>,<span class="number">9</span>,<span class="number">10</span>]]</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> flatten(a):</span><br><span class="line">    <span class="built_in">print</span>(i) <span class="comment">#仅仅打印出0</span></span><br></pre></td></tr></table></figure><p>这个结果似乎出人意料，分析一下，设<code>g=flatten(a)</code>，<code>for</code>语句第一次调用<code>g</code>的<code>next()</code>方法，由于列表<code>a</code>的第一个元素是数字，因此函数执行流将到达位置1处中止并返回<code>yield</code>表达式值，即0，第二次调用<code>next()</code>方法，执行流从中止处继续，由于列表<code>a</code>的第二个元素是列表，因此到达位置2处，关键即在于此，位置2处的<code>flatten(i)</code>将返回一个生成器，然而生成器是惰性的，在没有调用<code>next()</code>方法的情况下生成器根本不会执行（修正的办法就是手动去迭代这个生成器），更何况返回的生成器对象还没有被赋值，没有外部引用的它随即会被当作垃圾回收，因此完全可以忽略它的存在，即可以将位置2处的语句替换成<code>pass</code>，于是执行流继续向后执行，而列表<code>a</code>中的后面的两个元素仍都是列表对象，因此执行流不会再到达位置1，生成器也不会再生产值，执行流结束将抛出<code>StopIteration</code>异常，分析结束，可知<code>g</code>这个迭代器的长度仅为1。修正：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">flatten</span>(<span class="params">lists</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> lists:</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">isinstance</span>(i,<span class="built_in">list</span>):</span><br><span class="line">            <span class="keyword">for</span> j <span class="keyword">in</span> flatten(i):</span><br><span class="line">                <span class="keyword">yield</span> j</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">yield</span> i</span><br></pre></td></tr></table></figure></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><p>序列操作三大函数：</p><ul><li><p><code>map(func,seq1[,seq2,...])</code><br>批量映射函数，<code>map</code>将序列中的元素映射或转换成其他元素，<code>func</code>充当转换器</p><ol><li>当只有一个序列参数时，<code>map(func,seq)</code>等同于<code>[func(e) for e in seq]</code></li><li>当有多个序列参数时，<code>map(func,seq1,seq2,...)</code>等同于<code>[func(*t) for t in [*zip(seq1,seq2,...)]]</code>（这些序列的长度的长度可以不一致，按最短的来，在python2中，当<code>func</code>取<code>None</code>时，<code>map</code>就等同于<code>zip</code>，但python3已不再允许<code>func</code>参数为<code>None</code>）<br>打个比方，如果将<code>seq1</code>、<code>seq2</code>、… 各自比作飞机的不同的零件提供商，那么<code>map</code>函数就是批量制造飞机的工厂，<code>func</code>就是制造飞机的原理图纸</li></ol> <div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>zip</code>函数</span></div>    <div class="hide-content"><p>简单应用：</p><ul><li><p>快速构建字典</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">dict</span>(<span class="built_in">zip</span>(<span class="built_in">range</span>(<span class="number">5</span>),<span class="built_in">range</span>(<span class="number">5</span>,<span class="number">10</span>))) <span class="comment">#通过dict类初始化函数或者说工厂函数</span></span><br><span class="line">&#123;<span class="number">0</span>: <span class="number">5</span>, <span class="number">1</span>: <span class="number">6</span>, <span class="number">2</span>: <span class="number">7</span>, <span class="number">3</span>: <span class="number">8</span>, <span class="number">4</span>: <span class="number">9</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>&#123;k:v <span class="keyword">for</span> k,v <span class="keyword">in</span> <span class="built_in">zip</span>(<span class="built_in">range</span>(<span class="number">5</span>),<span class="built_in">range</span>(<span class="number">5</span>,<span class="number">10</span>))&#125; <span class="comment">#通过字典生成式</span></span><br><span class="line">&#123;<span class="number">0</span>: <span class="number">5</span>, <span class="number">1</span>: <span class="number">6</span>, <span class="number">2</span>: <span class="number">7</span>, <span class="number">3</span>: <span class="number">8</span>, <span class="number">4</span>: <span class="number">9</span>&#125;</span><br></pre></td></tr></table></figure></li><li><p>利用<code>zip</code>完成二维矩阵转置</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">a = [[<span class="number">11</span>, <span class="number">12</span>, <span class="number">13</span>], [<span class="number">14</span>, <span class="number">15</span>, <span class="number">16</span>], [<span class="number">17</span>, <span class="number">18</span>, <span class="number">19</span>], [<span class="number">20</span>, <span class="number">21</span>, <span class="number">22</span>]] <span class="comment">#按行描述的矩阵，现将该矩阵按列描述，即为转置的结果</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> a: <span class="comment">#原矩阵</span></span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line"><span class="comment">#利用列表生成式进行转置</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> [[row[col] <span class="keyword">for</span> row <span class="keyword">in</span> a] <span class="keyword">for</span> col <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(a[<span class="number">0</span>]))]:</span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line"><span class="comment">#这个生成式正是zip压缩的过程，因此直接用zip很简便：</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">zip</span>(*a): <span class="comment">#*为解包裹函数参数传递</span></span><br><span class="line">    <span class="built_in">print</span>(i)</span><br></pre></td></tr></table></figure></li><li><p>将序列按连续k个值分组</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#假设是将序列a按连续两个值分组</span></span><br><span class="line">a = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>]</span><br><span class="line"></span><br><span class="line"><span class="comment">#大佬写法1</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">zip</span>(*[<span class="built_in">iter</span>(a)]*<span class="number">2</span>): <span class="comment">#操作符优先级为：zip(*([iter(a)]*2))，这里的*是函数参数的解包裹传递方式，就是将一个序列解包为诸多的位置参数传给函数</span></span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line">    </span><br><span class="line"><span class="comment">#普通写法2</span></span><br><span class="line">b=<span class="built_in">iter</span>(a)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">zip</span>(b,b): <span class="comment">#另注意不能构成长度为2的分组的部分元素（残值）将被丢弃</span></span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">(1, 2)</span></span><br><span class="line"><span class="string">(3, 4)</span></span><br><span class="line"><span class="string">(5, 6)</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#正常人写法3</span></span><br><span class="line">myslice=<span class="keyword">lambda</span> a,k:[a[i:i+k] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>,<span class="built_in">len</span>(a),k)] <span class="comment">#缺点在于假设传入的a万一是一个迭代器（无法计算长度，无len()方法），那就需要转为列表或其它可计算长度的对象类型，相比之下，zip调用next()更鲁棒。这种写法不丢弃“残值”</span></span><br><span class="line"><span class="built_in">print</span>(myslice(a,<span class="number">2</span>)) <span class="comment">#[[1, 2], [3, 4], [5, 6], [7]]</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#正常人写法4</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">zip</span>(a[::<span class="number">2</span>],a[<span class="number">1</span>::<span class="number">2</span>]): <span class="comment">#相邻2个元素</span></span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">zip</span>(a[::<span class="number">3</span>],a[<span class="number">1</span>::<span class="number">3</span>],a[<span class="number">2</span>::<span class="number">3</span>]): <span class="comment">#相邻3个元素</span></span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line"><span class="comment"># 假设要相邻k个元素，就要进行k次切片，显然很麻烦，改写一下：</span></span><br><span class="line">myzip=<span class="keyword">lambda</span> k:<span class="built_in">zip</span>(*[a[i::k] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(k)])</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> myzip(<span class="number">4</span>):</span><br><span class="line">    <span class="built_in">print</span>(i)</span><br></pre></td></tr></table></figure><p>解释：先说一下<code>zip</code>函数的工作原理，函数接收任意数量的可迭代对象参数，第一步利用<code>iter()</code>将参数全部转换为迭代器对象，第二步在一个<code>while</code>循环中，每一轮，依次获取每个迭代器的下一项，然后组装成一个元组，并追加到返回值序列中，当最短的迭代器对象抛出<code>StopIteration</code>异常时，退出<code>while</code>循环。<code>zip</code>原理（看看就好）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">myzip</span>(<span class="params">*args</span>):</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;the principle of function zip&#x27;&#x27;&#x27;</span></span><br><span class="line">    m=<span class="built_in">list</span>(<span class="built_in">map</span>(<span class="built_in">iter</span>,args))</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        ret=[] <span class="comment">#返回值序列</span></span><br><span class="line">        <span class="keyword">while</span> <span class="number">1</span>:</span><br><span class="line">            li=[]</span><br><span class="line">            <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(m)):</span><br><span class="line">                li.append(m[i].__next__())</span><br><span class="line">            ret.append(<span class="built_in">tuple</span>(li))</span><br><span class="line">    <span class="keyword">except</span> StopIteration:</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line">    <span class="keyword">return</span> ret</span><br><span class="line">ret=myzip([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>],[<span class="number">8</span>,<span class="number">9</span>,<span class="number">10</span>,<span class="number">11</span>,<span class="number">12</span>],[<span class="number">13</span>,<span class="number">14</span>])</span><br><span class="line"><span class="built_in">print</span>(ret) <span class="comment">#[(1, 4, 8, 13), (2, 5, 9, 14)]</span></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;或者：</span></span><br><span class="line"><span class="string">def myzip(*args): #直接根据最短的列表长度确定轮回次数nloop</span></span><br><span class="line"><span class="string">    m=list(map(iter,args))</span></span><br><span class="line"><span class="string">    nloop=min([len(args[i]) for i in range(len(m))])</span></span><br><span class="line"><span class="string">    #ret=[tuple([m[i].__next__() for i in range(len(m))]) for j in range(len(list(m[0])))] #和下面修改的区别在于：list(one iteration)会导致对迭代器（参数）的一遍迭代，结果想再调用next就会立即抛出异常，由此我们可以大概知道工厂函数list的原理：list(iterable obj)，首先将可迭代参数对象转为迭代器，然后迭代(next)整个迭代器得到新的列表对象，其中的元素都是对参数对象中元素的引用</span></span><br><span class="line"><span class="string">    ret=[tuple([m[i].__next__() for i in range(len(m))]) for j in range(nloop)]</span></span><br><span class="line"><span class="string">    return ret</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>现在回头看写法2就非常明了了，写法1就是换个写法而已，前提是你要知道<code>[obj]*i</code>将返回一个长度为<code>i</code>的序列<code>[obj,obj,...]</code>，其中每一项都是对原始的<code>obj</code>对象的引用（或者说浅复制），如果是按连续k个值分组，那就将<code>zip(*[iter(a)]*2)</code>中的2换成k即可<br>注：实际上<code>zip()</code>的返回值是一个类似生成器的对象，即用即弃</p></li><li><p>滑动窗口</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> itertools <span class="keyword">import</span> islice</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">slicing</span>(<span class="params">obj,n</span>):</span><br><span class="line">    <span class="comment">#obj为可迭代序列，n为窗口大小，每次滑动（步长为1）我们看见的序列内容都不一样，函数返回全部窗口滑动状态下的序列的内容视图</span></span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">zip</span>(*[islice(obj,i,<span class="literal">None</span>) <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(n)]) <span class="comment">#注意obj只能是可迭代对象，不能是迭代器，因为islice会消耗迭代器。最简单的还是用obj[i:]替代islice(obj,i,None)，其实我也想不到islice有什么用处，参考：https://stackoverflow.com/questions/41079001/python-3-5-slice-vs-islice-vs-alternatives-efficiency-comparison</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> slicing([<span class="number">2</span>,<span class="number">3</span>,<span class="number">8</span>,<span class="number">5</span>,<span class="number">1</span>],<span class="number">3</span>):</span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line">    </span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">(2, 3, 8)</span></span><br><span class="line"><span class="string">(3, 8, 5)</span></span><br><span class="line"><span class="string">(8, 5, 1)</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></li><li><p>反转字典</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>m = &#123;<span class="string">&#x27;a&#x27;</span>: <span class="number">1</span>, <span class="string">&#x27;b&#x27;</span>: <span class="number">2</span>, <span class="string">&#x27;c&#x27;</span>: <span class="number">3</span>, <span class="string">&#x27;d&#x27;</span>: <span class="number">4</span>&#125; <span class="comment">#字典value必须都是不可变对象</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">dict</span>(<span class="built_in">zip</span>(*<span class="built_in">list</span>(<span class="built_in">zip</span>(*m.items()))[::-<span class="number">1</span>]))</span><br><span class="line">&#123;<span class="number">1</span>: <span class="string">&#x27;a&#x27;</span>, <span class="number">2</span>: <span class="string">&#x27;b&#x27;</span>, <span class="number">3</span>: <span class="string">&#x27;c&#x27;</span>, <span class="number">4</span>: <span class="string">&#x27;d&#x27;</span>&#125;</span><br></pre></td></tr></table></figure></li></ul></div></div></li><li><p><code>filter(func,seq)</code><br>序列过滤器，过滤掉不符合条件的元素，返回那些符合条件的元素所组成的新（子）序列，<code>func</code>充当筛选器（应返回<code>True</code>或<code>False</code>）。等同于<code>[e for e in seq if func(e)]</code></p></li><li><p><code>reduce(func,seq[,initial])</code><br>该函数工作流程是：在迭代<code>seq</code>的过程中，首先将前两个元素传给<code>func</code>函数（可以通过<code>initial</code>参数额外指定首个元素值，相当于序列<code>seq</code>增加了一个元素，新序列为<code>[initial,*seq]</code>），函数加工后将返回值和<code>seq</code>序列的第三个元素重新传入<code>func</code>函数，再将返回值和<code>seq</code>的第四个元素一起传入<code>func</code>函数，以此类推，直至遍历到<code>seq</code>的最后一个元素，最后一次执行的<code>func</code>函数输出将作为<code>reduce</code>函数的返回值<br>注：python3从全局空间移除了该函数，需要从标准库<code>functools</code>中引入<br><code>reduce</code>最大的特点在于，过程中每一次迭代都携带着上一次的迭代结果，这种对历史的可见性有时候很有用。记忆力是个好东西<br>案例1（计算阶乘）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">from</span> functools <span class="keyword">import</span> reduce</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>reduce(<span class="keyword">lambda</span> x,y:x*y,<span class="built_in">range</span>(<span class="number">1</span>,<span class="number">6</span>)) <span class="comment"># 也可以写成：import operator;reduce(operator.mul,range(1,6) #计算5!</span></span><br><span class="line"><span class="number">120</span></span><br></pre></td></tr></table></figure><p>案例2（将整数列表拼成整数）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>reduce(<span class="keyword">lambda</span> x,y:x*<span class="number">10</span>+y,[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>])</span><br><span class="line"><span class="number">12345</span></span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>案例3（计算斐波那契）</span></div>    <div class="hide-content">  <div class="note green icon disabled"><i class="note-icon fas fa-question"></i><p>已知斐波那契数列：1、1、2、3、5、8、13、21、34、……<br>要求：输出数列第n项的值</p></div>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#根据数列规律：当前项的值等于前两项的和，即在迭代过程中只要保留最近的历史（前两项元素值）即可，因此基调确定，即reduce中的func参数应该返回一个二元组，而参数seq其实对计算没用，仅用于迭代。且实际假设斐波那契序列为（增加首项0）：0,1,1,2,3,5,8,...，然后将前两项(0,1)作为reduce的initial参数，于是reduce首次迭代可以计算出第三项数值（前两项和）为1，并使func返回第二项和第三项的值(1,1)，然后第二次迭代可以计算出第四项数值为2，并使func返回第三项和第四项的值(1,2)，以此类推</span></span><br><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> reduce</span><br><span class="line">fib=<span class="keyword">lambda</span> n:<span class="number">1</span> <span class="keyword">if</span> n==<span class="number">1</span> <span class="keyword">else</span> reduce(<span class="keyword">lambda</span> x,y:(x[<span class="number">1</span>],x[<span class="number">0</span>]+x[<span class="number">1</span>]),<span class="built_in">range</span>(n-<span class="number">1</span>),(<span class="number">0</span>,<span class="number">1</span>))[<span class="number">1</span>]</span><br><span class="line"><span class="built_in">print</span>(fib(<span class="number">10</span>)) <span class="comment">#55</span></span><br></pre></td></tr></table></figure>  <div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>其他实现</span></div>    <div class="hide-content"><p>普通递归：</p>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">Fibonacci</span>(<span class="params">n=<span class="number">6</span></span>):</span><br><span class="line">    <span class="keyword">if</span> n==<span class="number">1</span> <span class="keyword">or</span> n==<span class="number">2</span>:</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">return</span> Fibonacci(n-<span class="number">2</span>)+Fibonacci(n-<span class="number">1</span>)</span><br><span class="line">        </span><br><span class="line">ret=Fibonacci(<span class="number">10</span>) <span class="comment">#由于递归层数限制，如果n取值过大，会爆栈，所以严格来说，这种写法是错误的，另一个关键问题是递归计算实在是太耗时了，其具有指数级的时间复杂度！试试求取第35数值，已经明显迟钝，如果把上述递归树画出来，其实有大量结点是重复计算，关于速度的改进参见第二章节·装饰器</span></span><br><span class="line"><span class="built_in">print</span>(ret)</span><br></pre></td></tr></table></figure><p>看看大佬们是怎么写的：</p>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">fib1</span>(<span class="params">n</span>):</span><br><span class="line">    <span class="keyword">return</span> n&lt;=<span class="number">2</span> <span class="keyword">and</span> <span class="number">1</span> <span class="keyword">or</span> fib1(n-<span class="number">1</span>)+fib1(n-<span class="number">2</span>) <span class="comment">#秀我一脸</span></span><br><span class="line">  </span><br><span class="line"><span class="comment">#等价于：</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fib2</span>(<span class="params">n</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span> <span class="keyword">if</span> n&lt;=<span class="number">2</span> <span class="keyword">else</span> fib2(n-<span class="number">1</span>)+fib2(n-<span class="number">2</span>)</span><br><span class="line">    </span><br><span class="line"><span class="comment">#形式再简化：</span></span><br><span class="line">fib3=<span class="keyword">lambda</span> n:<span class="number">1</span> <span class="keyword">if</span> n&lt;=<span class="number">2</span> <span class="keyword">else</span> fib3(n-<span class="number">1</span>)+fib3(n-<span class="number">2</span>)</span><br></pre></td></tr></table></figure>  <div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>and</code>与<code>or</code></span></div>    <div class="hide-content"><p><code>and</code>和<code>or</code>执行布尔逻辑运算，但是在python中返回值并非<code>True</code>或<code>False</code>，其返回的是两端的比较值之一</p><p>运算规则：</p>   <ul><li> <code>and</code>运算规则<br>       <ol><li> 当<code>and</code>左端表达式为真时，继续对右端表达式进行计算并返回该(右端)表达式的值</li>       <li>当<code>and</code>左端表达式为假时，立即返回该(左端)表达式的值</li></ol>     </li>     <li> <code>or</code>运算规则<br>       <ol><li> 当<code>or</code>左端表达式为假时，继续对右端表达式进行计算并返回该(右端)表达式的值</li>       <li> 当<code>or</code>左端表达式为真时，立即返回该(左端)表达式的值</li>       </ol>     </li>  </ul><p>两规则的第二条体现了<code>and</code>和<code>or</code>的截断作用（其右端表达式可能并没有被计算），因此<code>and</code>和<code>or</code>又被称为“短路运算符”（再次注意只有在<code>and</code>左边为假或者<code>or</code>左边为真才会表现出该特性）</p>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(<span class="number">0</span> <span class="keyword">and</span> (<span class="number">3</span>-<span class="number">2</span>)) <span class="comment">#0</span></span><br><span class="line"><span class="built_in">print</span>(<span class="number">1</span> <span class="keyword">or</span> <span class="number">0</span>) <span class="comment">#1</span></span><br></pre></td></tr></table></figure><p>简单使用：</p>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#（一）and和or单独使用（多个and或者多个or）</span></span><br><span class="line"><span class="comment">#and：从左到右扫描，返回第一个为假的表达式值，无假值则返回最后一个表达式值。简单说就是：and返回真，除非遇见一个假，则返回假</span></span><br><span class="line"><span class="built_in">print</span>(-<span class="number">1</span> <span class="keyword">and</span> <span class="string">&#x27;dy&#x27;</span> <span class="keyword">and</span> ...) <span class="comment">#注意负数、字符串都是逻辑为真，而...其实是一个Ellipse对象（该对象没有任何属性，python也没有任何内置类型使用该对象），其逻辑为真</span></span><br><span class="line"><span class="built_in">print</span>(<span class="literal">True</span> <span class="keyword">if</span> -<span class="number">1</span> <span class="keyword">and</span> <span class="string">&#x27;dy&#x27;</span> <span class="keyword">and</span> ... <span class="keyword">else</span> <span class="literal">False</span>) <span class="comment">#建议使用all([-1,&#x27;dy&#x27;,...])替代</span></span><br><span class="line"><span class="comment">#or：从左到右扫描，返回第一个为真的表达式值，无真值则返回最后一个表达式值。简单说就是：or返回假，除非遇见一个真，则返回真</span></span><br><span class="line"><span class="built_in">print</span>(<span class="number">0</span> <span class="keyword">or</span> <span class="number">0</span> <span class="keyword">or</span> <span class="number">1</span> <span class="keyword">or</span> <span class="number">2</span> <span class="keyword">or</span> <span class="number">0</span>) <span class="comment">#1</span></span><br><span class="line"><span class="built_in">print</span>(<span class="literal">True</span> <span class="keyword">if</span> <span class="number">0</span> <span class="keyword">or</span> <span class="number">0</span> <span class="keyword">or</span> <span class="number">1</span> <span class="keyword">or</span> <span class="number">2</span> <span class="keyword">or</span> <span class="number">0</span> <span class="keyword">else</span> <span class="literal">False</span>) <span class="comment">#建议使用any([0,0,1,2,0])替代</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#（二）and-or搭配使用</span></span><br><span class="line"><span class="comment">#and优先级大于or，结合性从左到右</span></span><br><span class="line"><span class="comment">#经典案例之逻辑表达式(condition and a or b)：</span></span><br><span class="line">a,b=<span class="string">&quot;JAVA&quot;</span>,<span class="string">&quot;PYTHON&quot;</span></span><br><span class="line"><span class="built_in">print</span>(<span class="number">1</span> <span class="keyword">and</span> a <span class="keyword">or</span> b) <span class="comment">#JAVA</span></span><br><span class="line"><span class="built_in">print</span>(<span class="number">0</span> <span class="keyword">and</span> a <span class="keyword">or</span> b) <span class="comment">#PYTHON</span></span><br><span class="line"><span class="comment">#我们可以通过控制condition的真假，控制输出a还是输出b。语义即为：“若 真 则返回 a，否则返回 b”，等同于C++中的条件运算符(bool? a:b)，但是必须注意：a和b都必须是逻辑真的</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="number">1</span> <span class="keyword">and</span> <span class="number">0</span> <span class="keyword">or</span> a <span class="keyword">and</span> b <span class="keyword">and</span> <span class="number">0</span> <span class="keyword">and</span> a <span class="keyword">or</span> b) <span class="comment">#b</span></span><br><span class="line"><span class="comment">#对于一个比较复杂的and-or混合运算，将and视为乘、or视为加：((1 and 0) or (((a and b) and 0) and a)) or b</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#由于(condition and a or b)中a和b都要满足逻辑真，这如何确保？先看个反例：</span></span><br><span class="line">a,b=[],<span class="number">1</span> <span class="comment">#a是逻辑假的，此时and-or实现的条件运算将失效</span></span><br><span class="line"><span class="built_in">print</span>(<span class="literal">True</span> <span class="keyword">and</span> a <span class="keyword">or</span> b) <span class="comment">#1</span></span><br><span class="line"><span class="built_in">print</span>(<span class="literal">False</span> <span class="keyword">and</span> a <span class="keyword">or</span> b) <span class="comment">#1</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#还是有安全的解法的，如下（套个[]强制变成逻辑真，新的逻辑表达式变为(condition and [a] or [b])[0]）：</span></span><br><span class="line">a=<span class="string">&#x27;&#x27;</span></span><br><span class="line">b=<span class="string">&quot;MSY&quot;</span></span><br><span class="line"><span class="built_in">print</span>((<span class="number">0</span> <span class="keyword">and</span> [a] <span class="keyword">or</span> [b])[<span class="number">0</span>])</span><br><span class="line"></span><br><span class="line"><span class="comment">#通常情况下，还是建议if-else实现条件运算符的功能，以增强程序的可读性，装B除外</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;daiyang&#x27;</span> <span class="keyword">if</span> <span class="literal">False</span> <span class="keyword">else</span> <span class="string">&#x27;daixiaodong&#x27;</span>) <span class="comment">#daixiaodong</span></span><br></pre></td></tr></table></figure>  <!--对于a and b or c and d，假设a, b, c, d = True, True, False, True，and优先级大于or的情况下，应当返回True，若优先级相同，则应返回False--><p><i class="fas fa-hand-point-right"></i>上述小结（可跳过代码）：</p>  <p class='div-border green'>and-or实现条件运算：<code>(condition and [a] or [b])[0]</code>等同于<code>condition ? a : b</code></p>  <p class='div-border yellow'><code>all([condition1,condition2,...])</code>等同于<code>True if condition1 and condition2 and ... else False</code></p>  <p class='div-border blue'>  <code>any([condition1,condition2,...])</code>等同于<code>True if condition1 or condition2 or ... else False</code></p>  <br>  <div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>全部逻辑运算</span></div>    <div class="hide-content">  <div class="dytable"><table><thead><tr><th style="text-align:center">运算</th><th style="text-align:center">名称</th><th style="text-align:center">逻辑函数表示</th><th style="text-align:center">短释</th><th style="text-align:center">实现</th></tr></thead><tbody><tr><td style="text-align:center">A <strong>AND</strong> B</td><td style="text-align:center"><small>与门</small></td><td style="text-align:center">A·B</td><td style="text-align:center"><small>所有输入为高时，才有高的输出，一低出低</small></td><td style="text-align:center"><small>A and B</small></td></tr><tr><td style="text-align:center">A <strong>OR</strong> B</td><td style="text-align:center"><small>或门</small></td><td style="text-align:center">A+B</td><td style="text-align:center"><small>所有输入为低时，才有低的输出，一高出高</small></td><td style="text-align:center"><small>A or B</small></td></tr><tr><td style="text-align:center"><strong>NOT</strong> A</td><td style="text-align:center"><small>非门</small></td><td style="text-align:center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi>A</mi><mo>ˉ</mo></mover></mrow><annotation encoding="application/x-tex">\bar{A}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8201099999999999em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8201099999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">A</span></span></span><span style="top:-3.25233em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.11110999999999999em;"><span class="mord">ˉ</span></span></span></span></span></span></span></span></span></span></td><td style="text-align:center"><small>根据输入的高低逆转后输出</small></td><td style="text-align:center"><small>not A</small></td></tr><tr><td style="text-align:center">A <strong>NAND</strong> B</td><td style="text-align:center"><small>与非门</small></td><td style="text-align:center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mrow><mi>A</mi><mo separator="true">⋅</mo><mi>B</mi></mrow><mo stretchy="true">‾</mo></mover></mrow><annotation encoding="application/x-tex">\overline{A·B}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8833300000000001em;vertical-align:0em;"></span><span class="mord overline"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8833300000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="mpunct">⋅</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span><span style="top:-3.80333em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span></span></span></span></span></span></span></td><td style="text-align:center"><small>所有输入为高时，才有低的输出，一低出高</small></td><td style="text-align:center"><small>not (A and B)</small></td></tr><tr><td style="text-align:center">A <strong>NOR</strong> B</td><td style="text-align:center"><small>或非门</small></td><td style="text-align:center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mrow><mi>A</mi><mo>+</mo><mi>B</mi></mrow><mo stretchy="true">‾</mo></mover></mrow><annotation encoding="application/x-tex">\overline {A+B}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9666600000000001em;vertical-align:-0.08333em;"></span><span class="mord overline"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8833300000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span><span style="top:-3.80333em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.08333em;"><span></span></span></span></span></span></span></span></span></td><td style="text-align:center"><small>所有输入为低时，才有高的输出，一高出低</small></td><td style="text-align:center"><small>not (A or B)</small></td></tr><tr><td style="text-align:center">A <strong>XOR</strong> B</td><td style="text-align:center"><small>异或门</small></td><td style="text-align:center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>A</mi><mo>⊕</mo><mi>B</mi></mrow><annotation encoding="application/x-tex">A\oplus B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊕</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span></td><td style="text-align:center"><small>输入为一高一低时，才有高的输出，否则出低</small></td><td style="text-align:center"><small>(A and not B) or (not A and B)</small></td></tr><tr><td style="text-align:center">A <strong>XNOR</strong> B</td><td style="text-align:center"><small>同或门</small></td><td style="text-align:center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mrow><mi>A</mi><mo>⊕</mo><mi>B</mi></mrow><mo stretchy="true">‾</mo></mover></mrow><annotation encoding="application/x-tex">\overline {A\oplus B}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9666600000000001em;vertical-align:-0.08333em;"></span><span class="mord overline"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8833300000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊕</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span><span style="top:-3.80333em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.08333em;"><span></span></span></span></span></span></span></span></span></td><td style="text-align:center"><small>输入为一高一低时，才有低的输出，否则出高</small></td><td style="text-align:center"><small>(A and B) or (not A and not B)</small></td></tr><tr><td style="text-align:center"><strong>BUF</strong> A</td><td style="text-align:center"><small>是门</small></td><td style="text-align:center">A</td><td style="text-align:center"><small>输出与输入相同的高低状态</small></td><td style="text-align:center"><small>A</small></td></tr><tr><td style="text-align:center">A <strong>IMPLY</strong> B</td><td style="text-align:center"><small>蕴含门</small></td><td style="text-align:center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>A</mi><mo>→</mo><mi>B</mi></mrow><annotation encoding="application/x-tex">A\rightarrow B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">→</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span></td><td style="text-align:center"><small>第一输入为低时输出高，否则输出同第二输入</small></td><td style="text-align:center"><small>(not A) or B</small></td></tr><tr><td style="text-align:center">A <strong>NIMPLY</strong> B</td><td style="text-align:center"><small>蕴含非门</small></td><td style="text-align:center"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mrow><mi>A</mi><mo>→</mo><mi>B</mi></mrow><mo stretchy="true">‾</mo></mover></mrow><annotation encoding="application/x-tex">\overline {A\rightarrow B}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8833300000000001em;vertical-align:0em;"></span><span class="mord overline"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8833300000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">→</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span><span style="top:-3.80333em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span></span></span></span></span></span></span></td><td style="text-align:center"><small>第一输入为低时输出低，否则输出与第二输入相反</small></td><td style="text-align:center"><small>A and (not B)</small></td></tr></tbody></table>  </div><p>注1，表中的A、B均为二值型数据，要么是0，要么是1。最后一列是python代码实现，但不仅适用于二值0和1或布尔值<code>True</code>or<code>False</code>，且适用于其他任何自定义对象，只要实现<code>__bool__()</code>方法即可</p><p>注2，上表中除了前三个门是基础外，其他门都可以用这三个门实现，譬如：“异或门”<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>A</mi><mo>⊕</mo><mi>B</mi><mo>=</mo><mi>A</mi><mo separator="true">⋅</mo><mover accent="true"><mi>B</mi><mo stretchy="true">‾</mo></mover><mo>+</mo><mover accent="true"><mi>A</mi><mo stretchy="true">‾</mo></mover><mo separator="true">⋅</mo><mi>B</mi></mrow><annotation encoding="application/x-tex">A\oplus B=A·\overline B+\overline A·B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊕</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.9666600000000001em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">A</span><span class="mpunct">⋅</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord overline"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8833300000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span><span style="top:-3.80333em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8833300000000001em;vertical-align:0em;"></span><span class="mord overline"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8833300000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal">A</span></span><span style="top:-3.80333em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span></span></span></span><span class="mpunct">⋅</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span>、“同或门”<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mrow><mi>A</mi><mo>⊕</mo><mi>B</mi></mrow><mo stretchy="true">‾</mo></mover><mo>=</mo><mi>A</mi><mo separator="true">⋅</mo><mi>B</mi><mo>+</mo><mover accent="true"><mi>A</mi><mo stretchy="true">‾</mo></mover><mo separator="true">⋅</mo><mover accent="true"><mi>B</mi><mo stretchy="true">‾</mo></mover></mrow><annotation encoding="application/x-tex">\overline {A\oplus B}=A·B+\overline A·\overline B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9666600000000001em;vertical-align:-0.08333em;"></span><span class="mord overline"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8833300000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊕</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span><span style="top:-3.80333em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.08333em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">A</span><span class="mpunct">⋅</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8833300000000001em;vertical-align:0em;"></span><span class="mord overline"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8833300000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal">A</span></span><span style="top:-3.80333em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span></span></span></span><span class="mpunct">⋅</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord overline"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8833300000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span><span style="top:-3.80333em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span></span></span></span></span></span></span>、“蕴含门”<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>A</mi><mo>→</mo><mi>B</mi><mo>=</mo><mover accent="true"><mi>A</mi><mo stretchy="true">‾</mo></mover><mo>+</mo><mi>B</mi></mrow><annotation encoding="application/x-tex">A\rightarrow B=\overline A+B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">→</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.9666600000000001em;vertical-align:-0.08333em;"></span><span class="mord overline"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8833300000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal">A</span></span><span style="top:-3.80333em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span>、“蕴含非门”<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mrow><mi>A</mi><mo>→</mo><mi>B</mi></mrow><mo stretchy="true">‾</mo></mover><mo>=</mo><mi>A</mi><mo separator="true">⋅</mo><mover accent="true"><mi>B</mi><mo stretchy="true">‾</mo></mover></mrow><annotation encoding="application/x-tex">\overline {A\rightarrow B}=A·\overline B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8833300000000001em;vertical-align:0em;"></span><span class="mord overline"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8833300000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">→</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span><span style="top:-3.80333em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8833300000000001em;vertical-align:0em;"></span><span class="mord mathnormal">A</span><span class="mpunct">⋅</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord overline"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8833300000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span><span style="top:-3.80333em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span></span></span></span></span></span></span>。记忆：“与非门”是对“与门”输出取反，“或非门”是对“或门”输出取反，“同或门”是对“异或门”输出取反，“蕴含非门”是对“蕴含门”输出取反</p></div></div></div></div><p>在某些语言如C中可以使用尾递归解决递归爆栈问题，虽然python本身不支持尾递归，但是存在一些解决方案可以间接实现尾递归，下面我先给出尾递归形式的写法：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">fib5</span>(<span class="params">n</span>): <span class="comment">#计算原理同下面循环版本的fib4</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">fib_iter</span>(<span class="params">n,n1,n2</span>):</span><br><span class="line">        <span class="keyword">if</span> n==<span class="number">0</span>: <span class="keyword">return</span> n2</span><br><span class="line">        <span class="keyword">else</span>: <span class="keyword">return</span> fib_iter(n-<span class="number">1</span>,n2,n1+n2)</span><br><span class="line">    <span class="keyword">return</span> fib_iter(n,<span class="number">1</span>,<span class="number">0</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">#lambda形式的尾递归</span></span><br><span class="line">fib6=<span class="keyword">lambda</span> n,n1=<span class="number">1</span>,n2=<span class="number">0</span>:n2 <span class="keyword">if</span> n==<span class="number">0</span> <span class="keyword">else</span> fib6(n-<span class="number">1</span>,n2,n1+n2) <span class="comment">#同fib5</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#and-or形式的尾递归</span></span><br><span class="line">fib7=<span class="keyword">lambda</span> n,n1=<span class="number">1</span>,n2=<span class="number">0</span>:n==<span class="number">0</span> <span class="keyword">and</span> n2 <span class="keyword">or</span> fib7(n-<span class="number">1</span>,n2,n1+n2) <span class="comment">#同fib6</span></span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>python实现尾递归</span></div>    <div class="hide-content"><p>在计算机中，函数调用是通过“栈”这种数据结构实现的，每调用一个函数，就会往栈中压入一个栈帧对象，其中保存着函数所对应的可执行代码（即代码对象，通常由<code>compile()</code>函数返回，可通过栈帧对象<code>frame</code>的<code>f_code</code>属性访问）、变量命名空间（包含<code>frame.f_locals</code>局部变量、<code>frame.f_globals</code>全局变量和<code>frame.f_builtins</code>内置名称）以及其他一些属性（如<code>frame.f_back</code>，表示对当前调用者而言的上一个栈帧对象），当函数执行结束，就会从栈中删除当前栈帧，如果函数没有结束就又发生了其他函数调用，栈中的帧数就会线性增加，由于栈的大小不是无限的，对于递归函数，如果递归过深，很容易导致栈溢出错误</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">import</span> sys</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>sys.getrecursionlimit <span class="comment">#python允许的最大递归深度</span></span><br><span class="line"><span class="number">1000</span></span><br></pre></td></tr></table></figure><p>那么旧的栈帧能不能删除呢？一般来说递归调用的返回结果是要为上层函数所使用的，即递归的回溯过程通常不可避免，所以不能删除。尽管如此，由于尾递归的特殊性（尾调用由于是函数执行流的最后一步，调用结果不需要反馈给调用者，因此在这种情况下旧的栈帧可以直接销毁，此即为“尾调用优化”），决定了这种递归形式在执行过程中是不需要回溯的，于是可以把原本需要线性复杂度栈内存空间的执行过程用常数复杂度的空间完成，实现该优化的解释器或编译器可以使得递归本身无论调用多少次，都只占用一个栈帧。本质上尾递归和循环没什么区别，要效率，还是建议循环</p><p>大佬实现的<a href="https://code.activestate.com/recipes/474088-tail-call-optimization-decorator/"><span class="inline-tag yellow">TCO(Tail-Call Optimization)</span></a>装饰器（原理简单来说就是当发现尾递归调用的函数在栈帧中重复出现时，手动抛出异常并携带着最新调用的函数参数返回上层，从而使之后重复调用的函数栈帧被销毁）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">TailRecurseException</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, args, kwargs</span>):</span><br><span class="line">        self.args = args</span><br><span class="line">        self.kwargs = kwargs</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">tail_call_optimized</span>(<span class="params">g</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">    This function decorates a function with tail call</span></span><br><span class="line"><span class="string">    optimization. It does this by throwing an exception</span></span><br><span class="line"><span class="string">    if it is it&#x27;s own grandparent, and catching such</span></span><br><span class="line"><span class="string">    exceptions to fake the tail call optimization.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    This function fails if the decorated</span></span><br><span class="line"><span class="string">    function recurses in a non-tail context.</span></span><br><span class="line"><span class="string">    &quot;&quot;&quot;</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">func</span>(<span class="params">*args, **kwargs</span>):</span><br><span class="line">        f = sys._getframe()</span><br><span class="line">        <span class="keyword">if</span> f.f_back <span class="keyword">and</span> f.f_back.f_back \</span><br><span class="line">            <span class="keyword">and</span> f.f_back.f_back.f_code == f.f_code: <span class="comment">#位置1</span></span><br><span class="line">            <span class="keyword">raise</span> TailRecurseException(args, kwargs)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">while</span> <span class="number">1</span>:</span><br><span class="line">                <span class="keyword">try</span>:</span><br><span class="line">                    <span class="keyword">return</span> g(*args, **kwargs) <span class="comment">#位置2</span></span><br><span class="line">                <span class="keyword">except</span> TailRecurseException <span class="keyword">as</span> e:</span><br><span class="line">                    args = e.args</span><br><span class="line">                    kwargs = e.kwargs</span><br><span class="line">    func.__doc__ = g.__doc__</span><br><span class="line">    <span class="keyword">return</span> func</span><br></pre></td></tr></table></figure><p>使用案例（尾递归实现的阶乘计算）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@tail_call_optimized</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">factorial</span>(<span class="params">n, acc=<span class="number">1</span></span>):</span><br><span class="line">    <span class="string">&quot;calculate a factorial&quot;</span> <span class="comment">#函数__doc__文档</span></span><br><span class="line">    <span class="keyword">if</span> n == <span class="number">0</span>:</span><br><span class="line">        <span class="keyword">return</span> acc</span><br><span class="line">    <span class="keyword">return</span> factorial(n-<span class="number">1</span>, n*acc) <span class="comment">#位置3</span></span><br><span class="line">    </span><br><span class="line"><span class="built_in">print</span>(factorial(<span class="number">1000</span>))</span><br></pre></td></tr></table></figure><p>解读：首先得知道装饰器的基本原理，于是有<code>factorial=tail_call_optimized(factorial)</code>，即变量名<code>factorial</code>实际指向闭包函数<code>func</code>，而<code>func</code>闭包内部的变量<code>g</code>实际指向函数<code>factorial</code>。在执行<code>factorial(1000)</code>时，由函数<code>func</code>构成的栈帧将首次被压入函数调用栈中，程序执行到位置1，不符合<code>if</code>条件，于是执行到位置2，再一次发生函数调用，此时由函数<code>factorial</code>构成的栈帧将被压入栈中，程序继而执行到位置3并函数调用，于是由函数<code>func</code>构成的栈帧将再次被压入栈中，然后执行到位置1发现满足条件（当前栈帧的前两个栈帧存在且上上个栈帧的代码对象和当前栈帧的代码对象相同，即发生重复调用），于是向上层抛出异常（具体返回到哪一层就看哪一层捕捉到了该异常），同时携带着最新的调用参数，显然程序将返回到第一个栈帧（即第一个函数调用）的位置2处（此时栈内就只有这一个帧了），此处异常被捕捉，由于处在一个<code>while</code>循环中，于是又来到位置2并发生函数调用，函数<code>factorial</code>构成的栈帧将被压入栈中，来到位置3并发生函数调用，函数<code>func</code>构成的栈帧将被压入栈中，判断<code>if</code>条件，再次满足条件，抛出异常…，依此类推</p><p>之前的斐波那契问题，使用TCO修饰：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">fib5</span>(<span class="params">n</span>):</span><br><span class="line"><span class="meta">    @tail_call_optimized</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">fib_iter</span>(<span class="params">n,n1,n2</span>):</span><br><span class="line">        <span class="keyword">if</span> n==<span class="number">0</span>: <span class="keyword">return</span> n2</span><br><span class="line">        <span class="keyword">else</span>: <span class="keyword">return</span> fib_iter(n-<span class="number">1</span>,n2,n1+n2)</span><br><span class="line">    <span class="keyword">return</span> fib_iter(n,<span class="number">1</span>,<span class="number">0</span>)</span><br></pre></td></tr></table></figure><p>注意，TCO只能用于尾递归，否则出错，示例如下：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@tail_call_optimized</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">n=<span class="number">6</span></span>): <span class="comment">#此递归函数功能：每深入调用一次递归函数，计数器增1，即函数返回递归的深度</span></span><br><span class="line">    <span class="keyword">if</span> n==<span class="number">0</span>:</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>+f(n-<span class="number">1</span>)</span><br><span class="line">    </span><br><span class="line"><span class="built_in">print</span>(f()) <span class="comment">#0 #去掉TCO时返回6</span></span><br></pre></td></tr></table></figure></div></div><p>最正确且效率最高的当属循环：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#能用循环解决的问题，尽量不要使用递归，有时候递归可以极大简化问题，那也应当在合理的递归深度范围内，否则意味着错误必将发生</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fib4</span>(<span class="params">n</span>):</span><br><span class="line">    n1,n2=<span class="number">1</span>,<span class="number">0</span></span><br><span class="line">    <span class="keyword">while</span> n:</span><br><span class="line">        n1,n2,n=n2,n1+n2,n-<span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> n2</span><br><span class="line">  </span><br><span class="line"><span class="built_in">print</span>(fib4(<span class="number">10000</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment">#顺便给出打印完整数列的方法，稍微改造上述fib函数即可</span></span><br><span class="line"><span class="keyword">from</span> itertools <span class="keyword">import</span> count</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">all_fib</span>(<span class="params">n</span>):</span><br><span class="line">    n1,n2=<span class="number">0</span>,<span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> count():</span><br><span class="line">        <span class="keyword">if</span> i==n:<span class="keyword">break</span></span><br><span class="line">        <span class="built_in">print</span>(n2,end=<span class="string">&#x27;,&#x27;</span>)</span><br><span class="line">        n1,n2=n2,n1+n2</span><br><span class="line"></span><br><span class="line">all_fib(<span class="number">6</span>) <span class="comment">#1,1,2,3,5,8,13,21,34,55</span></span><br></pre></td></tr></table></figure></div></div></div></div><p>案例4（增量求平均）：<br>记<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><msub><mi>x</mi><mi>n</mi></msub><mo stretchy="true">‾</mo></mover></mrow><annotation encoding="application/x-tex">\overline{x_n}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.78056em;vertical-align:-0.15em;"></span><span class="mord overline"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.63056em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.55056em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span>为序列<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">{</mo><msub><mi>x</mi><mn>1</mn></msub><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msub><mi>x</mi><mi>n</mi></msub><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">\{x_1, ..., x_n\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">}</span></span></span></span>的均值，由<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><msub><mi>x</mi><mi>n</mi></msub><mo stretchy="true">‾</mo></mover><mo>−</mo><mover accent="true"><msub><mi>x</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo stretchy="true">‾</mo></mover><mo>=</mo><mfrac><mrow><msub><mi>x</mi><mn>1</mn></msub><mo>+</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo>+</mo><msub><mi>x</mi><mi>n</mi></msub></mrow><mi>n</mi></mfrac><mo>−</mo><mover accent="true"><msub><mi>x</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo stretchy="true">‾</mo></mover><mo>=</mo><mfrac><mrow><mover accent="true"><msub><mi>x</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo stretchy="true">‾</mo></mover><mo stretchy="false">(</mo><mi>n</mi><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo><mo>+</mo><msub><mi>x</mi><mi>n</mi></msub></mrow><mi>n</mi></mfrac><mo>−</mo><mover accent="true"><msub><mi>x</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo stretchy="true">‾</mo></mover><mo>=</mo><mfrac><mrow><msub><mi>x</mi><mi>n</mi></msub><mo>−</mo><mover accent="true"><msub><mi>x</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo stretchy="true">‾</mo></mover></mrow><mi>n</mi></mfrac></mrow><annotation encoding="application/x-tex">\overline{x_n}-\overline{x_{n-1}} = \frac{x_1+...+x_n}{n} - \overline{x_{n-1}} = \frac{\overline{x_{n-1}}(n-1)+x_n}{n} - \overline{x_{n-1}} = \frac{x_n - \overline{x_{n-1}}}{n}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.78056em;vertical-align:-0.15em;"></span><span class="mord overline"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.63056em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.55056em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.838891em;vertical-align:-0.208331em;"></span><span class="mord overline"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.63056em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.55056em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.1634309999999999em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8184309999999999em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.4101em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mbin mtight">+</span><span class="mord mtight">.</span><span class="mord mtight">.</span><span class="mord mtight">.</span><span class="mbin mtight">+</span><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285719em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.838891em;vertical-align:-0.208331em;"></span><span class="mord overline"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.63056em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.55056em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.355em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.01em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.485em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord overline mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.6755600000000002em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3173142857142857em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.20252142857142857em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.57756em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line mtight" style="border-bottom-width:0.049em;"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.20252142857142857em;"><span></span></span></span></span></span><span class="mopen mtight">(</span><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span><span class="mclose mtight">)</span><span class="mbin mtight">+</span><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285719em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.838891em;vertical-align:-0.208331em;"></span><span class="mord overline"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.63056em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.55056em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.269657em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9246570000000001em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.451765em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285719em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord overline mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.6755600000000002em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3173142857142857em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.20252142857142857em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.57756em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line mtight" style="border-bottom-width:0.049em;"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.20252142857142857em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>，则<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><msub><mi>x</mi><mi>n</mi></msub><mo stretchy="true">‾</mo></mover><mo>=</mo><mover accent="true"><msub><mi>x</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo stretchy="true">‾</mo></mover><mo>+</mo><mfrac><mrow><msub><mi>x</mi><mi>n</mi></msub><mo>−</mo><mover accent="true"><msub><mi>x</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo stretchy="true">‾</mo></mover></mrow><mi>n</mi></mfrac></mrow><annotation encoding="application/x-tex">\overline{x_n}=\overline{x_{n-1}} + \frac{x_n - \overline{x_{n-1}}}{n}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.78056em;vertical-align:-0.15em;"></span><span class="mord overline"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.63056em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.55056em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.838891em;vertical-align:-0.208331em;"></span><span class="mord overline"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.63056em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.55056em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.269657em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9246570000000001em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.451765em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285719em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord overline mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.6755600000000002em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3173142857142857em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.20252142857142857em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.57756em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line mtight" style="border-bottom-width:0.049em;"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.20252142857142857em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>，于是有：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>avg = <span class="keyword">lambda</span> arr : reduce(<span class="keyword">lambda</span> avg_num, xn : (avg_num[<span class="number">0</span>] + (xn - avg_num[<span class="number">0</span>])/(avg_num[<span class="number">1</span>] + <span class="number">1</span>), avg_num[<span class="number">1</span>] + <span class="number">1</span>), arr, (<span class="number">0</span>,<span class="number">0</span>))[<span class="number">0</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>avg([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>])</span><br><span class="line"><span class="number">2.5</span></span><br></pre></td></tr></table></figure></li></ul><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="dytab1-4"><div class="tabs" id="dytab1-2"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#dytab1-2-1">字典</button></li><li class="tab"><button type="button" data-href="#dytab1-2-2">集合</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="dytab1-2-1"><p>字典又名哈希表、散列表，实现一个哈希表需要讨论两大基本问题：地址映射和冲突处理</p><ol><li><p>地址映射<br>一个好的<code>hash</code>方法是在对象不相同的情况下能产生不相等的哈希值，这是最理想的情况，退而求次，<code>hash</code>方法应尽力将数据集合中不相同的对象均匀分布到所有可能的地址上面，即通过哈希函数应能得到一个“尽可能随机的地址”</p></li><li><p>冲突处理<br>如果两个不同对象映射到了相同的地址，将产生冲突，无论怎样精心构造<code>hash</code>函数，这种冲突都不可避免，但是可以解决，如开放定址（探测再散列）、再哈希、链式、公共溢出区，其中链表法是比较常见的冲突处理办法，python采用开放定址办法</p></li></ol><p>因此当我们对字典成员对象进行操作时，需要能够计算对象的哈希并比较对象之间的异同，特别是用户自定义类型，需要用户自己实现。先说说几个特殊方法（也叫“魔法方法”，以双下划线开头且以双下划线结尾，这些方法会在进行特定操作时被自动调用，譬如运算符重载方法，如上面提到过的对象比较<code>==</code>相当于调用对象的<code>__eq__()</code>方法、加法<code>+</code>相当于调用对象的<code>__add__()</code>方法等）：</p><ul><li> <code>object.__hash__(self)</code><br>  <p>注：这是<code>object</code>基类所定义的哈希方法签名，下同</p>  <p><code>__hash__()</code>会在以下情况被调用：1）由内置方法<code>hash()</code>调用（<code>hash(obj)</code>即等同于<code>obj.__hash__()</code>），2）对散列集合成员进行操作时被调用，散列集合类型包括<code>dict</code>、<code>set</code>和<code>frozenset</code>。注意<code>__hash__()</code>应当返回一个整数，对于用户自定义类型，我们建议将对象的不同组件打包进元组，然后计算元组的哈希值，譬如：</p>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">__hash__</span>(<span class="params">self</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">hash</span>((self.name, self.sex, self.age))</span><br></pre></td></tr></table></figure>  </li><li> <code>object.__getattribute__(self, name)</code><br>  <p>实例属性访问时始终会调用<code>__getattribute__()</code>方法（类属性访问则不会调用之，很明显一个道理，<code>__getattribute__()</code>是实例方法嘛，怎么可能会调用它，当类属性不存在时也将触发<code>AttributeError</code>异常，而这就更不太可能触发调用<code>__getattr__()</code>了），如果还定义了<code>__getattr__()</code>，则除非<code>__getattribute__()</code>显式调用它或者其中引发了<code>AttributeError</code>异常（属性不存在的默认行为），否则不会调用后者。为了防止在此方法中陷入无穷递归，其实现应始终调用具有相同名称的基类方法来访问其所需的任何属性，如<code>object.__getattribute__(self, name)</code>（之所以要传入当前实例<code>self</code>，是因为在类上访问实例方法返回的是“非绑定方法”（即原始函数对象），而在实例上访问方法返回的则是“绑定方法”，所谓绑定，即绑定实例，实例方法访问返回的其实是一个闭包对象，譬如<code>x.method</code>返回的相当于<code>partial(method,self=x)</code>），不过一般还是使用<code>super().method(arg)</code>实现基类方法调用。下面的错误示例将导致无限递归（但受最大递归层数限制）：</p>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,name</span>):</span><br><span class="line">        self.name=name</span><br><span class="line">      </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__getattribute__</span>(<span class="params">self,item</span>):</span><br><span class="line">        <span class="keyword">return</span> self.__dict__[item] <span class="comment">#__dict__中存放着对象上绑定着的实例属性，若你想从中取值，self.__dict__又将调用self.__getattribute__()方法，从而陷入无穷递归</span></span><br><span class="line">      </span><br><span class="line"><span class="built_in">print</span>(A(<span class="string">&#x27;a&#x27;</span>).name) <span class="comment">#RecursionError: maximum recursion depth exceeded while calling a Python object</span></span><br></pre></td></tr></table></figure>  修改：  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">__getattribute__</span>(<span class="params">self,item</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">super</span>(A,self).__getattribute__(item) <span class="comment">#在python3中也可以简写为super()，完全等同于super(A,self)</span></span><br></pre></td></tr></table></figure>  <div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>遇到的问题</span></div>    <div class="hide-content"><p>我写了下面的代码，但是对输出感到困惑：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,name</span>):</span><br><span class="line">        self.name=name</span><br><span class="line">      </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__getattribute__</span>(<span class="params">self,item</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;属性访问:&#x27;</span>,item)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;object的__getattr__方法:&#x27;</span>,<span class="built_in">super</span>(A,self).__getattr__) <span class="comment">#？</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="built_in">super</span>(A,self).__getattr__(item)) <span class="comment">#super到底发生了什么？</span></span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">super</span>(A,self).__getattribute__(item)</span><br><span class="line">      </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__getattr__</span>(<span class="params">self,item</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&#x27;daiyang&#x27;</span></span><br><span class="line">      </span><br><span class="line"><span class="built_in">print</span>(A(<span class="string">&#x27;a&#x27;</span>).name)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">属性访问: name</span></span><br><span class="line"><span class="string">daiyang</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>首先我们来看一下<code>super(…)</code>的原理（仅用于理解，因为<code>super</code>本身是一个类）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">super</span>(<span class="params">cls, inst</span>):</span><br><span class="line">    mro = inst.__class__.mro()</span><br><span class="line">    <span class="keyword">return</span> mro[mro.index(cls) + <span class="number">1</span>]</span><br></pre></td></tr></table></figure><p>MRO（method resolution order）列表记录了类继承体系中的成员解析顺序，每个类都有这样的属性，可以用来解决python中<a href="https://www.cnblogs.com/czaiz/p/7772194.html">钻石继承</a>的难题，核心就在于它将非线性的父类继承顺序通过C3算法转换成线性顺序。因此以后不要再单纯地认为<code>super()</code>返回的就是当前类的父类了，这不一定（单继承不用怀疑，肯定是父类啦，指的是多继承的情况下不一定），也可能是兄弟类（当然了，不管是“父类”还是“兄弟类”都是不严谨的说法，因为返回的是<code>super</code>类实例），看个例子：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Base</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">  <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">      <span class="built_in">print</span>(<span class="string">&quot;enter Base&quot;</span>)</span><br><span class="line">      <span class="built_in">print</span>(<span class="string">&quot;leave Base&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>(<span class="title class_ inherited__">Base</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;enter A&quot;</span>)</span><br><span class="line">        <span class="comment">#print(self.__class__.mro()) #[&lt;class &#x27;__main__.C&#x27;&gt;, &lt;class &#x27;__main__.A&#x27;&gt;, &lt;class &#x27;__main__.B&#x27;&gt;, &lt;class &#x27;__main__.Base&#x27;&gt;, &lt;class &#x27;object&#x27;&gt;]</span></span><br><span class="line">        <span class="built_in">super</span>(A,self).__init__() <span class="comment">#根据MRO列表可知，super(A,self)返回的是类B，注意了，这也是为什么说super()返回的不一定是父类，此处返回的是类A的兄弟B</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;leave A&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">B</span>(<span class="title class_ inherited__">Base</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;enter B&quot;</span>)</span><br><span class="line">        <span class="comment">#print(self.__class__.mro()) #[&lt;class &#x27;__main__.C&#x27;&gt;, &lt;class &#x27;__main__.A&#x27;&gt;, &lt;class &#x27;__main__.B&#x27;&gt;, &lt;class &#x27;__main__.Base&#x27;&gt;, &lt;class &#x27;object&#x27;&gt;]</span></span><br><span class="line">        <span class="built_in">super</span>(B,self).__init__() <span class="comment">#根据MRO列表可知，super(B,self)返回的是类Base</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;leave B&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">C</span>(A,B):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;enter C&quot;</span>)</span><br><span class="line">        <span class="comment">#print(self.__class__.mro()) #[&lt;class &#x27;__main__.C&#x27;&gt;, &lt;class &#x27;__main__.A&#x27;&gt;, &lt;class &#x27;__main__.B&#x27;&gt;, &lt;class &#x27;__main__.Base&#x27;&gt;, &lt;class &#x27;object&#x27;&gt;]</span></span><br><span class="line">        <span class="built_in">super</span>(C,self).__init__() <span class="comment">#根据MRO列表可知，super(C,self)返回的是类A，准确来说返回的是绑定了self实例的super类对象（bound super object），可以通过__self__属性查看绑定的实例，super(C,self).__self__</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;leave C&quot;</span>)</span><br><span class="line"></span><br><span class="line">c=C()</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">enter C</span></span><br><span class="line"><span class="string">enter A</span></span><br><span class="line"><span class="string">enter B</span></span><br><span class="line"><span class="string">enter Base</span></span><br><span class="line"><span class="string">leave Base</span></span><br><span class="line"><span class="string">leave B</span></span><br><span class="line"><span class="string">leave A</span></span><br><span class="line"><span class="string">leave C</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>事实上，<code>super(cls,inst)</code>有两种用法，一是上述所说，参数1是类，参数2是实例，且必须满足<code>isinstance(inst,cls)</code>为<code>True</code>的条件，二是参数2也可以是一个类，此时则必须满足<code>issubclass(inst,cls)</code>为<code>True</code>的条件，两者返回的都是绑定了<code>inst</code>（应该是绑在<code>__self__</code>属性中）的<code>super</code>对象，注意并不是预期的父类哦，如果绑定的<code>inst</code>是实例，那么该<code>super</code>对象可以调用父类的实例方法，如果绑定的<code>inst</code>是类，那么该<code>super</code>对象则可以调用父类的类方法，当然也可以访问父类的其他类属性（包括类中定义的静态方法、非方法属性），如果父类中找不到的话，则会到父类的基类中继续搜寻，如果一直没有找到将抛出<code>AttributeError</code></p><p>回到原题，<code>super(A,self).__getattr__</code>理论上应该返回基类<code>object</code>相应的绑定方法（绑定了类<code>A</code>实例<code>self</code>），问题在于<code>object</code>类并未定义<code>__getattr__()</code>方法啊（参考书[1]出来挨打O(∩_∩)O），当访问一个不存在的属性将引发<code>AttributeError</code>异常，注意这个异常是在类<code>A</code>的<code>__getattribute__()</code>内部引发的，而由于还定义了<code>__getattr__()</code>，因此程序最终输出了字符串<code>daiyang</code>。我们可以捕捉该异常：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,name</span>):</span><br><span class="line">        self.name=name</span><br><span class="line">      </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__getattribute__</span>(<span class="params">self,item</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;属性访问:&#x27;</span>,item)</span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&#x27;object的__getattr__方法:&#x27;</span>,<span class="built_in">super</span>(A,self).__getattr__)</span><br><span class="line">        <span class="keyword">except</span> AttributeError <span class="keyword">as</span> e:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&#x27;异常捕捉:&#x27;</span>,e)</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">super</span>(A,self).__getattribute__(item)</span><br><span class="line">      </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__getattr__</span>(<span class="params">self,item</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&#x27;daiyang&#x27;</span></span><br><span class="line">      </span><br><span class="line"><span class="built_in">print</span>(A(<span class="string">&#x27;a&#x27;</span>).name)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">属性访问: name</span></span><br><span class="line"><span class="string">异常捕捉: &#x27;super&#x27; object has no attribute &#x27;__getattr__&#x27;</span></span><br><span class="line"><span class="string">a</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></div></div>  </li><li> <code>object.__getitem__(self,key)</code><br>执行<code>self[key]</code>时被调用，对于序列类型，接受的键应该是整数和切片对象，请注意，负索引的特殊解释（如果类希望模拟序列类型）取决于<code>__getitem__()</code>方法，如果key是不合适的类型，则可能引发<code>TypeError</code>，如果是序列的索引集合之外的值，则应引发<code>IndexError</code>，对于映射类型，如果缺少键（不在容器中），则应引发<code>KeyError</code></li><li><code>object.__setitem__(self,key,value)</code><br>执行<code>self[key]=value</code>时被调用</li></ul><p>一般我们使用内置的标准字典或集合，甚至不需要子类化进行任何定制，即使有其它方面的需求，也有第三方库提供的数据结构供我们使用，譬如<code>defaultdict</code>、<code>OrderedDict</code>。但是自定义成员对象并通过字典等存取时，基本都得重写<code>__hash__()</code>和<code>__eq__()</code>方法，这一点很重要，现假设我们要向集合中存放自定义类对象，如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">man</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,name,sex,age</span>):</span><br><span class="line">        self.name=name</span><br><span class="line">        self.sex=sex</span><br><span class="line">        self.age=age</span><br><span class="line">        </span><br><span class="line">man1=man(<span class="string">&#x27;muggle&#x27;</span>,<span class="string">&#x27;male&#x27;</span>,<span class="number">22</span>)</span><br><span class="line">man2=man(<span class="string">&#x27;muggle&#x27;</span>,<span class="string">&#x27;male&#x27;</span>,<span class="number">22</span>)</span><br><span class="line"><span class="built_in">hash</span>(man1)==<span class="built_in">hash</span>(man2) <span class="comment">#False</span></span><br></pre></td></tr></table></figure><p>如你所见，两个“相同”（只要姓名、性别、年龄都一样，我们就认为两个人是同一人啊）对象的哈希值不一样，将它们存放到字典<code>s=set([man1,man2])</code>中的后果就是，字典<code>s</code>中竟然“有两个一毛一样的人”，这实在是匪夷所思，原因即在于，执行映射类容器相关操作的时候（譬如向字典中添加一个键值对，或查询某键的值），会先后调用键（此处<code>man</code>实例对象就是“键”）对象的<code>__hash__()</code>以及<code>__eq__()</code>，现在我们两个对象<code>man1</code>和<code>man2</code>的哈希值不一样，而且默认的<code>__eq__</code>方法也判断两个对象不相同，尽管哈希值不一样的键也有可能落到同一个“桶”里面，但是现在这两对象也不<code>equal</code>啊，于是这两个对象必然不同且同时存在于集合中，解决的办法就是为<code>man</code>类重写<code>__hash__()</code>和<code>__eq__()</code>（一般修改其中任意一个方法，另一个也要相应修改），它们必须满足以下两大规则：</p><ol><li>如果两个对象相同，即<code>obj1.equal(obj2)==True</code>，则两个对象的哈希地址映射也必须相同，即<code>hash(obj1)==hash(obj2)</code>（否则对象明明存在于容器中，却找不到）</li><li>如果两个对象的哈希地址映射不同，即<code>hash(obj1)!=hash(obj2)</code>，则两个对象必须不相同，即<code>obj1.equal(obj2)==False</code>（否则容器中将存在同一对象的多个“副本”，浪费存储资源）</li></ol><p>修改后的<code>man</code>类已满足上述规则：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">man</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,name,sex,age</span>):</span><br><span class="line">        self.name=name</span><br><span class="line">        self.sex=sex</span><br><span class="line">        self.age=age</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__hash__</span>(<span class="params">self</span>): <span class="comment">#用姓名、性别和年龄判断两个人是否相同，若相同，此时他们的哈希也必然相同，但是相同的哈希也可能对应不同的人，此时就要靠equal方法来判断了</span></span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">hash</span>((self.name, self.sex, self.age))</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__eq__</span>(<span class="params">self,other</span>):</span><br><span class="line">        <span class="keyword">if</span> self.name==other.name <span class="keyword">and</span> self.sex==other.sex <span class="keyword">and</span> self.age==other.age:</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">False</span></span><br></pre></td></tr></table></figure><p>关于<code>__hash__()</code>和<code>__eq__()</code>，官方文档中有非常明确的指示：</p><ol><li><p>如果重写了<code>__eq__()</code>，必须重写<code>__hash__()</code>，因为两个“相同”对象的哈希地址映射不一定相同，为了确保这一点，必须重写<code>__hash__()</code>加以保证。反之，如果重写了<code>__hash__()</code>，也必须重写<code>__eq__()</code>，因为两个哈希地址相同的对象，如果是相同对象，<code>__eq__()</code>也必须相同，否则不同，若两个对象哈希地址不同，则<code>__eq__()</code>必须不同，否则出错</p></li><li><p>如果只重写了<code>__eq__()</code>，那么该类对象将不能用于映射类容器，因为此时<code>__hash__()</code>将隐式地被赋为<code>None</code>，即此时<code>__hash__</code>方法失效，该类实例将不可哈希。如果想使用父类的<code>__hash__()</code>，需要明确说明：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">B</span>(<span class="title class_ inherited__">A</span>):</span><br><span class="line">    __hash__=A.__hash__</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__eq__</span>(<span class="params">self,other</span>):</span><br><span class="line">        <span class="keyword">pass</span></span><br></pre></td></tr></table></figure></li><li><p>如果没有重写<code>__eq__()</code>，又希望使<code>__hash__()</code>失效，应明确赋值为<code>None</code>：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>():</span><br><span class="line">    __hash__=<span class="literal">None</span></span><br><span class="line">        </span><br><span class="line">s=<span class="built_in">set</span>()</span><br><span class="line">s.add(A()) <span class="comment">#TypeError: unhashable type: &#x27;A&#x27;</span></span><br></pre></td></tr></table></figure></li><li><p>如果可变对象的类实现了<code>__eq__()</code>，就不必再为之重写<code>__hash__()</code>了，因为即使你重写了一个看似不会抛异常的<code>__hash__()</code>，但是由于对象可变，它总是会出错（可变对象就不能作为字典或集合的“键”）。举个例子，我们子类化列表，重写<code>__eq__()</code>，规定只要新列表的第一个元素相同，那么两个新列表就相同，同时重写<code>__hash__()</code>，使它返回新列表第一个元素的哈希值，这一设定是合理的，并假设新列表的第一个元素我们总是使它是可哈希的，我们创建一个新列表的实例<code>a=['muggle']</code>，设对象<code>a</code>的哈希地址为<code>addr1</code>，将其添加到集合<code>s</code>中，于是<code>s={['muggle'],}</code>，我们修改<code>a</code>的第一个元素值为<code>'jingjing'</code>，结果就是<code>addr1</code>地址上存放的字符串从<code>muggle</code>变成了<code>jingjing</code>，现在新建一个新列表实例<code>b=['jingjing']</code>，设对象<code>b</code>的哈希地址为<code>addr2</code>，且<code>addr1!=addr2</code>，将<code>b</code>也添加到<code>s</code>中，于是<code>s={['jingjing'],['jingjing'],}</code>，可是根据我们的<code>__eq__</code>和<code>__hash__</code>方法，显然有<code>a==b</code>以及<code>hash(a)==hash(b)</code>成立啊，即这两个对象“完全相同”，而不该在集合中重复出现！代码如下：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">MyArray</span>(<span class="title class_ inherited__">list</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,*args</span>):</span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> args:</span><br><span class="line">            self.append(i)</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">set</span>(<span class="params">self,index,value</span>):</span><br><span class="line">        self[index]=value</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__hash__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">hash</span>(self[<span class="number">0</span>])</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__eq__</span>(<span class="params">self,other</span>):</span><br><span class="line">        <span class="keyword">if</span> self[<span class="number">0</span>]==other[<span class="number">0</span>]:</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line">        </span><br><span class="line">a=MyArray(<span class="string">&#x27;muggle&#x27;</span>)</span><br><span class="line">s=<span class="built_in">set</span>()</span><br><span class="line">s.add(a) <span class="comment">#s=&#123;[&#x27;muggle&#x27;]&#125;</span></span><br><span class="line">a[<span class="number">0</span>]=<span class="string">&#x27;jingjing&#x27;</span> <span class="comment">#&#123;[&#x27;jingjing&#x27;]&#125;</span></span><br><span class="line">b=MyArray(<span class="string">&#x27;jingjing&#x27;</span>)</span><br><span class="line">s.add(b) <span class="comment">#&#123;[&#x27;jingjing&#x27;], [&#x27;jingjing&#x27;]&#125;</span></span><br><span class="line"><span class="built_in">hash</span>(a)==<span class="built_in">hash</span>(b) <span class="comment">#True</span></span><br><span class="line">a==b <span class="comment">#True</span></span><br></pre></td></tr></table></figure></li><li><p>用户自定义类默认的<code>__hash__()</code>和<code>__eq__()</code>继承自基类<code>object</code>，它们都是非常严格的，判断两个实例相不相同是根据唯一身份标识<code>id</code>，哈希也是对身份标识进行哈希</p></li></ol><p>字典的使用和一些注意点：</p><ol><li><p>Python2中判断某个<code>key</code>是否存在字典中可使用<code>has_key()</code>方法，另外一种方式是使用<code>in</code>关键字（<code>key in dict</code>），推荐使用后者，因为<code>in</code>的处理速度更快，另一个原因是<code>has_key()</code>这个方法在Python3被移除了</p></li><li><p>获取字典中某个键的值，两种方式：<code>dict[key]</code>或<code>dict.get(key[, default])</code>，前者简便但如果键不存在会导致<code>KeyError</code>异常，为了避免异常不得不先进行键存在性的判断，或者捕捉异常，如果不想手动捕捉异常那就子类化字典并重新定义字典的<code>__missing__()</code>方法以避免异常的抛出，该特殊方法只有在使用<code>dict[key]</code>且<code>key</code>不存在时才会被调用。一般我们使用<code>dict.get()</code>方法，键不存在则返回<code>None</code>（可通过<code>default</code>参数修改该默认值），但并不会修改底层数据，这不同于<code>defaultdict</code>类或<code>dict.setdefault(key,default)</code>，示例：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">MyDict</span>(<span class="title class_ inherited__">dict</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__missing__</span>(<span class="params">self,key</span>):</span><br><span class="line">        <span class="comment">#self[key]=0 #通常都会这么做，修改底层数据，否则就没有意义了，因为还不如直接通过dict.get(key,default)设置缺省值</span></span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line"></span><br><span class="line">d=MyDict()</span><br><span class="line"><span class="keyword">for</span> k <span class="keyword">in</span> <span class="string">&#x27;11422134431&#x27;</span>: <span class="comment">#计数器</span></span><br><span class="line">    d[k]+=<span class="number">1</span></span><br><span class="line"><span class="built_in">print</span>(d) <span class="comment">#&#123;&#x27;1&#x27;: 4, &#x27;4&#x27;: 3, &#x27;2&#x27;: 2, &#x27;3&#x27;: 2&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#或者：</span></span><br><span class="line">d=<span class="built_in">dict</span>()</span><br><span class="line"><span class="keyword">for</span> k <span class="keyword">in</span> <span class="string">&#x27;11422134431&#x27;</span>:</span><br><span class="line">    d[k]=d.get(k,<span class="number">0</span>)+<span class="number">1</span></span><br><span class="line"><span class="built_in">print</span>(d) <span class="comment">#&#123;&#x27;1&#x27;: 4, &#x27;4&#x27;: 3, &#x27;2&#x27;: 2, &#x27;3&#x27;: 2&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#或者：</span></span><br><span class="line">d=&#123;&#125;</span><br><span class="line"><span class="keyword">for</span> k <span class="keyword">in</span> <span class="string">&#x27;11422134431&#x27;</span>:</span><br><span class="line">    d[k]=d.setdefault(k,<span class="number">0</span>)+<span class="number">1</span> <span class="comment">#setdefault(key,default=None)和get(key,default=None)方法用法类似，区别是，如果键不存在于字典中，将会添加键并将值设为默认值，即会直接修改底层数据。如果字典中包含有给定键，则返回键所对应的值，否则返回为键设置的default值</span></span><br><span class="line"><span class="built_in">print</span>(d) <span class="comment">#&#123;&#x27;1&#x27;: 4, &#x27;4&#x27;: 3, &#x27;2&#x27;: 2, &#x27;3&#x27;: 2&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#或者：</span></span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> defaultdict</span><br><span class="line"></span><br><span class="line">d=defaultdict(<span class="built_in">int</span>) <span class="comment">#defaultdict类的初始化函数接受一个工厂函数作为参数，作用是当key不存在时，返回的是工厂函数的默认值，比如list对应[]，str对应的是空字符串，set对应set()，int对应0</span></span><br><span class="line"><span class="keyword">for</span> k <span class="keyword">in</span> <span class="string">&#x27;11422134431&#x27;</span>:</span><br><span class="line">    d[k]+=<span class="number">1</span></span><br><span class="line"><span class="built_in">print</span>(d) <span class="comment">#defaultdict(&lt;class &#x27;int&#x27;&gt;, &#123;&#x27;1&#x27;: 4, &#x27;4&#x27;: 3, &#x27;2&#x27;: 2, &#x27;3&#x27;: 2&#125;)</span></span><br></pre></td></tr></table></figure></li><li><p>创建字典的几种方式：</p><ul><li><p><code>dict()</code>实例化字典对象（默认无参数时创建一个空字典，也可以直接写<code>d={}</code>），可以传递任意数量的关键字参数，或者是一个二元元组列表以及任意数量的关键字参数，再或者是一个字典和任意数量的关键字参数</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">dict</span>()</span><br><span class="line">&#123;&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>data=[(<span class="string">&quot;animal&quot;</span>, <span class="string">&quot;bear&quot;</span>),(<span class="string">&quot;animal&quot;</span>, <span class="string">&quot;duck&quot;</span>),(<span class="string">&quot;plant&quot;</span>, <span class="string">&quot;cactus&quot;</span>),(<span class="string">&quot;vehicle&quot;</span>, <span class="string">&quot;speed boat&quot;</span>),(<span class="string">&quot;vehicle&quot;</span>, <span class="string">&quot;school bus&quot;</span>)]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">dict</span>(data) <span class="comment">#可以传入一个二元元组列表，实际上只要是可迭代的对象且对象元素也是可迭代对象且这些元素长度一律为2的都可以</span></span><br><span class="line">&#123;<span class="string">&#x27;animal&#x27;</span>: <span class="string">&#x27;duck&#x27;</span>, <span class="string">&#x27;plant&#x27;</span>: <span class="string">&#x27;cactus&#x27;</span>, <span class="string">&#x27;vehicle&#x27;</span>: <span class="string">&#x27;school bus&#x27;</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">dict</span>(<span class="built_in">zip</span>([<span class="string">&#x27;a&#x27;</span>,<span class="string">&#x27;b&#x27;</span>,<span class="string">&#x27;c&#x27;</span>],[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])) <span class="comment">#使用zip构造二元组序列</span></span><br><span class="line">&#123;<span class="string">&#x27;a&#x27;</span>: <span class="number">1</span>, <span class="string">&#x27;b&#x27;</span>: <span class="number">2</span>, <span class="string">&#x27;c&#x27;</span>: <span class="number">3</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">dict</span>(([<span class="string">&#x27;a&#x27;</span>,<span class="number">1</span>],[<span class="string">&#x27;b&#x27;</span>,<span class="number">2</span>]),c=<span class="number">3</span>) <span class="comment">#可以传入关键字参数</span></span><br><span class="line">&#123;<span class="string">&#x27;a&#x27;</span>: <span class="number">1</span>, <span class="string">&#x27;b&#x27;</span>: <span class="number">2</span>, <span class="string">&#x27;c&#x27;</span>: <span class="number">3</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">dict</span>(&#123;<span class="number">1</span>:<span class="number">2</span>,<span class="number">3</span>:<span class="number">4</span>&#125;,last=<span class="number">6</span>) <span class="comment">#也可以传入一个字典，实际上只要是mapping类型都可以，python标准mapping就是dict</span></span><br><span class="line">&#123;<span class="number">1</span>: <span class="number">2</span>, <span class="number">3</span>: <span class="number">4</span>, <span class="string">&#x27;last&#x27;</span>: <span class="number">6</span>&#125;</span><br></pre></td></tr></table></figure></li><li><p><code>dict.fromkeys(seq[,initial])</code>根据序列<code>seq</code>构造字典，列表中的元素将作为键，需另外指定初始值<code>initial</code>，若未指定则值全部为<code>None</code>，<code>fromkeys()</code>完全可以用字典生成式实现</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>d=[<span class="string">&#x27;first&#x27;</span>,<span class="string">&#x27;second&#x27;</span>,<span class="string">&#x27;third&#x27;</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">dict</span>.fromkeys(d,<span class="number">8</span>)</span><br><span class="line">&#123;<span class="string">&#x27;first&#x27;</span>: <span class="number">8</span>, <span class="string">&#x27;second&#x27;</span>: <span class="number">8</span>, <span class="string">&#x27;third&#x27;</span>: <span class="number">8</span>&#125;</span><br></pre></td></tr></table></figure></li><li><p>字典生成式，现在有两个序列，分别为一一对应的键值序列，将其组装为字典：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=[<span class="string">&#x27;first&#x27;</span>,<span class="string">&#x27;second&#x27;</span>,<span class="string">&#x27;third&#x27;</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d=&#123;k:v <span class="keyword">for</span> k,v <span class="keyword">in</span> <span class="built_in">zip</span>(a,b)&#125; <span class="comment">#for子句中有一个变量解构操作</span></span><br><span class="line">&#123;<span class="string">&#x27;first&#x27;</span>: <span class="number">1</span>, <span class="string">&#x27;second&#x27;</span>: <span class="number">2</span>, <span class="string">&#x27;third&#x27;</span>: <span class="number">3</span>&#125;</span><br></pre></td></tr></table></figure></li></ul></li><li><p>字典更新</p><ul><li><p><code>d.update(other_d)</code>，用另一个字典<code>other_d</code>更新原字典<code>d</code>，对于原字典中不存在的键值对直接增添，若存在，则更新旧值为新值</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>d=&#123;<span class="string">&#x27;1&#x27;</span>:<span class="number">1</span>,<span class="string">&#x27;2&#x27;</span>:<span class="number">2</span>,<span class="string">&#x27;3&#x27;</span>:<span class="number">3</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d.update(&#123;<span class="string">&#x27;1&#x27;</span>:<span class="number">11</span>,<span class="string">&#x27;4&#x27;</span>:<span class="number">4</span>,<span class="string">&#x27;5&#x27;</span>:<span class="number">5</span>&#125;)</span><br><span class="line">&#123;<span class="string">&#x27;1&#x27;</span>: <span class="number">11</span>, <span class="string">&#x27;2&#x27;</span>: <span class="number">2</span>, <span class="string">&#x27;3&#x27;</span>: <span class="number">3</span>, <span class="string">&#x27;4&#x27;</span>: <span class="number">4</span>, <span class="string">&#x27;5&#x27;</span>: <span class="number">5</span>&#125;</span><br></pre></td></tr></table></figure></li><li><p><code>d[key]=value</code>方式用于添加一个新的键值对或者更新某个键的旧值</p></li></ul></li><li><p>字典元素删除</p><ul><li><p>使用<code>d.pop(key[,default])</code>删除键值对，可以指定默认的返回值，可以避免由于键不存在而导致的<code>KeyError</code>：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>d = &#123;<span class="string">&#x27;a&#x27;</span>: <span class="number">1</span>, <span class="string">&#x27;b&#x27;</span>: <span class="number">2</span>, <span class="string">&#x27;c&#x27;</span>: <span class="number">3</span>, <span class="string">&#x27;d&#x27;</span>: <span class="number">4</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d.pop(<span class="string">&#x27;e&#x27;</span>)</span><br><span class="line">Traceback (most recent call last):</span><br><span class="line">  File <span class="string">&quot;&lt;stdin&gt;&quot;</span>, line <span class="number">1</span>, <span class="keyword">in</span> &lt;module&gt;</span><br><span class="line">KeyError: <span class="string">&#x27;e&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d.pop(<span class="string">&#x27;e&#x27;</span>,<span class="literal">None</span>)</span><br><span class="line"><span class="literal">None</span></span><br></pre></td></tr></table></figure></li><li><p><code>popitem()</code>返回并删除字典中的最后一对键和值（这里没搞懂，最后一对键值是怎么确定的？）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>d = &#123;<span class="string">&#x27;a&#x27;</span>: <span class="number">1</span>, <span class="string">&#x27;b&#x27;</span>: <span class="number">2</span>, <span class="string">&#x27;c&#x27;</span>: <span class="number">3</span>, <span class="string">&#x27;d&#x27;</span>: <span class="number">4</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d.popitem()</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d</span><br><span class="line">&#123;<span class="string">&#x27;a&#x27;</span>: <span class="number">1</span>, <span class="string">&#x27;b&#x27;</span>: <span class="number">2</span>, <span class="string">&#x27;c&#x27;</span>: <span class="number">3</span>&#125;</span><br></pre></td></tr></table></figure></li><li><p>使用<code>del</code>执行删除，既可以删除整个字典，也可以删除字典的某个键值对，如果删除的键不存在，则会报错</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>d = &#123;<span class="string">&#x27;a&#x27;</span>: <span class="number">1</span>, <span class="string">&#x27;b&#x27;</span>: <span class="number">2</span>, <span class="string">&#x27;c&#x27;</span>: <span class="number">3</span>, <span class="string">&#x27;d&#x27;</span>: <span class="number">4</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">del</span> d[<span class="string">&#x27;a&#x27;</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">del</span> d</span><br></pre></td></tr></table></figure></li></ul></li><li><p>字典遍历<br><code>d.keys()</code>、<code>d.values()</code>、<code>d.items()</code>，其中<code>items()</code>多用于<code>for</code>循环遍历：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> k,v <span class="keyword">in</span> d.items():</span><br><span class="line">    <span class="built_in">print</span>(k,v)</span><br></pre></td></tr></table></figure><p>事实上，字典本身也是可迭代对象，且迭代字典对象等同于迭代字典的键序列：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>d=&#123;<span class="string">&#x27;a&#x27;</span>:<span class="number">1</span>,<span class="string">&#x27;b&#x27;</span>:<span class="number">2</span>,<span class="string">&#x27;c&#x27;</span>:<span class="number">3</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>[k <span class="keyword">for</span> k <span class="keyword">in</span> d]</span><br><span class="line">[<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;c&#x27;</span>]</span><br></pre></td></tr></table></figure></li></ol><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="dytab1-2-2"><p>和字典一样，集合虽然可以迭代，但它们都是无序的，不支持切片和index（数值下标）索引（虽然集合不属于“映射类型”，但由于都是基于散列表实现，所以放在一起描述）</p><ul><li>创建集合<br>  <ol><li>创建一个空集合：<br>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">set</span>()</span><br><span class="line">&#123;&#125;</span><br></pre></td></tr></table></figure>  <li>使用现有数据初始化一个集合，<code>set(iterable)</code>构造方法接受一个可迭代对象，如列表：<br>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line">&#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>&#125;</span><br></pre></td></tr></table></figure>  </li>  </ol></li><li>查询集合<br>  集合是无序容器，不能通过下标索引元素，只能遍历：  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> e <span class="keyword">in</span> <span class="built_in">set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]):</span><br><span class="line">    <span class="built_in">print</span>(e)</span><br></pre></td></tr></table></figure><p>使用<code>in</code>或<code>not in</code>检查某一元素是否存在于集合中：</p>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="number">1</span> <span class="keyword">in</span> <span class="built_in">set</span>([<span class="number">1</span>,<span class="number">2</span>])</span><br><span class="line"><span class="literal">True</span></span><br></pre></td></tr></table></figure></li><li>添加元素<br>  <ol><li><code>add(item)</code>向集合中添加单项元素：<br>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>s=<span class="built_in">set</span>()</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s.add(<span class="string">&#x27;msy&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s</span><br><span class="line">&#123;<span class="string">&#x27;msy&#x27;</span>&#125;</span><br></pre></td></tr></table></figure><p>注：鉴于集合的原理（散列表），向集合中添加的元素既是value又是key，因此添加的元素必须是可哈希的，即集合元素必须是不可变类型</p>  </li>  <li><code>update(iterable)</code>使用一系列元素（可迭代序列）更新集合（<code>s1.update(s2)</code>等同于“并集”操作<code>s1|=s2</code>）：<br>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>s=&#123;<span class="number">12</span>,<span class="number">13</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s.update([<span class="string">&#x27;muggle&#x27;</span>,<span class="number">101</span>,<span class="string">&#x27;msy&#x27;</span>])</span><br><span class="line">&#123;<span class="string">&#x27;muggle&#x27;</span>, <span class="number">101</span>, <span class="number">12</span>, <span class="number">13</span>, <span class="string">&#x27;msy&#x27;</span>&#125;</span><br></pre></td></tr></table></figure>  </li></ol></li><li>删除元素<br>  <ol><li><code>remove(item)</code>从集合中删除元素<code>item</code>，无返回值，如果元素不存在则引发<code>keyError</code>：<br>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>s=&#123;<span class="string">&#x27;msy&#x27;</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s.remove(<span class="string">&#x27;msy&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s.remove(<span class="string">&#x27;msy&#x27;</span>)</span><br><span class="line">Traceback (most recent call last):</span><br><span class="line">  File <span class="string">&quot;&lt;stdin&gt;&quot;</span>, line <span class="number">1</span>, <span class="keyword">in</span> &lt;module&gt;</span><br><span class="line">KeyError: <span class="string">&#x27;msy&#x27;</span></span><br></pre></td></tr></table></figure>  </li>  <li><code>discard(item)</code>同<code>remove(item)</code>，但是元素不存在时不会引发异常</li>  <li><code>pop()</code>从集合中随机删除一个元素，由于集合是无序的容器，无法通过下标索引查询元素，因此<code>pop()</code>不接受任何参数（可对比列表的<code>pop()</code>方法），该方法会返回被（某种程度可以认为是“随机”）删除的元素：<br>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>s=<span class="built_in">set</span>()</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s.update(<span class="string">&#x27;1a2b3c4d&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s</span><br><span class="line">&#123;<span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;2&#x27;</span>, <span class="string">&#x27;3&#x27;</span>, <span class="string">&#x27;4&#x27;</span>, <span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;c&#x27;</span>, <span class="string">&#x27;d&#x27;</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s.pop()</span><br><span class="line"><span class="string">&#x27;a&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s.pop()</span><br><span class="line"><span class="string">&#x27;c&#x27;</span></span><br></pre></td></tr></table></figure>  </li>  <li><code>clear()</code>删除集合中的全部元素，无返回值</li>  </ol></li><li>交并集数学运算（非原址）<br>  <ol><li><code>s1.intersection(s2)</code>返回集合<code>s1</code>和<code>s2</code>的交集，该操作对应的运算符为<code>s1 & s2</code>：<br>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1=<span class="built_in">set</span>([<span class="number">1</span>,<span class="number">2</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s2=<span class="built_in">set</span>([<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1.intersection(s2)</span><br><span class="line">&#123;<span class="number">2</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1 &amp; s2</span><br><span class="line">&#123;<span class="number">2</span>&#125;</span><br></pre></td></tr></table></figure>  </li>  <li><code>s1.union(s2)</code>返回集合<code>s1</code>和<code>s2</code>的并集，该操作对应的运算符为<code>s1 | s2</code>：<br>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1=<span class="built_in">set</span>([<span class="number">1</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s2=<span class="built_in">set</span>([<span class="number">2</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1.union(s2)</span><br><span class="line">&#123;<span class="number">1</span>, <span class="number">2</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1 | s2</span><br><span class="line">&#123;<span class="number">1</span>, <span class="number">2</span>&#125;</span><br></pre></td></tr></table></figure>  </li>  <li><code>s1.difference(s2)</code>返回集合<code>s1</code>和<code>s2</code>的差集（简单来说就是返回集合<code>s1</code>中有的而集合<code>s2</code>中所没有的那些元素），该操作对应的运算符为<code>s1 - s2</code>：<br>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1=<span class="built_in">set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s2=<span class="built_in">set</span>([<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1.difference(s2)</span><br><span class="line">&#123;<span class="number">1</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1 - s2</span><br><span class="line">&#123;<span class="number">1</span>&#125;</span><br></pre></td></tr></table></figure>  </li>  <li><code>s1.symmetric_difference(s2)</code>返回集合<code>s1</code>和<code>s2</code>的对称差集（简单说就是返回集合<code>s1</code>中有的而集合<code>s2</code>中所没有的，以及集合<code>s2</code>中有的而集合<code>s1</code>中所没有的那些元素，等同于<code>(s1-s2) | (s2-s1)</code>），该操作对应的运算符为<code>s1 ^ s2</code>：<br>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1=<span class="built_in">set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s2=<span class="built_in">set</span>([<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1.symmetric_difference(s2)</span><br><span class="line">&#123;<span class="number">1</span>, <span class="number">4</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1 ^ s2</span><br><span class="line">&#123;<span class="number">1</span>, <span class="number">4</span>&#125;</span><br></pre></td></tr></table></figure>  </li>  </ol>  注1，并集、交集、差集和对称差集的非运算符版本（non-operator，如<code>s1.union(s2)</code>）允许接受任何可迭代对象作为参数，但它们的运算符版本要求操作数必须都是集合类型：  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">set</span>([<span class="number">1</span>]).union([<span class="number">2</span>]) <span class="comment">#合法</span></span><br><span class="line">&#123;<span class="number">1</span>, <span class="number">2</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">set</span>([<span class="number">1</span>]) | [<span class="number">2</span>] <span class="comment">#非法</span></span><br><span class="line">Traceback (most recent call last):</span><br><span class="line">  File <span class="string">&quot;&lt;stdin&gt;&quot;</span>, line <span class="number">1</span>, <span class="keyword">in</span> &lt;module&gt;</span><br><span class="line">TypeError: unsupported operand <span class="built_in">type</span>(s) <span class="keyword">for</span> |: <span class="string">&#x27;set&#x27;</span> <span class="keyword">and</span> <span class="string">&#x27;list&#x27;</span></span><br></pre></td></tr></table></figure><p>注2，我们知道在执行<code>s1-s2</code>的时候，将触发执行<code>s1.difference(s2)</code>，但操作执行完毕后<code>s1</code>的值仍保持不变，属于非原址操作，同样<code>-=</code>运算符也适用于两个集合对象，在计算差集之后会立即更新第一个操作数（即完成两个步骤：<code>t=s1-s2; s1=t</code>），属于原址操作，而它实际上将触发执行<code>s1.difference_update(s2)</code>：</p>  <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1=<span class="built_in">set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s2=<span class="built_in">set</span>([<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1-s2</span><br><span class="line">&#123;<span class="number">1</span>&#125;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1.difference_update(s2) <span class="comment">#s1-=s2</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1</span><br><span class="line">&#123;<span class="number">1</span>&#125;</span><br></pre></td></tr></table></figure><p>其它原址操作：</p>  <ul><li><code>s1.intersection_update(s2)</code>交集更新操作，对应运算符为<code>s1 &= s2</code></li>  <li><code>s1.update(s2)</code>并集更新操作，对应运算符为<code>s1 |= s2</code></li>  <li><code>s1.symmetric_difference_update(s2)</code>对称差集更新操作，对应运算符为<code>s1 ^= s2</code></li>  </ul></li><li>父集和子集判断<br> <ol> <li><code>s1.issubset(s2)</code>判断集合<code>s1</code>是否是集合<code>s2</code>的子集，对应运算符为<code>s1 <= s2</code>：<br> <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1=<span class="built_in">set</span>([<span class="number">1</span>,<span class="number">2</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s2=<span class="built_in">set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1.issubset(s2)</span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1 &lt;= s2</span><br><span class="line"><span class="literal">True</span></span><br></pre></td></tr></table></figure> </li> <li><code>s1.issuperset(s2)</code>判断集合<code>s1</code>是否是集合<code>s2</code>的父集，对应运算符为<code>s1 >= s2</code>：<br> <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>s2.issuperset(s1)</span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s2 &gt;= s1</span><br><span class="line"><span class="literal">True</span></span><br></pre></td></tr></table></figure> </li> </ol>注，两个集合只有在这种情况下是相等（<code>s1 == s2</code>，不等关系测试则使用<code>!=</code>）的：集合中的每一个元素同时也是另一个集合中的元素（或者说二者互为子集）。一个集合比另一个集合小（<code>s1 < s2</code>，用于严格意义上的子集测试）：只有在第一个集合是第二个集合的子集，且第二个集合不是第一个的子集时成立。一个集合比另一个集合大（<code>s1 > s2</code>）：只有在第二个集合是第一个集合的子集，且第一个集合不是第二个的子集时成立</li><li>“冰冻”集合<br>Python提供一个集合的不可变版本<code>frozenset</code>，创建的方式同<code>set</code>，譬如：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>fs=<span class="built_in">frozenset</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])</span><br></pre></td></tr></table></figure><p>两者的区别主要在于，<code>set</code>是可变对象，不可哈希，有<code>add()</code>、<code>remove()</code>等方法，<code>frozenset</code>则是不可变的，存在哈希值，因此它可以作为字典的键，也可以作为其它集合的元素，缺点是一旦创建便不能更改，没有<code>add()</code>、<code>remove()</code>等方法，但是和普通集合一样，支持<code>union()</code>、<code>difference()</code>等交并运算以及<code>issubset()</code>等关系运算</p><p>普通集合和冰冻集合可以混用，用于交并运算时，第一个操作数的类型还决定了返回值的类型，譬如第一个操作数是<code>frozenset</code>，第二个是<code>set</code>，那么返回值就是<code>frozenset</code>：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">frozenset</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])-<span class="built_in">set</span>([<span class="number">1</span>])</span><br><span class="line"><span class="built_in">frozenset</span>(&#123;<span class="number">2</span>, <span class="number">3</span>&#125;)</span><br></pre></td></tr></table></figure><p><code>collections</code>模块提供了两个集合类型，<code>Set</code>和<code>MutableSet</code>，后者用于判断是否是可变集合</p></li></ul><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><br><link rel="stylesheet" href="https://cdn.statically.io/gh/celestezj/ImageHosting/v4.5/data/donate/donate.min.css"><div id="dy-coffee-donate" style="position:relative;width:317px;height:98px;left:calc(50% - 159px);z-index: 1">    <a id="donategithub" href="https://github.com/Kaiyuan/sponsor-page" target="_blank" title="Github" style="position:absolute"></a>    <div id="DonateText" class="donatetr3"><span title="请勿轻信，仅作示范使用">Sponsor</span></div>    <ul id="donateBox" class="donatelist donate-pos-f donatetr3">        <li id="PayPal"><a href="javascript:void(0)" title="暂未开通">PayPal</a></li><!-- target="_blank" -->        <li id="BTC"></li>        <li id="AliPay">AliPay</li>        <li id="DonateWeChat">WeChat</li>    </ul>    <div id="QRBox" class="donate-pos-f donate-left-100">    <div id="DonateMainBox"></div></div></div><script src="https://cdn.statically.io/gh/celestezj/ImageHosting/v4.5/data/donate/donate.min.js"></script><div class="tip fas fa-quote-left"><p>[1] <a href="https://pan.baidu.com/s/17r__wNMxIXTMWhglf3wyuw" title="密码：1y2r" target="_blank"><span style="color:red">Python参考手册</span> 第4版 修订版 [美] 大卫·M.比兹利（David M.Beazley）著，谢俊，杨越，高伟 译</a><br>[2] <a href="https://blog.csdn.net/sunxb10/article/details/81036693" target="_blank">Formatted string literals 详解</a><br>[3] <a href="https://www.zhihu.com/question/38791962" target="_blank">知乎 Python的type和object之间是什么关系？</a><br>[4] <a href="http://python.jobbole.com/86258/" target="_blank">可迭代对象和迭代器</a></p></div>]]></content>
      
      
      <categories>
          
          <category> 计算机基础 </category>
          
          <category> 编程语言 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> Python </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>Numpy基础教程</title>
      <link href="posts/10423/"/>
      <url>posts/10423/</url>
      
        <content type="html"><![CDATA[<style>.note.simple{    padding-left: 1rem;}.table-wrap {    margin: 0 0 .3rem;}</style><div class="note info flat"><p><span title="2018.12.26-2019.1.21">考研那年年末</span>学习和梳理了numpy和matplotlib这两个模块，该文档主要就是基于那时的笔记，matplotlib没有时间重新整理了，见原始笔记（<a href="https://muggledy.github.io/appendix/matplotlib/1/" target="_blank">matplotlib初级教程</a>、<a href="https://muggledy.github.io/appendix/matplotlib/2/" target="_blank">3D绘图</a>、<a href="https://muggledy.github.io/appendix/matplotlib/3/" target="_blank">patches与path</a>）</p></div><p>Numpy主要提供了同构（所有元素类型相同）多维（维度也被称为“轴”）数组对象<code>ndarray</code>，具有矢量化运算能力，除了支持多维数组与矩阵运算，此外还针对数组运算提供大量的数学函数库</p><p>首先看看核心对象<code>ndarray</code>的主要属性：</p><ul><li><code>ndim</code>：轴的数量，即数组维数</li><li><code>shape</code>：数组的形状，一个整数元组，长度即为数组维数，从左到右依次是每个维度的轴长，譬如一个<code>n</code>行<code>m</code>列的矩阵，其形状为<code>(n,m)</code>，表示第0维（轴）的长度为<code>n</code>、第1维（轴）的长度为<code>m</code></li><li><code>dtype</code>：数组元素类型，如<code>np.int32</code>、<code>np.int16</code>和<code>np.float64</code>（<code>np</code>是<code>numpy</code>的缩写）</li><li><code>flags</code>：数组的<a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.flags.html" class="dyadefaultcolor" title="很多numpy函数都有一个order参数，我是似懂非懂——即是不懂">内存布局</a>信息</li><li><code>real</code>和<code>imag</code>：分别是数组的实部和虚部（即时非虚数类型也有这两个属性）</li><li><code>itemsize</code>：数组元素大小，以字节为单位，如元素为<code>float64</code>类型的数组<code>itemsize</code>为8（64/8，一个字节占8位），而<code>complex32</code>类型的数组<code>itemsize</code>为4（32/8），其等于<code>ndarray.dtype.itemsize</code></li><li><code>size</code>：数组中的元素个数（可用于判断数组是否为空，<code>np.array([]).size=0</code>）</li><li><code>T</code>：数组转置，仅针对二维数组（或矩阵<code>matrix</code>对象）</li><li><code>strides</code>：跨度元组，其中的整数是指为了前进到当前维度下一个元素需要“跨过”的字节数</li><li><code>flat</code>：数组的元素迭代器，返回一个<code>flatiter</code>对象，可以用作一维数组“视图”</li></ul><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>数据类型</span></div>    <div class="hide-content"><p>内置数据类型包括（括号中是数据类型的格式字符或格式字符串）：<br><code>np.bool</code>（<code>?</code>或<code>b1</code>）、<code>np.int</code>（默认为<code>np.int32</code>）、<code>np.int8</code>（<code>b</code>或<code>i1</code>或<code>int8</code>）、<code>np.int16</code>（<code>h</code>或<code>i2</code>或<code>int16</code>）、<code>np.int32</code>（<code>i</code>或<code>i4</code>或<code>int32</code>）、<code>np.int64</code>（<code>q</code>或<code>i8</code>或<code>int64</code>）、<code>np.uint8</code>（<code>B</code>或<code>u1</code>或<code>uint8</code>）、<code>np.uint16</code>（<code>H</code>或<code>u2</code>或<code>uint16</code>）、<code>np.uint32</code>（<code>I</code>或<code>u4</code>或<code>uint32</code>）、<code>np.uint64</code>（<code>Q</code>或<code>u8</code>或<code>uint64</code>）、<code>np.float</code>（默认为<code>np.float64</code>）、<code>np.float16</code>（<code>e</code>或<code>f2</code>或<code>float16</code>）、<code>np.float32</code>（<code>f</code>或<code>f4</code>或<code>float32</code>）、<code>np.float64</code>（<code>d</code>或<code>f8</code>或<code>float64</code>）、<code>np.complex</code>（默认为<code>np.complex128</code>）、<code>np.complex64</code>（<code>F</code>或<code>c8</code>或<code>complex64</code>）、<code>np.complex128</code>（<code>D</code>或<code>c16</code>或<code>complex128</code>）、<code>np.str</code>（<code>a</code>或<code>S</code>，可以在<code>a</code>或<code>S</code>后面添加数字，表示字符串长度，比如<code>S3</code>表示长度为三的字符串，不写则为最大长度）、<code>np.unicode</code>（<code>U</code>）、<code>np.object</code>（<code>O</code>）、<code>np.void</code>（<code>V</code>）。可以用格式字符（串）作为<code>np.dtype()</code>的参数来创建相应的数据类型对象，或作为<code>np.array()</code>等函数的参数用于创建数组对象，譬如<code>np.dtype('i1')==np.int8</code>、<code>np.array([1,2,3,4],dtype='d')</code></p><p>注1：可以通过<code>np.sctypeDict.keys()</code>获取所有的字符代码，<code>dtype</code>对象有一个<code>char</code>属性用于获取对应的字符代码（另见<code>str</code>属性），还有一个<code>type</code>属性获取对应的数据类型<br>注2：数组的类型转换可以通过<code>astype()</code>方法实现，譬如<code>np.array([1,2,3],dtype='i4').astype('float')</code>（将数据类型从<code>int32</code>转换成<code>float64</code>）</p><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>自定义结构化数据类型</span></div>    <div class="hide-content"><p>Numpy允许我们自定义结构化数据类型和结构化数组对象（<a href="https://numpy.org/doc/stable/user/basics.rec.html" class="dyadefaultcolor">numpy structured arrays</a>），这些数组既可以通过标签索引也可以通过命名字段索引，看一个简单的示例：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.array([[[(<span class="string">&#x27;a&#x27;</span>,<span class="number">1</span>),(<span class="string">&#x27;b&#x27;</span>,<span class="number">2</span>),(<span class="string">&#x27;c&#x27;</span>,<span class="number">3</span>)],[(<span class="string">&#x27;d&#x27;</span>,<span class="number">4</span>),(<span class="string">&#x27;e&#x27;</span>,<span class="number">5</span>),(<span class="string">&#x27;f&#x27;</span>,<span class="number">6</span>)],[(<span class="string">&#x27;g&#x27;</span>,<span class="number">7</span>),(<span class="string">&#x27;h&#x27;</span>,<span class="number">8</span>),(<span class="string">&#x27;i&#x27;</span>,<span class="number">9</span>)]],[[(<span class="string">&#x27;j&#x27;</span>,<span class="number">10</span>),(<span class="string">&#x27;k&#x27;</span>,<span class="number">11</span>),(<span class="string">&#x27;l&#x27;</span>,<span class="number">12</span>)],[(<span class="string">&#x27;m&#x27;</span>,<span class="number">13</span>),(<span class="string">&#x27;n&#x27;</span>,<span class="number">14</span>),(<span class="string">&#x27;o&#x27;</span>,<span class="number">15</span>)],[(<span class="string">&#x27;p&#x27;</span>,<span class="number">16</span>),(<span class="string">&#x27;q&#x27;</span>,<span class="number">17</span>),(<span class="string">&#x27;r&#x27;</span>,<span class="number">18</span>)]]],dtype=[(<span class="string">&#x27;char&#x27;</span>,<span class="string">&#x27;S3&#x27;</span>),(<span class="string">&#x27;int&#x27;</span>,np.<span class="built_in">int</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">3</span>, <span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.dtype</span><br><span class="line">dtype([(<span class="string">&#x27;char&#x27;</span>, <span class="string">&#x27;S3&#x27;</span>), (<span class="string">&#x27;int&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">1</span>]</span><br><span class="line">array([[(<span class="string">b&#x27;j&#x27;</span>, <span class="number">10</span>), (<span class="string">b&#x27;k&#x27;</span>, <span class="number">11</span>), (<span class="string">b&#x27;l&#x27;</span>, <span class="number">12</span>)],</span><br><span class="line">       [(<span class="string">b&#x27;m&#x27;</span>, <span class="number">13</span>), (<span class="string">b&#x27;n&#x27;</span>, <span class="number">14</span>), (<span class="string">b&#x27;o&#x27;</span>, <span class="number">15</span>)],</span><br><span class="line">       [(<span class="string">b&#x27;p&#x27;</span>, <span class="number">16</span>), (<span class="string">b&#x27;q&#x27;</span>, <span class="number">17</span>), (<span class="string">b&#x27;r&#x27;</span>, <span class="number">18</span>)]],</span><br><span class="line">      dtype=[(<span class="string">&#x27;char&#x27;</span>, <span class="string">&#x27;S3&#x27;</span>), (<span class="string">&#x27;int&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">3</span>, <span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>] <span class="comment">#等同于a[1][1][1]</span></span><br><span class="line">(<span class="string">b&#x27;n&#x27;</span>, <span class="number">14</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>c=a[<span class="string">&#x27;char&#x27;</span>] <span class="comment">#切片和索引得到的可变对象都是浅拷贝，所以对c的修改将如实反映在a中</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>c</span><br><span class="line">array([[[<span class="string">b&#x27;a&#x27;</span>, <span class="string">b&#x27;b&#x27;</span>, <span class="string">b&#x27;c&#x27;</span>],</span><br><span class="line">        [<span class="string">b&#x27;d&#x27;</span>, <span class="string">b&#x27;e&#x27;</span>, <span class="string">b&#x27;f&#x27;</span>],</span><br><span class="line">        [<span class="string">b&#x27;g&#x27;</span>, <span class="string">b&#x27;h&#x27;</span>, <span class="string">b&#x27;i&#x27;</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="string">b&#x27;j&#x27;</span>, <span class="string">b&#x27;k&#x27;</span>, <span class="string">b&#x27;l&#x27;</span>],</span><br><span class="line">        [<span class="string">b&#x27;m&#x27;</span>, <span class="string">b&#x27;n&#x27;</span>, <span class="string">b&#x27;o&#x27;</span>],</span><br><span class="line">        [<span class="string">b&#x27;p&#x27;</span>, <span class="string">b&#x27;q&#x27;</span>, <span class="string">b&#x27;r&#x27;</span>]]], dtype=<span class="string">&#x27;|S3&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>c.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">3</span>, <span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>c[<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>]=<span class="string">&#x27;dy&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>]</span><br><span class="line">(<span class="string">b&#x27;dy&#x27;</span>, <span class="number">14</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="string">&#x27;int&#x27;</span>]</span><br><span class="line">array([[[ <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">        [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>],</span><br><span class="line">        [ <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">10</span>, <span class="number">11</span>, <span class="number">12</span>],</span><br><span class="line">        [<span class="number">13</span>, <span class="number">14</span>, <span class="number">15</span>],</span><br><span class="line">        [<span class="number">16</span>, <span class="number">17</span>, <span class="number">18</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.dtype</span><br><span class="line">dtype(<span class="string">&#x27;int32&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">0</span>][<span class="string">&#x27;int&#x27;</span>]</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>],</span><br><span class="line">       [<span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[[<span class="string">&#x27;int&#x27;</span>,<span class="string">&#x27;char&#x27;</span>]] <span class="comment">#可以使用字段名称列表一次访问多个字段，类似于花式索引</span></span><br><span class="line">array([[[( <span class="number">1</span>, <span class="string">b&#x27;a&#x27;</span>), ( <span class="number">2</span>, <span class="string">b&#x27;b&#x27;</span>), ( <span class="number">3</span>, <span class="string">b&#x27;c&#x27;</span>)],</span><br><span class="line">        [( <span class="number">4</span>, <span class="string">b&#x27;d&#x27;</span>), ( <span class="number">5</span>, <span class="string">b&#x27;e&#x27;</span>), ( <span class="number">6</span>, <span class="string">b&#x27;f&#x27;</span>)],</span><br><span class="line">        [( <span class="number">7</span>, <span class="string">b&#x27;g&#x27;</span>), ( <span class="number">8</span>, <span class="string">b&#x27;h&#x27;</span>), ( <span class="number">9</span>, <span class="string">b&#x27;i&#x27;</span>)]],</span><br><span class="line"></span><br><span class="line">       [[(<span class="number">10</span>, <span class="string">b&#x27;j&#x27;</span>), (<span class="number">11</span>, <span class="string">b&#x27;k&#x27;</span>), (<span class="number">12</span>, <span class="string">b&#x27;l&#x27;</span>)],</span><br><span class="line">        [(<span class="number">13</span>, <span class="string">b&#x27;m&#x27;</span>), (<span class="number">14</span>, <span class="string">b&#x27;n&#x27;</span>), (<span class="number">15</span>, <span class="string">b&#x27;o&#x27;</span>)],</span><br><span class="line">        [(<span class="number">16</span>, <span class="string">b&#x27;p&#x27;</span>), (<span class="number">17</span>, <span class="string">b&#x27;q&#x27;</span>), (<span class="number">18</span>, <span class="string">b&#x27;r&#x27;</span>)]]],</span><br><span class="line">      dtype=[(<span class="string">&#x27;int&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>), (<span class="string">&#x27;char&#x27;</span>, <span class="string">&#x27;S3&#x27;</span>)])</span><br></pre></td></tr></table></figure><p>上面这个数组<code>a</code>的形状是<code>(2,3,3)</code>，只不过每一个元素都是结构化数据，其由两个字段构成，字段名称分别为<code>char</code>和<code>int</code>，类型分别为“长度为3的字符串”和“32位整数”，可以像访问字典那样将某一字段的数据从结构化数组中剥离出来，如<code>a['int']</code>，也可以同时访问多个字段，如<code>a[['int','char']]</code>。结构化数据类型同样可以用于创建特定数组，譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>z=np.zeros(<span class="number">3</span>,dtype=np.dtype([(<span class="string">&#x27;first&#x27;</span>,<span class="string">&#x27;i4&#x27;</span>),(<span class="string">&#x27;second&#x27;</span>,<span class="string">&#x27;f&#x27;</span>)]))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z</span><br><span class="line">array([(<span class="number">0</span>, <span class="number">0.</span>), (<span class="number">0</span>, <span class="number">0.</span>), (<span class="number">0</span>, <span class="number">0.</span>)],</span><br><span class="line">      dtype=[(<span class="string">&#x27;first&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>), (<span class="string">&#x27;second&#x27;</span>, <span class="string">&#x27;&lt;f4&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z.shape</span><br><span class="line">(<span class="number">3</span>,)</span><br></pre></td></tr></table></figure><p>上述结构化数据类型的定义形如<code>[(字段名,类型),...]</code>（二元组列表），其中“类型”既可以是<code>dtype</code>对象，也可以是类型格式字符（串），且类型格式字符（串）前面还可以添加可选的“形状”信息，用于描述数组形状，换句话说，字段类型除了可以是整型、布尔型、字符串、复数类型等外，还可以是数组类型，譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>z=np.zeros(<span class="number">3</span>,dtype=np.dtype([(<span class="string">&#x27;first&#x27;</span>,<span class="string">&#x27;(2,3)i4&#x27;</span>),(<span class="string">&#x27;second&#x27;</span>,<span class="string">&#x27;f&#x27;</span>)]))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z.shape</span><br><span class="line">(<span class="number">3</span>,)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z[<span class="string">&#x27;first&#x27;</span>]</span><br><span class="line">array([[[<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>],</span><br><span class="line">        [<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>],</span><br><span class="line">        [<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>],</span><br><span class="line">        [<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">3</span>, <span class="number">2</span>, <span class="number">3</span>)</span><br></pre></td></tr></table></figure><p>事实上，还有其他三种定义结构化数据类型的方式：</p><ul><li><p>以逗号分隔的类型格式字符串<br>每个类型字符串各自代表一个字段，但是此种情况下无法自由指定字段名，默认的字段名为<code>f0</code>、<code>f1</code>、…，譬如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>z=np.zeros(<span class="number">3</span>,dtype=<span class="string">&#x27;3int8, float32, (2,3)float64&#x27;</span>) <span class="comment">#包含三个字段，字段1为(3,)形单字节整数类型数组，字段2为32位浮点数，字段3为(2,3)形64位浮点数类型数组</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z.shape</span><br><span class="line">(<span class="number">3</span>,)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z[<span class="string">&#x27;f0&#x27;</span>]</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>],</span><br><span class="line">       [<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>],</span><br><span class="line">       [<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>]], dtype=int8)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z[<span class="string">&#x27;f1&#x27;</span>]</span><br><span class="line">array([<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">0.</span>], dtype=float32)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z[<span class="string">&#x27;f2&#x27;</span>]</span><br><span class="line">array([[[<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">0.</span>],</span><br><span class="line">        [<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">0.</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">0.</span>],</span><br><span class="line">        [<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">0.</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">0.</span>],</span><br><span class="line">        [<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">0.</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.dtype</span><br><span class="line">dtype(<span class="string">&#x27;float64&#x27;</span>)</span><br></pre></td></tr></table></figure></li><li><p>字典，形如<code>{'names':[字段名1,...],'formats':[类型1,...]}</code>：</p>   <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>z=np.zeros(<span class="number">3</span>,&#123;<span class="string">&#x27;names&#x27;</span>:[<span class="string">&#x27;first&#x27;</span>,<span class="string">&#x27;second&#x27;</span>],<span class="string">&#x27;formats&#x27;</span>:[np.float32,<span class="string">&#x27;2i4&#x27;</span>]&#125;)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z.shape</span><br><span class="line">(<span class="number">3</span>,)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z.dtype</span><br><span class="line">dtype([(<span class="string">&#x27;first&#x27;</span>, <span class="string">&#x27;&lt;f4&#x27;</span>), (<span class="string">&#x27;second&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>, (<span class="number">2</span>,))])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z[<span class="string">&#x27;first&#x27;</span>]</span><br><span class="line">array([<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">0.</span>], dtype=float32)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z[<span class="string">&#x27;second&#x27;</span>]</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">0</span>],</span><br><span class="line">       [<span class="number">0</span>, <span class="number">0</span>],</span><br><span class="line">       [<span class="number">0</span>, <span class="number">0</span>]])</span><br></pre></td></tr></table></figure></li><li><p>这个似乎比较特殊，我也不知道具体有什么应用，看个例子吧：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>z=np.zeros(<span class="number">3</span>, dtype=(<span class="string">&#x27;i4&#x27;</span>,[(<span class="string">&#x27;b1&#x27;</span>,<span class="string">&#x27;u1&#x27;</span>), (<span class="string">&#x27;b2&#x27;</span>,<span class="string">&#x27;u1&#x27;</span>), (<span class="string">&#x27;b3&#x27;</span>,<span class="string">&#x27;u1&#x27;</span>), (<span class="string">&#x27;b4&#x27;</span>,<span class="string">&#x27;u1&#x27;</span>)]))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z.shape</span><br><span class="line">(<span class="number">3</span>,)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z</span><br><span class="line">array([<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>],</span><br><span class="line">      dtype=(numpy.int32, [(<span class="string">&#x27;b1&#x27;</span>, <span class="string">&#x27;u1&#x27;</span>), (<span class="string">&#x27;b2&#x27;</span>, <span class="string">&#x27;u1&#x27;</span>), (<span class="string">&#x27;b3&#x27;</span>, <span class="string">&#x27;u1&#x27;</span>), (<span class="string">&#x27;b4&#x27;</span>, <span class="string">&#x27;u1&#x27;</span>)]))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z[<span class="string">&#x27;b1&#x27;</span>]</span><br><span class="line">array([<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>], dtype=uint8)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z[<span class="string">&#x27;b1&#x27;</span>]=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z[<span class="string">&#x27;b2&#x27;</span>]=[<span class="number">11</span>,<span class="number">12</span>,<span class="number">13</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z</span><br><span class="line">array([<span class="number">2817</span>, <span class="number">3074</span>, <span class="number">3331</span>],</span><br><span class="line">      dtype=(numpy.int32, [(<span class="string">&#x27;b1&#x27;</span>, <span class="string">&#x27;u1&#x27;</span>), (<span class="string">&#x27;b2&#x27;</span>, <span class="string">&#x27;u1&#x27;</span>), (<span class="string">&#x27;b3&#x27;</span>, <span class="string">&#x27;u1&#x27;</span>), (<span class="string">&#x27;b4&#x27;</span>, <span class="string">&#x27;u1&#x27;</span>)]))</span><br></pre></td></tr></table></figure><p>简单解释一下，<code>('i4',[('b1','u1'), ('b2','u1'), ('b3','u1'), ('b4','u1')])</code>表示将一个4字节的整型划分成了四个部分，每部分都是一个单字节的无符号整型，分别对应字段<code>b1</code>（最低字节）、<code>b2</code>、<code>b3</code>、<code>b4</code>（最高字节），此时有<code>z[i]==(z['b4'][i]&lt;&lt;24)+(z['b3'][i]&lt;&lt;16)+(z['b2'][i]&lt;&lt;8)+z['b1'][i]</code>成立，以<code>z[1]</code>为例，<code>z['b1'][1]=2</code>（十进制的<code>2</code>对应二进制的<code>00000010</code>），<code>z['b2'][1]=12</code>（十进制的<code>12</code>对应二进制的<code>00001100</code>），<code>z['b3'][1]=0</code>（十进制的<code>0</code>对应二进制的<code>00000000</code>），<code>z['b4'][1]=0</code>（十进制的<code>0</code>对应二进制的<code>00000000</code>），于是将这四个字节拼接得到<code>00000000,00000000,00001100,00000010</code>，再转换成十进制即可得到<code>3074</code></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="number">0b00000000_00000000_00001100_00000010</span></span><br><span class="line"><span class="number">3074</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>i=<span class="number">1</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z[i]==(z[<span class="string">&#x27;b4&#x27;</span>][i]&lt;&lt;<span class="number">24</span>)+(z[<span class="string">&#x27;b3&#x27;</span>][i]&lt;&lt;<span class="number">16</span>)+(z[<span class="string">&#x27;b2&#x27;</span>][i]&lt;&lt;<span class="number">8</span>)+z[<span class="string">&#x27;b1&#x27;</span>][i]</span><br><span class="line"><span class="literal">True</span></span><br></pre></td></tr></table></figure><p>另外还可以这样定义：<code>z=np.zeros(3, dtype=('i4','u1,u1,u1,u1'))</code>、<code>z=np.zeros(3, dtype=('i4',{'names':['b1','b2','b3','b4'],'formats':['u1','u1','u1','u1']}))</code>，都是一样的</p></li></ul><p>可以通过<code>names</code>属性访问和修改结构化数据类型的字段名，还有一个类似于字典的<code>fields</code>只读属性，键名为字段名，非结构化数据类型的<code>names</code>和<code>fields</code>都是<code>None</code>，因而可以据此判断一个<code>dtype</code>对象是否是结构化数据类型：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>d=np.dtype(<span class="string">&#x27;i1,f,S10&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d.<span class="built_in">type</span></span><br><span class="line">&lt;<span class="keyword">class</span> <span class="string">&#x27;numpy.void&#x27;</span>&gt;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d.names</span><br><span class="line">(<span class="string">&#x27;f0&#x27;</span>, <span class="string">&#x27;f1&#x27;</span>, <span class="string">&#x27;f2&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d.names=(<span class="string">&#x27;field1&#x27;</span>,<span class="string">&#x27;field2&#x27;</span>,<span class="string">&#x27;field3&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d</span><br><span class="line">dtype([(<span class="string">&#x27;field1&#x27;</span>, <span class="string">&#x27;i1&#x27;</span>), (<span class="string">&#x27;field2&#x27;</span>, <span class="string">&#x27;&lt;f4&#x27;</span>), (<span class="string">&#x27;field3&#x27;</span>, <span class="string">&#x27;S10&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d.fields <span class="comment">#键值为字段类型和偏移量构成的元组，我也不知道这个偏移量是什么鬼，官方文档里我没有找到相关解释啊</span></span><br><span class="line">mappingproxy(&#123;<span class="string">&#x27;f0&#x27;</span>: (dtype(<span class="string">&#x27;int8&#x27;</span>), <span class="number">0</span>), <span class="string">&#x27;f1&#x27;</span>: (dtype(<span class="string">&#x27;float32&#x27;</span>), <span class="number">1</span>), <span class="string">&#x27;f2&#x27;</span>: (dtype(<span class="string">&#x27;S10&#x27;</span>), <span class="number">5</span>)&#125;)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.dtype(<span class="string">&#x27;i4&#x27;</span>).names <span class="keyword">is</span> <span class="literal">None</span></span><br><span class="line"><span class="literal">True</span></span><br></pre></td></tr></table></figure><p>可以按行、按列或者按字段对结构化数组进行填充：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>z=np.zeros((<span class="number">2</span>,<span class="number">3</span>),dtype=[(<span class="string">&#x27;f1&#x27;</span>,<span class="string">&#x27;i4&#x27;</span>),(<span class="string">&#x27;f2&#x27;</span>,<span class="string">&#x27;f&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z</span><br><span class="line">array([[(<span class="number">0</span>, <span class="number">0.</span>), (<span class="number">0</span>, <span class="number">0.</span>), (<span class="number">0</span>, <span class="number">0.</span>)],</span><br><span class="line">       [(<span class="number">0</span>, <span class="number">0.</span>), (<span class="number">0</span>, <span class="number">0.</span>), (<span class="number">0</span>, <span class="number">0.</span>)]], dtype=[(<span class="string">&#x27;f1&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>), (<span class="string">&#x27;f2&#x27;</span>, <span class="string">&#x27;&lt;f4&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z[<span class="number">0</span>]=[(<span class="number">1</span>,<span class="number">2</span>),(<span class="number">3</span>,<span class="number">4</span>),(<span class="number">5</span>,<span class="number">6</span>)] <span class="comment">#按行填充</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z[:,<span class="number">0</span>]=[(<span class="number">11</span>,<span class="number">12</span>),(<span class="number">13</span>,<span class="number">14</span>)] <span class="comment">#按列填充</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z[<span class="string">&#x27;f1&#x27;</span>]=[[<span class="number">21</span>,<span class="number">22</span>,<span class="number">23</span>],[<span class="number">24</span>,<span class="number">25</span>,<span class="number">26</span>]] <span class="comment">#按字段填充</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z[<span class="number">1</span>,<span class="number">1</span>]=(<span class="number">31</span>,<span class="number">32</span>) <span class="comment">#注意只能使用元组填充某一个元素而不能使用列表，否则报错ValueError: setting an array element with a sequence.</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z</span><br><span class="line">array([[(<span class="number">21</span>, <span class="number">12.</span>), (<span class="number">22</span>,  <span class="number">4.</span>), (<span class="number">23</span>,  <span class="number">6.</span>)],</span><br><span class="line">       [(<span class="number">24</span>, <span class="number">14.</span>), (<span class="number">31</span>, <span class="number">32.</span>), (<span class="number">26</span>,  <span class="number">0.</span>)]],</span><br><span class="line">      dtype=[(<span class="string">&#x27;f1&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>), (<span class="string">&#x27;f2&#x27;</span>, <span class="string">&#x27;&lt;f4&#x27;</span>)])</span><br></pre></td></tr></table></figure><div class="note warning flat"><p>这里介绍的并不全面，实际上每个字段还可以指定偏移量和标题等（我也没大看懂，具体有什么用我也不知道），并且构造方式也不止上述几种形式，具体请参阅官方文档</p></div><p>创建结构化数组时需要注意的地方：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>L=[[[<span class="number">0</span>, <span class="number">0</span>], [<span class="number">0</span>, <span class="number">1</span>], [<span class="number">0</span>, <span class="number">2</span>], [<span class="number">0</span>, <span class="number">3</span>]], [[<span class="number">1</span>, <span class="number">0</span>], [<span class="number">1</span>, <span class="number">1</span>], [<span class="number">1</span>, <span class="number">2</span>], [<span class="number">1</span>, <span class="number">3</span>]], [[<span class="number">2</span>, <span class="number">0</span>], [<span class="number">2</span>, <span class="number">1</span>], [<span class="number">2</span>, <span class="number">2</span>], [<span class="number">2</span>, <span class="number">3</span>]]]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>LT=[[(<span class="number">0</span>, <span class="number">0</span>), (<span class="number">0</span>, <span class="number">1</span>), (<span class="number">0</span>, <span class="number">2</span>), (<span class="number">0</span>, <span class="number">3</span>)], [(<span class="number">1</span>, <span class="number">0</span>), (<span class="number">1</span>, <span class="number">1</span>), (<span class="number">1</span>, <span class="number">2</span>), (<span class="number">1</span>, <span class="number">3</span>)], [(<span class="number">2</span>, <span class="number">0</span>), (<span class="number">2</span>, <span class="number">1</span>), (<span class="number">2</span>, <span class="number">2</span>), (<span class="number">2</span>, <span class="number">3</span>)]]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.array(L,dtype=<span class="string">&#x27;i4,i4&#x27;</span>)</span><br><span class="line">array([[[(<span class="number">0</span>, <span class="number">0</span>), (<span class="number">0</span>, <span class="number">0</span>)],</span><br><span class="line">        [(<span class="number">0</span>, <span class="number">0</span>), (<span class="number">1</span>, <span class="number">1</span>)],</span><br><span class="line">        [(<span class="number">0</span>, <span class="number">0</span>), (<span class="number">2</span>, <span class="number">2</span>)],</span><br><span class="line">        [(<span class="number">0</span>, <span class="number">0</span>), (<span class="number">3</span>, <span class="number">3</span>)]],</span><br><span class="line"></span><br><span class="line">       [[(<span class="number">1</span>, <span class="number">1</span>), (<span class="number">0</span>, <span class="number">0</span>)],</span><br><span class="line">        [(<span class="number">1</span>, <span class="number">1</span>), (<span class="number">1</span>, <span class="number">1</span>)],</span><br><span class="line">        [(<span class="number">1</span>, <span class="number">1</span>), (<span class="number">2</span>, <span class="number">2</span>)],</span><br><span class="line">        [(<span class="number">1</span>, <span class="number">1</span>), (<span class="number">3</span>, <span class="number">3</span>)]],</span><br><span class="line"></span><br><span class="line">       [[(<span class="number">2</span>, <span class="number">2</span>), (<span class="number">0</span>, <span class="number">0</span>)],</span><br><span class="line">        [(<span class="number">2</span>, <span class="number">2</span>), (<span class="number">1</span>, <span class="number">1</span>)],</span><br><span class="line">        [(<span class="number">2</span>, <span class="number">2</span>), (<span class="number">2</span>, <span class="number">2</span>)],</span><br><span class="line">        [(<span class="number">2</span>, <span class="number">2</span>), (<span class="number">3</span>, <span class="number">3</span>)]]], dtype=[(<span class="string">&#x27;f0&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>), (<span class="string">&#x27;f1&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">3</span>, <span class="number">4</span>, <span class="number">2</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.array(LT,dtype=<span class="string">&#x27;i4,i4&#x27;</span>)</span><br><span class="line">array([[(<span class="number">0</span>, <span class="number">0</span>), (<span class="number">0</span>, <span class="number">1</span>), (<span class="number">0</span>, <span class="number">2</span>), (<span class="number">0</span>, <span class="number">3</span>)],</span><br><span class="line">       [(<span class="number">1</span>, <span class="number">0</span>), (<span class="number">1</span>, <span class="number">1</span>), (<span class="number">1</span>, <span class="number">2</span>), (<span class="number">1</span>, <span class="number">3</span>)],</span><br><span class="line">       [(<span class="number">2</span>, <span class="number">0</span>), (<span class="number">2</span>, <span class="number">1</span>), (<span class="number">2</span>, <span class="number">2</span>), (<span class="number">2</span>, <span class="number">3</span>)]],</span><br><span class="line">      dtype=[(<span class="string">&#x27;f0&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>), (<span class="string">&#x27;f1&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">3</span>, <span class="number">4</span>)</span><br></pre></td></tr></table></figure><p>我写了个函数（<code>list2structarray()</code>）来解决该问题：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="comment">#给定结构化数据类型将一个（嵌套）列表无差别转换成结构化数组对象</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">list2structarray</span>(<span class="params">a,dtype</span>):</span><br><span class="line">    a=np.array(a)</span><br><span class="line">    t=[<span class="built_in">tuple</span>(i) <span class="keyword">for</span> i <span class="keyword">in</span> a.reshape(-<span class="number">1</span>,a.shape[-<span class="number">1</span>])]</span><br><span class="line">    <span class="keyword">return</span> np.array(t,dtype=dtype).reshape(a.shape[:-<span class="number">1</span>])</span><br><span class="line">    </span><br><span class="line">a=[[[<span class="number">0</span>, <span class="number">0</span>], [<span class="number">0</span>, <span class="number">1</span>], [<span class="number">0</span>, <span class="number">2</span>], [<span class="number">0</span>, <span class="number">3</span>]], [[<span class="number">1</span>, <span class="number">0</span>], [<span class="number">1</span>, <span class="number">1</span>], [<span class="number">1</span>, <span class="number">2</span>], [<span class="number">1</span>, <span class="number">3</span>]], [[<span class="number">2</span>, <span class="number">0</span>], [<span class="number">2</span>, <span class="number">1</span>], [<span class="number">2</span>, <span class="number">2</span>], [<span class="number">2</span>, <span class="number">3</span>]]]</span><br><span class="line">s=list2structarray(a,<span class="string">&#x27;i4,i4&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(s)</span><br><span class="line"><span class="built_in">print</span>(s.shape)</span><br><span class="line"><span class="built_in">print</span>(s.dtype)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">[[(0, 0) (0, 1) (0, 2) (0, 3)]</span></span><br><span class="line"><span class="string"> [(1, 0) (1, 1) (1, 2) (1, 3)]</span></span><br><span class="line"><span class="string"> [(2, 0) (2, 1) (2, 2) (2, 3)]]</span></span><br><span class="line"><span class="string">(3, 4)</span></span><br><span class="line"><span class="string">[(&#x27;f0&#x27;, &#x27;&lt;i4&#x27;), (&#x27;f1&#x27;, &#x27;&lt;i4&#x27;)]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></div></div></div></div><h2 id="创建数组">创建数组</h2><div class="tabs" id="cjsz"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#cjsz-1"><code>np.array()</code></button></li><li class="tab"><button type="button" data-href="#cjsz-2"><code>np.asarray()</code></button></li><li class="tab"><button type="button" data-href="#cjsz-3"><code>np.fromiter()</code></button></li><li class="tab"><button type="button" data-href="#cjsz-4"><code>np.fromfunction()</code></button></li><li class="tab"><button type="button" data-href="#cjsz-5">创建特定数组</button></li><li class="tab"><button type="button" data-href="#cjsz-6">随机数组</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="cjsz-1"><div class="note blue simple"><p><code>np.array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0)</code><br>参数说明：</p><ul><li><code>object</code>：可以是python原生序列类型，如（嵌套）列表、（嵌套）元组等，也可以是<code>ndarray</code>类型及其子类，函数默认行为总是会返回<code>object</code>的（深）拷贝副本，两者占据完全不同的内存</li><li><code>dtype</code>：设置数组元素的数据类型，缺省时会根据<code>object</code>的类型自行确定</li><li><code>copy</code>：控制当<code>object</code>为<code>ndarray</code>类型或其子类<code>matrix</code>时是否进行（深）复制的行为，设为<code>False</code>，如果<code>object</code>是<code>ndarray</code>类型，将直接返回<code>object</code>自身（即满足<code>is</code>判断），如果<code>object</code>是<code>matrix</code>类型，则浅拷贝，修改任意一方都会体现在对方，且只有当<code>subok</code>置为<code>True</code>时才会返回<code>object</code>自身</li><li><code>order</code>：指定数组在内存中的布局，有两种不同的风格（C或Fortran），<code>C</code>为行主方向（譬如一个二维数组，在内存中依次存储数组的每一行），<code>F</code>为列主方向（譬如一个二维数组，在内存中依次存储数组的每一列），如果<code>object</code>非<code>ndarray</code>类型，可取值就是<code>C</code>（默认）或者<code>F</code>，否则，还可以取值<code>A</code>或<code>K</code>，所创建的数组<code>order</code>由以下规则确定：<!-- https://www.zhihu.com/question/295285045?sort=created --><div class="dytable"><table><thead><tr><th>order</th><th>copy=False</th><th>copy=True</th></tr></thead><tr><td>'K'</td><td>和<code>object</code>的<code>order</code>一致</td><td><a href="https://numpy.org/doc/stable/reference/generated/numpy.array.html" class="dyadefaultcolor" title="前半句大意是：保持和object一致的F和C（一个数组可以同时是F布局和C布局，譬如一维数组）布局，后半句啥意思">F & C order preserved, otherwise most similar order</a>（没懂）</td></tr><tr><td>'A'</td><td>和<code>object</code>的<code>order</code>一致</td><td>若<code>object</code>的<code>order</code>为<code>F</code>且非<code>C</code>，则<code>order</code>为<code>F</code>，反之为<code>C</code></td></tr><tr><td>'C'</td><td><code>order</code>为<code>C</code></td><td><code>order</code>为<code>C</code></td></tr><tr><td>'F'</td><td><code>order</code>为<code>F</code></td><td><code>order</code>为<code>F</code></td></tr></table></div></li><li><code>subok</code>：默认情况下将创建的数组强制转换为基类数组对象（<code>ndarray</code>），设为<code>True</code>则返回子类（譬如矩阵类型<code>matrix</code>是<code>ndarray</code>的子类，<code>m=np.matrix('1 2 3; 4 5 6');a=np.array(m,subok=True)</code>，<code>type(a)</code>为<code>numpy.matrixlib.defmatrix.matrix</code>，且<code>issubclass(type(a),np.ndarray)</code>为<code>True</code>）</li><li><code>ndmin</code>：设置最低维度，创建的多维数组至少是<code>ndmin</code>维（譬如<code>object</code>的形状为<code>(2,3)</code>，而<code>ndmin</code>为4，则创建的数组形状为<code>(1,1,2,3)</code>），当<code>object</code>的维度大于此值时，则不管，维度同<code>object</code></li></ul></div><p>注（<code>order</code>参数），给定一个二维数组<code>a=[[1,2,3],[4,5,6]]</code>，如果按照<code>C</code>顺序创建<code>x=np.array(a,order='C')</code>，此时默认的<code>dtype</code>为<code>np.int32</code>，<code>x.itemsize</code>为4，形状<code>x.shape</code>为<code>(2,3)</code>，其在内存中的存储为：<code>|1|2|3|4|5|6|</code>（因为内存总是连续的），每个格子占据4字节大小，其跨度元组<code>x.strides</code>为<code>(12,4)</code>，表示第0维前进到下一个元素需要“跨过”12个字节（如内存中1到4之间的距离），第1维前进到下一个元素需要“跨过”4个字节（如内存中1到2之间的距离），如果是按照<code>F</code>顺序创建<code>y=np.array(a,order='F')</code>，<code>y.itemsize</code>为4，形状<code>y.shape</code>为<code>(2,3)</code>，其在内存中的存储为：<code>|1|4|2|5|3|6|</code>，其跨度元组<code>y.strides</code>为<code>(4,8)</code></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=[[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>]]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.array(a)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b[<span class="number">0</span>,<span class="number">0</span>]=<span class="number">888</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">[[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>], [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>c=np.array(b)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>c[<span class="number">0</span>,<span class="number">0</span>]=<span class="number">999</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">array([[<span class="number">888</span>,   <span class="number">2</span>,   <span class="number">3</span>],</span><br><span class="line">       [  <span class="number">4</span>,   <span class="number">5</span>,   <span class="number">6</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d=np.array(b,copy=<span class="literal">False</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d <span class="keyword">is</span> b</span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d[<span class="number">0</span>,<span class="number">0</span>]=<span class="number">111</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">array([[<span class="number">111</span>,   <span class="number">2</span>,   <span class="number">3</span>],</span><br><span class="line">       [  <span class="number">4</span>,   <span class="number">5</span>,   <span class="number">6</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>e=np.matrix(a)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>e</span><br><span class="line">matrix([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line">        [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>e[<span class="number">0</span>,<span class="number">0</span>]=<span class="number">222</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">[[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>], [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>f=np.array(e,copy=<span class="literal">False</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>f[<span class="number">0</span>,<span class="number">0</span>]=<span class="number">333</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>e</span><br><span class="line">matrix([[<span class="number">333</span>,   <span class="number">2</span>,   <span class="number">3</span>],</span><br><span class="line">        [  <span class="number">4</span>,   <span class="number">5</span>,   <span class="number">6</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>f <span class="keyword">is</span> e</span><br><span class="line"><span class="literal">False</span></span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.copy()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.copy(a, order='K')</code><br>函数说明：<br>深拷贝输入对象<code>a</code>（可以是<code>ndarray</code>也可以是python原生列表等），尽管<code>np.array()</code>可以达到相同的功能，但是<code>np.copy()</code>的函数名更加直截了当，即复制一个数组对象，通常直接在<code>ndarray</code>对象上调用（<code>ndarray.copy()</code>）</p></div></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="cjsz-2"><div class="note blue simple"><p><code>np.asarray(a, dtype=None, order=None)</code><br>函数说明：<br>作用也是将输入<code>a</code>转换为一个<code>ndarray</code>对象，除了比<code>np.array()</code>少了很多控制参数，最大的区别是，当<code>a</code>是<code>ndarray</code>对象时，将返回自身，如果<code>a</code>是列表、元组等，则还是深拷贝，但当<code>a</code>是<code>matrix</code>对象，则浅拷贝，此时虽然不满足<code>is</code>判断，但是修改任意一方，都会体现在对方，换句话说，<code>np.asarray()</code>相当于<code>np.array()</code>的参数<code>copy</code>置为<code>False</code>时的版本</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=[[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>]]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.array(a)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>c=np.asarray(b)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b <span class="keyword">is</span> c</span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d=np.matrix(<span class="string">&#x27;1 2 3;4 5 6&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>e=np.asarray(d)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d <span class="keyword">is</span> e</span><br><span class="line"><span class="literal">False</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>e[<span class="number">0</span>,<span class="number">0</span>]=<span class="number">666</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>d</span><br><span class="line">matrix([[<span class="number">666</span>,   <span class="number">2</span>,   <span class="number">3</span>],</span><br><span class="line">        [  <span class="number">4</span>,   <span class="number">5</span>,   <span class="number">6</span>]])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="cjsz-3"><div class="note blue simple"><p><code>np.fromiter(iterable, dtype, count=-1)</code><br>函数说明：<br>将一个一维的可迭代（序列）对象<code>iterable</code>转为一维数组并返回，如果（序列）元素也是序列，则只能自定义结构化数据类型，否则出错。注意参数<code>dtype</code>是必填参数，<code>count</code>参数用于决定读取序列的多少个元素，默认值<code>-1</code>表示全部读取。须知，<code>np.array()</code>仅能将<span title="An array, any object exposing the array interface, an object whose __array__ method returns an array, or any (nested) sequence."><code>array_like</code></span>对象转换为<code>ndarray</code>，如列表等，如果是生成器等或其他自定义可迭代对象则无法转换</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>g=(i <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">5</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.array(g)</span><br><span class="line">array(&lt;generator <span class="built_in">object</span> &lt;genexpr&gt; at <span class="number">0x00000239D28B0728</span>&gt;, dtype=<span class="built_in">object</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.fromiter(g,dtype=<span class="string">&#x27;i&#x27;</span>,count=<span class="number">3</span>)</span><br><span class="line">array([<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>], dtype=int32)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>n=[(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>),(<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>)]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.array(n)</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.fromiter(n,dtype=<span class="string">&#x27;i&#x27;</span>)</span><br><span class="line">Traceback (most recent call last):</span><br><span class="line">  File <span class="string">&quot;&lt;stdin&gt;&quot;</span>, line <span class="number">1</span>, <span class="keyword">in</span> &lt;module&gt;</span><br><span class="line">ValueError: setting an array element <span class="keyword">with</span> a sequence.</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.fromiter(n,dtype=np.dtype([(<span class="string">&#x27;col1&#x27;</span>,<span class="string">&#x27;i1&#x27;</span>),(<span class="string">&#x27;col2&#x27;</span>,<span class="string">&#x27;i1&#x27;</span>),(<span class="string">&#x27;col3&#x27;</span>,<span class="string">&#x27;i1&#x27;</span>)])) <span class="comment">#参见numpy structured arrays</span></span><br><span class="line">array([(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>), (<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>)],</span><br><span class="line">      dtype=[(<span class="string">&#x27;col1&#x27;</span>, <span class="string">&#x27;i1&#x27;</span>), (<span class="string">&#x27;col2&#x27;</span>, <span class="string">&#x27;i1&#x27;</span>), (<span class="string">&#x27;col3&#x27;</span>, <span class="string">&#x27;i1&#x27;</span>)])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="cjsz-4"><div class="note blue simple"><p><code>np.fromfunction(function, shape, dtype=float)</code><br>函数说明：<br><code>function</code>函数可接受参数个数应等于<code>shape</code>形状元组的长度（假设<code>shape</code>长度为<code>n</code>，则表示<code>function</code>是一个<code>n</code>元函数），同时<code>shape</code>也是将要创建的数组的形状。以二维为例，<code>shape=(m,n)</code>，则<code>function</code>是一个二元函数，创建的数组记作<code>a</code>，则有<code>a[i,j]=function(i,j)</code>。更一般的，对<code>shape=(k1,k2,k3...kn)</code>来说，<code>fromfunction()</code>将返回一个<code>n</code>维数组对象<code>a</code>，第<code>i</code>维的长度为<code>ki</code>，<code>a[i1,i2,...,in]</code>的值就是<code>function(i1,i2,...,in)</code></p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#(3,4)形二维数组位置坐标</span></span><br><span class="line">y,x=np.meshgrid(<span class="built_in">range</span>(<span class="number">4</span>),<span class="built_in">range</span>(<span class="number">3</span>))</span><br><span class="line"><span class="built_in">print</span>(list2structarray(np.rollaxis(np.stack([x,y]),<span class="number">0</span>,<span class="number">3</span>),<span class="string">&#x27;i4,i4&#x27;</span>)) <span class="comment">#list2structarray()函数定义见numpy structured arrays</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#设二元函数f(x,y)=x*y</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">x,y</span>):</span><br><span class="line">    <span class="keyword">return</span> x*y</span><br><span class="line"><span class="built_in">print</span>(np.fromfunction(f,(<span class="number">3</span>,<span class="number">4</span>)))</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">[[(0, 0) (0, 1) (0, 2) (0, 3)]</span></span><br><span class="line"><span class="string"> [(1, 0) (1, 1) (1, 2) (1, 3)]</span></span><br><span class="line"><span class="string"> [(2, 0) (2, 1) (2, 2) (2, 3)]]</span></span><br><span class="line"><span class="string">[[0. 0. 0. 0.]</span></span><br><span class="line"><span class="string"> [0. 1. 2. 3.]</span></span><br><span class="line"><span class="string"> [0. 2. 4. 6.]]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;间隙等于1太大？希望缩小至1/m，则：</span></span><br><span class="line"><span class="string">def f(i1,i2,...,in):</span></span><br><span class="line"><span class="string">    i1/=m</span></span><br><span class="line"><span class="string">    ...</span></span><br><span class="line"><span class="string">    in/=m</span></span><br><span class="line"><span class="string">    ...</span></span><br><span class="line"><span class="string">相应的shape也应成倍增大，fromfunction(f,(m*k1,m*k2,...,m*kn))</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="comment">#举个一维的例子，设一维函数：f(x)=x^2，要求画出在x轴[0,8]区间上的图像，采样间隔设为1/5，相较于间隔为1时的图像将显得更为光滑</span></span><br><span class="line">y=np.fromfunction(<span class="keyword">lambda</span> x:(x/<span class="number">5</span>)**<span class="number">2</span>,(<span class="number">8</span>*<span class="number">5</span>,))</span><br><span class="line">x=[i/<span class="number">5</span> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">8</span>*<span class="number">5</span>)]</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line">plt.plot(x,y)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="cjsz-5"><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.arange()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.arange([start,] stop[, step,], dtype=None)</code><br>函数说明：<br>类似于python内置的<code>range()</code>函数，区别在于，<code>range()</code>不接受浮点数作为参数，只接受整数类型，而<code>np.arange()</code>允许浮点数作为参数，一般说来两者都是在左闭右开的数值范围内产生均匀间隔的值，但<code>np.arange()</code>由于允许接受浮点型参数，受计算精度影响得到的结果有可能是左闭右闭的，譬如<code>np.arange(3,3.2,0.1)</code>的结果是<code>[3.0,3.1,3.2]</code>，而<code>np.arange(3,3.3,0.1)</code>的结果却又是<code>[3.0,3.1,3.2]</code>，具体原因不明</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.arange(<span class="number">5</span>)</span><br><span class="line">array([<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.arange(<span class="number">2</span>,<span class="number">7</span>)</span><br><span class="line">array([<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.arange(<span class="number">2.3</span>,<span class="number">4.1</span>,<span class="number">0.3</span>)</span><br><span class="line">array([<span class="number">2.3</span>, <span class="number">2.6</span>, <span class="number">2.9</span>, <span class="number">3.2</span>, <span class="number">3.5</span>, <span class="number">3.8</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.arange(<span class="number">3</span>,<span class="number">3.2</span>,<span class="number">0.1</span>)</span><br><span class="line">array([<span class="number">3.</span> , <span class="number">3.1</span>, <span class="number">3.2</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">range</span>(<span class="number">5</span>)</span><br><span class="line"><span class="built_in">range</span>(<span class="number">0</span>, <span class="number">5</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">list</span>(_)</span><br><span class="line">[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">list</span>(<span class="built_in">range</span>(<span class="number">2</span>,<span class="number">7</span>))</span><br><span class="line">[<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">list</span>(<span class="built_in">range</span>(<span class="number">2.3</span>,<span class="number">4.1</span>,<span class="number">0.3</span>))</span><br><span class="line">Traceback (most recent call last):</span><br><span class="line">  File <span class="string">&quot;&lt;stdin&gt;&quot;</span>, line <span class="number">1</span>, <span class="keyword">in</span> &lt;module&gt;</span><br><span class="line">TypeError: <span class="string">&#x27;float&#x27;</span> <span class="built_in">object</span> cannot be interpreted <span class="keyword">as</span> an integer</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.linspace()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)</code><br>函数说明：<br>和<code>np.arange()</code>的区别：<code>np.arange()</code>通过指定开始值、终值和步长创建一个等差的一维数组，得到的结果中是不包含终值的，而<code>np.linspace()</code>则是通过指定开始值、终值和元素个数创建等差的一维数组，并且可以通过<code>endpoint</code>参数指定是否包含终值，默认值为<code>True</code>即表示包含终值，参数<code>retstep</code>为<code>True</code>时，将返回一个元组，第一个元素是生成的等差数组，第二个元素则是差值或者说间距</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.linspace(<span class="number">0</span>,<span class="number">1</span>,<span class="number">12</span>)</span><br><span class="line">array([<span class="number">0.</span>        , <span class="number">0.09090909</span>, <span class="number">0.18181818</span>, <span class="number">0.27272727</span>, <span class="number">0.36363636</span>,</span><br><span class="line">       <span class="number">0.45454545</span>, <span class="number">0.54545455</span>, <span class="number">0.63636364</span>, <span class="number">0.72727273</span>, <span class="number">0.81818182</span>,</span><br><span class="line">       <span class="number">0.90909091</span>, <span class="number">1.</span>        ])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.linspace(<span class="number">0</span>,<span class="number">1</span>,<span class="number">12</span>,endpoint=<span class="literal">False</span>,retstep=<span class="literal">True</span>)</span><br><span class="line">(array([<span class="number">0.</span>        , <span class="number">0.08333333</span>, <span class="number">0.16666667</span>, <span class="number">0.25</span>      , <span class="number">0.33333333</span>,</span><br><span class="line">       <span class="number">0.41666667</span>, <span class="number">0.5</span>       , <span class="number">0.58333333</span>, <span class="number">0.66666667</span>, <span class="number">0.75</span>      ,</span><br><span class="line">       <span class="number">0.83333333</span>, <span class="number">0.91666667</span>]), <span class="number">0.08333333333333333</span>)</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.logspace()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)</code><br>函数说明：<br>该函数用于创建一个一维的对数等比数组，计算过程是这样的：首先将除<code>base</code>以外的参数（暂且假设<code>endpoint</code>为<code>True</code>）全部传递给<code>np.linspace()</code>函数创建一个等差数列<code>[start,start+Δ,start+2·Δ,...,start+(num-1)·Δ]</code>（其中<code>Δ</code>为差值，满足条件<code>start+(num-1)·Δ=stop</code>），然后据此创建等比数列：<code>[base^start,base^(start+Δ),base^(start+2·Δ),...base^(stop)]</code>，公比为<code>base^Δ</code></p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.logspace(<span class="number">0</span>,<span class="number">5</span>,<span class="number">5</span>)</span><br><span class="line">array([<span class="number">1.00000000e+00</span>, <span class="number">1.77827941e+01</span>, <span class="number">3.16227766e+02</span>, <span class="number">5.62341325e+03</span>,</span><br><span class="line">       <span class="number">1.00000000e+05</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.linspace(<span class="number">0</span>,<span class="number">5</span>,<span class="number">5</span>)</span><br><span class="line">array([<span class="number">0.</span>  , <span class="number">1.25</span>, <span class="number">2.5</span> , <span class="number">3.75</span>, <span class="number">5.</span>  ])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="number">10</span>**_</span><br><span class="line">array([<span class="number">1.00000000e+00</span>, <span class="number">1.77827941e+01</span>, <span class="number">3.16227766e+02</span>, <span class="number">5.62341325e+03</span>,</span><br><span class="line">       <span class="number">1.00000000e+05</span>])</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.geomspace()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.geomspace(start, stop, num=50, endpoint=True, dtype=None)</code><br>函数说明：<br>该函数用于创建一个一维的指数等比数组，其返回（暂且假设<code>endpoint</code>为<code>True</code>）：<code>[start^1,start^(1+Δ),start^(1+2·Δ),...,start^(1+(num-1)·Δ)]</code>（其中<code>Δ</code>满足<code>start^(1+(num-1)·Δ)=stop</code>），公比为<code>start^Δ</code>，可以对比<code>np.logspace()</code>，<code>np.logspace()</code>需要指定等比数列取对数后的等差数列的首项和末项，而<code>np.geomspace()</code>则需要指定等比数列本身的首项和末项</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#np.geomspace()的输出取底为start的对数后将得到一个等差数列[1,1+Δ,1+2·Δ,...,1+(num-1)·Δ]</span></span><br><span class="line"><span class="comment">#设start=3，Δ=1，num=10，则stop=start^(1+(num-1)·Δ)=59049</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.geomspace(<span class="number">3</span>,<span class="number">59049</span>,<span class="number">10</span>)</span><br><span class="line">array([<span class="number">3.0000e+00</span>, <span class="number">9.0000e+00</span>, <span class="number">2.7000e+01</span>, <span class="number">8.1000e+01</span>, <span class="number">2.4300e+02</span>,</span><br><span class="line">       <span class="number">7.2900e+02</span>, <span class="number">2.1870e+03</span>, <span class="number">6.5610e+03</span>, <span class="number">1.9683e+04</span>, <span class="number">5.9049e+04</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.log10(_)/np.log10(<span class="number">3</span>) <span class="comment">#换底公式：log_a(b)=log_10(b)/log_10(a)，含义为：以a为底b的对数等于以10为底b的对数除以以10为底a的对数</span></span><br><span class="line">array([ <span class="number">1.</span>,  <span class="number">2.</span>,  <span class="number">3.</span>,  <span class="number">4.</span>,  <span class="number">5.</span>,  <span class="number">6.</span>,  <span class="number">7.</span>,  <span class="number">8.</span>,  <span class="number">9.</span>, <span class="number">10.</span>])</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.empty()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.empty(shape, dtype=float, order='C')</code><br>函数说明：<br>创建形状为<code>shape</code>的空数组，并以随机值填充（所谓“空”是指数组中没有任何有效值，这和<code>np.zeros()</code>不同，0是有效值）</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.empty((<span class="number">2</span>,<span class="number">3</span>))</span><br><span class="line">array([[<span class="number">6.23042070e-307</span>, <span class="number">5.11798224e-307</span>, <span class="number">1.37961370e-306</span>],</span><br><span class="line">       [<span class="number">4.22795269e-307</span>, <span class="number">9.34609790e-307</span>, <span class="number">1.06101441e-312</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.empty((<span class="number">2</span>,<span class="number">3</span>)) <span class="comment">#同一形状每次生成的结果是相同的</span></span><br><span class="line">array([[<span class="number">6.23042070e-307</span>, <span class="number">5.11798224e-307</span>, <span class="number">1.37961370e-306</span>],</span><br><span class="line">       [<span class="number">4.22795269e-307</span>, <span class="number">9.34609790e-307</span>, <span class="number">1.06101441e-312</span>]])</span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.empty_like()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.empty_like(a, dtype=None, order='K', subok=True)</code><br>函数说明：<br>创建形状、类型同<code>a</code>的空数组，但仍可通过<code>dtype</code>参数指定类型</p></div></div></div></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.zeros()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.zeros(shape, dtype=float, order='C')</code><br>函数说明：<br>创建形状为<code>shape</code>的零数组</p></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.zeros_like()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.zeros_like(a, dtype=None, order='K', subok=True)</code><br>函数说明：<br>创建形状、类型同<code>a</code>的零数组，但仍可通过<code>dtype</code>参数指定类型</p></div></div></div></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.ones()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.ones(shape, dtype=None, order='C')</code><br>函数说明：<br>创建形状为<code>shape</code>的全1数组</p></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.ones_like()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.ones_like(a, dtype=None, order='K', subok=True)</code><br>函数说明：<br>创建形状、类型同<code>a</code>的全1数组，但仍可通过<code>dtype</code>参数指定类型</p></div></div></div></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.full()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.full(shape, fill_value, dtype=None, order='C')</code><br>函数说明：<br>用指定的值<code>fill_value</code>填充一个形状为<code>shape</code>的多维数组</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.full((<span class="number">2</span>,<span class="number">3</span>),<span class="number">8</span>)</span><br><span class="line">array([[<span class="number">8</span>, <span class="number">8</span>, <span class="number">8</span>],</span><br><span class="line">       [<span class="number">8</span>, <span class="number">8</span>, <span class="number">8</span>]])</span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.full_like()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.full_like(a, fill_value, dtype=None, order='K', subok=True)</code><br>函数说明：<br>用指定的值填充与给定数组<code>a</code>形状、类型相同的多维数组，但仍可通过<code>dtype</code>参数指定类型</p></div></div></div></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.eye()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.eye(N, M=None, k=0, dtype=&lt;class 'float'&gt;, order='C')</code><br>函数说明：<br>能够用于创建单位矩阵（二维<code>ndarray</code>对象，对角线元素值为1，其余为0），<code>N</code>指定行数，<code>M</code>指定列数（缺省情况下<code>M=N</code>），参数<code>k</code>（整型）用于指定“主对角线”的偏移量，当为负数时，向左方偏移，为正数时向右方偏移</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.eye(<span class="number">3</span>)</span><br><span class="line">array([[<span class="number">1.</span>, <span class="number">0.</span>, <span class="number">0.</span>],</span><br><span class="line">       [<span class="number">0.</span>, <span class="number">1.</span>, <span class="number">0.</span>],</span><br><span class="line">       [<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">1.</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.eye(<span class="number">3</span>,<span class="number">5</span>)</span><br><span class="line">array([[<span class="number">1.</span>, <span class="number">0.</span>, <span class="number">0.</span>, <span class="number">0.</span>, <span class="number">0.</span>],</span><br><span class="line">       [<span class="number">0.</span>, <span class="number">1.</span>, <span class="number">0.</span>, <span class="number">0.</span>, <span class="number">0.</span>],</span><br><span class="line">       [<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">1.</span>, <span class="number">0.</span>, <span class="number">0.</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.eye(<span class="number">3</span>,<span class="number">5</span>,k=<span class="number">2</span>)</span><br><span class="line">array([[<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">1.</span>, <span class="number">0.</span>, <span class="number">0.</span>],</span><br><span class="line">       [<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">0.</span>, <span class="number">1.</span>, <span class="number">0.</span>],</span><br><span class="line">       [<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">0.</span>, <span class="number">0.</span>, <span class="number">1.</span>]])</span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.identity()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.identity(n, dtype=None)</code><br>函数说明：<br>专门用于创建形状为<code>(n,n)</code>的单位矩阵</p></div></div></div></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="cjsz-6"><p>如果希望能够重现生成的伪随机数，只需要设置相同的随机种子<code>np.random.seed(seed)</code>（参数<code>seed</code>是一个整数，范围限于<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">[</mo><mn>0</mn><mo separator="true">,</mo><msup><mn>2</mn><mn>32</mn></msup><mo>−</mo><mn>1</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[0,2^{32}-1]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">3</span><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">]</span></span></span></span>），如：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.seed(<span class="number">20210527</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.rand(<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line">array([[<span class="number">0.94230071</span>, <span class="number">0.7680507</span> , <span class="number">0.41849498</span>],</span><br><span class="line">       [<span class="number">0.23640405</span>, <span class="number">0.28777521</span>, <span class="number">0.53928407</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.rand(<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line">array([[<span class="number">0.03641101</span>, <span class="number">0.3279482</span> , <span class="number">0.48352279</span>],</span><br><span class="line">       [<span class="number">0.77410674</span>, <span class="number">0.50404311</span>, <span class="number">0.4773902</span> ]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.seed(<span class="number">20210527</span>) <span class="comment">#种下同一种子，随机函数结果一致</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.rand(<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line">array([[<span class="number">0.94230071</span>, <span class="number">0.7680507</span> , <span class="number">0.41849498</span>],</span><br><span class="line">       [<span class="number">0.23640405</span>, <span class="number">0.28777521</span>, <span class="number">0.53928407</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.rand(<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line">array([[<span class="number">0.03641101</span>, <span class="number">0.3279482</span> , <span class="number">0.48352279</span>],</span><br><span class="line">       [<span class="number">0.77410674</span>, <span class="number">0.50404311</span>, <span class="number">0.4773902</span> ]])</span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.random.rand()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.random.rand(d0, d1, ..., dn)</code><br>函数说明：<br>生成形状为<code>(d0,d1,...,dn)</code>的数组，并使用<code>[0.0, 1.0)</code>上均匀分布的随机样本（浮点数）填充它，如果没有给定任何参数，则返回单个浮点数</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.rand()</span><br><span class="line"><span class="number">0.6258827101037749</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.rand(<span class="number">5</span>)</span><br><span class="line">array([<span class="number">0.62735357</span>, <span class="number">0.88232692</span>, <span class="number">0.23067855</span>, <span class="number">0.59308295</span>, <span class="number">0.22785762</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.rand(<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line">array([[<span class="number">0.98092414</span>, <span class="number">0.32172215</span>, <span class="number">0.94662153</span>],</span><br><span class="line">       [<span class="number">0.27608697</span>, <span class="number">0.89694515</span>, <span class="number">0.55163334</span>]])</span><br></pre></td></tr></table></figure><p>如果希望生成的范围区间介于<code>[a,b)</code>，可以通过<code>(b - a) * np.random.rand(...) + a</code>得到：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a,b=<span class="number">3</span>,<span class="number">5</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>(b - a) * np.random.rand(<span class="number">5</span>) + a</span><br><span class="line">array([<span class="number">3.55059992</span>, <span class="number">4.37930213</span>, <span class="number">3.03409387</span>, <span class="number">4.17120523</span>, <span class="number">3.04866055</span>])</span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.random.sample()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.random.random_sample(size=None)</code><br>函数说明：<br>作用同<code>np.random.rand()</code>，只不过传入的是<code>size</code>形状参数，若<code>size</code>为<code>None</code>，则返回单个随机浮点数</p></div></div></div></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.random.randn()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.random.randn(d0, d1, ..., dn)</code><br>函数说明：<br>生成形状为<code>(d0,d1,...,dn)</code>的数组，并使用服从标准正态分布（均值为0，方差为1）的随机样本（浮点数，钟型曲线在-1.96～+1.96范围下的面积等于0.95）填充它，如果没有给定任何参数，则返回单个浮点数</p></div><p>如果你希望构造服从均值为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>μ</mi></mrow><annotation encoding="application/x-tex">\mu</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">μ</span></span></span></span>、方差为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>σ</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">\sigma^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span>的随机数（组），记作<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi><mo>∼</mo><mi>N</mi><mo stretchy="false">(</mo><mi>μ</mi><mo separator="true">,</mo><msup><mi>σ</mi><mn>2</mn></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">X\sim N(\mu,\sigma^2)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∼</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mopen">(</span><span class="mord mathnormal">μ</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>，根据标准化有<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mi>X</mi><mo>−</mo><mi>μ</mi></mrow><mi>σ</mi></mfrac><mo>∼</mo><mi>N</mi><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\frac{X-\mu}{\sigma}\sim N(0,1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.269439em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.924439em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">σ</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.446108em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.07847em;">X</span><span class="mbin mtight">−</span><span class="mord mathnormal mtight">μ</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∼</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span>，设<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Z</mi><mo>=</mo><mfrac><mrow><mi>X</mi><mo>−</mo><mi>μ</mi></mrow><mi>σ</mi></mfrac></mrow><annotation encoding="application/x-tex">Z=\frac{X-\mu}{\sigma}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">Z</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.269439em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.924439em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">σ</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.446108em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.07847em;">X</span><span class="mbin mtight">−</span><span class="mord mathnormal mtight">μ</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>，即有<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Z</mi><mo>∼</mo><mi>N</mi><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">Z\sim N(0,1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">Z</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∼</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi><mo>=</mo><mi>σ</mi><mi>Z</mi><mo>+</mo><mi>μ</mi><mo>∼</mo><mi>N</mi><mo stretchy="false">(</mo><mi>μ</mi><mo separator="true">,</mo><msup><mi>σ</mi><mn>2</mn></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">X=\sigma Z+\mu\sim N(\mu,\sigma^2)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mord mathnormal" style="margin-right:0.07153em;">Z</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">μ</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∼</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mopen">(</span><span class="mord mathnormal">μ</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>，因此可以通过<code>σ*np.random.randn(...)+μ</code>来获取这样的<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi></mrow><annotation encoding="application/x-tex">X</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span></span></span></span>：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line">μ,σ=<span class="number">2</span>,<span class="number">3</span></span><br><span class="line">X=σ*np.random.randn(<span class="number">10000</span>)+μ <span class="comment">#或者X=np.random.normal(loc=μ, scale=σ,size=(10000,))</span></span><br><span class="line"><span class="built_in">print</span>((μ-<span class="number">3</span>*σ,μ+<span class="number">3</span>*σ)) <span class="comment">#(-7, 11) #“3σ原则”</span></span><br><span class="line">plt.hist(X,<span class="number">80</span>,density=<span class="literal">True</span>,color=<span class="string">&#x27;g&#x27;</span>,edgecolor=<span class="string">&#x27;k&#x27;</span>)</span><br><span class="line">plt.title(<span class="string">f&#x27;$X\sim N(\mu,\sigma^2),\mu=<span class="subst">&#123;μ&#125;</span>,\sigma^2=<span class="subst">&#123;σ**<span class="number">2</span>&#125;</span>$&#x27;</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.random.standard_normal()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.random.standard_normal(size=None)</code><br>函数说明：<br>作用同<code>np.random.randn()</code>，区别好像仅在于<code>np.standard_normal()</code>允许接受形状元组作为参数</p></div></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.random.normal()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.random.normal(loc=0.0, scale=1.0, size=None)</code><br>函数说明：<br>生成服从均值为<code>loc</code>（<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>μ</mi></mrow><annotation encoding="application/x-tex">\mu</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">μ</span></span></span></span>）、标准差为<code>scale</code>（<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>σ</mi></mrow><annotation encoding="application/x-tex">\sigma</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span></span></span></span>）的正态分布的形状为<code>size</code>的数组</p></div></div></div></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.random.randint()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.random.randint(low, high=None, size=None, dtype='l')</code><br>函数说明：<br>生成一个数值介于<code>[low,high)</code>左闭右开区间的形状为<code>size</code>的整型随机数组。特别地，当只传入参数<code>low</code>且参数<code>high</code>为<code>None</code>时，生成的随机整数将处于<code>[0,low)</code>区间，当<code>size</code>形状为<code>None</code>时，将返回一个标量，而当<code>size</code>是一个整数时，将返回一个长度为<code>size</code>的一维数组</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.randint(<span class="number">1</span>) <span class="comment">#显然此时总是返回0</span></span><br><span class="line"><span class="number">0</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.randint(-<span class="number">10</span>,<span class="number">10</span>,size=(<span class="number">5</span>,))</span><br><span class="line">array([ <span class="number">1</span>, -<span class="number">6</span>, -<span class="number">8</span>, -<span class="number">9</span>,  <span class="number">5</span>])</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.random.choice()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.random.choice(a, size=None, replace=True, p=None)</code><br>函数说明：<br>用于从给定的一组数据<code>a</code>中产生随机样本（或依照指定概率<code>p</code>），采样数目由<code>size</code>参数决定（数目为<code>np.cumprod(a.shape)[-1]</code>），并组织成形状为<code>size</code>的数组返回<br>参数说明：</p><ul><li><code>a</code>：可以是一维数组（也可以是python列表）或者整型标量，特别地，当其为标量时，相当于<code>a=np.arange(a)</code>，表示从<code>[0,a)</code>中随机采样</li><li><code>size</code>：指定输出数组形状，也可以指定为一个整型标量，如<code>n</code>，相当于<code>size=(n,)</code>，如果<code>size</code>为<code>None</code>，函数将输出单个样本</li><li><code>replace</code>：决定采样中是否有重复值（<code>True</code>表示可以重复），只有当<code>size</code>小于等于<code>len(a)</code>的时候（采样数小于全部样本数），才能置为<code>False</code></li><li><code>p</code>：一个一维序列，对应着<code>a</code>中每个样本的概率分布，如果没有指定，则使用均匀分布</li></ul></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.choice([<span class="number">3</span>,<span class="number">5</span>,<span class="number">7</span>,<span class="number">9</span>,<span class="number">12</span>,<span class="number">67</span>,<span class="number">1</span>,<span class="number">19</span>],size=<span class="number">10</span>)</span><br><span class="line">array([ <span class="number">1</span>,  <span class="number">3</span>,  <span class="number">1</span>,  <span class="number">3</span>, <span class="number">67</span>, <span class="number">19</span>, <span class="number">67</span>, <span class="number">12</span>,  <span class="number">5</span>,  <span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.choice(<span class="number">5</span>, <span class="number">3</span>)</span><br><span class="line">array([<span class="number">1</span>, <span class="number">2</span>, <span class="number">2</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.choice(<span class="number">5</span>, <span class="number">3</span>, p=[<span class="number">0.1</span>, <span class="number">0</span>, <span class="number">0.3</span>, <span class="number">0.6</span>, <span class="number">0</span>])</span><br><span class="line">array([<span class="number">0</span>, <span class="number">3</span>, <span class="number">3</span>], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.choice(<span class="number">5</span>, <span class="number">3</span>, replace=<span class="literal">False</span>)</span><br><span class="line">array([<span class="number">2</span>, <span class="number">1</span>, <span class="number">0</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.choice(<span class="number">5</span>, <span class="number">8</span>, replace=<span class="literal">False</span>)</span><br><span class="line">Traceback (most recent call last):</span><br><span class="line">  File <span class="string">&quot;&lt;stdin&gt;&quot;</span>, line <span class="number">1</span>, <span class="keyword">in</span> &lt;module&gt;</span><br><span class="line">  File <span class="string">&quot;mtrand.pyx&quot;</span>, line <span class="number">1166</span>, <span class="keyword">in</span> mtrand.RandomState.choice</span><br><span class="line">ValueError: Cannot take a larger sample than population when <span class="string">&#x27;replace=False&#x27;</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.choice([<span class="string">&#x27;pooh&#x27;</span>, <span class="string">&#x27;rabbit&#x27;</span>, <span class="string">&#x27;piglet&#x27;</span>, <span class="string">&#x27;Christopher&#x27;</span>], <span class="number">5</span>, p=[<span class="number">0.5</span>, <span class="number">0.1</span>, <span class="number">0.1</span>, <span class="number">0.3</span>])</span><br><span class="line">array([<span class="string">&#x27;pooh&#x27;</span>, <span class="string">&#x27;rabbit&#x27;</span>, <span class="string">&#x27;Christopher&#x27;</span>, <span class="string">&#x27;pooh&#x27;</span>, <span class="string">&#x27;rabbit&#x27;</span>], dtype=<span class="string">&#x27;&lt;U11&#x27;</span>)</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.random.shuffle()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.random.shuffle(x)</code><br>函数说明：<br>沿第0维对数组<code>x</code>（<code>x</code>还可以是python列表，<code>shuffle</code>操作并不会改变其类型）进行“洗牌”（打乱顺序），且为原址操作，函数无返回值</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">10</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.shuffle(a)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([<span class="number">5</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">8</span>, <span class="number">4</span>, <span class="number">6</span>, <span class="number">9</span>, <span class="number">7</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">9</span>).reshape((<span class="number">3</span>,<span class="number">3</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>],</span><br><span class="line">       [<span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.shuffle(a)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=[<span class="string">&#x27;Christopher&#x27;</span>,<span class="string">&#x27;pooh&#x27;</span>,<span class="string">&#x27;rabbit&#x27;</span>,<span class="string">&#x27;pooh&#x27;</span>,<span class="string">&#x27;pooh&#x27;</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.shuffle(a)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">[<span class="string">&#x27;pooh&#x27;</span>, <span class="string">&#x27;rabbit&#x27;</span>, <span class="string">&#x27;Christopher&#x27;</span>, <span class="string">&#x27;pooh&#x27;</span>, <span class="string">&#x27;pooh&#x27;</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">type</span>(a)</span><br><span class="line">&lt;<span class="keyword">class</span> <span class="string">&#x27;list&#x27;</span>&gt;</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.random.permutation()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.random.permutation(x)</code><br>函数说明：<br>功能同<code>np.random.shuffle()</code>，但非原址操作，函数将返回打乱后的数组，<code>x</code>除了可以是python列表，还可以是一个整型参数，相当于对数组<code>np.arange(x)</code>进行shuffle</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=[<span class="string">&#x27;Christopher&#x27;</span>,<span class="string">&#x27;pooh&#x27;</span>,<span class="string">&#x27;rabbit&#x27;</span>,<span class="string">&#x27;pooh&#x27;</span>,<span class="string">&#x27;pooh&#x27;</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.permutation(a)</span><br><span class="line">array([<span class="string">&#x27;pooh&#x27;</span>, <span class="string">&#x27;Christopher&#x27;</span>, <span class="string">&#x27;rabbit&#x27;</span>, <span class="string">&#x27;pooh&#x27;</span>, <span class="string">&#x27;pooh&#x27;</span>], dtype=<span class="string">&#x27;&lt;U11&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">[<span class="string">&#x27;Christopher&#x27;</span>, <span class="string">&#x27;pooh&#x27;</span>, <span class="string">&#x27;rabbit&#x27;</span>, <span class="string">&#x27;pooh&#x27;</span>, <span class="string">&#x27;pooh&#x27;</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.permutation(<span class="number">10</span>)</span><br><span class="line">array([<span class="number">9</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">6</span>, <span class="number">5</span>, <span class="number">8</span>, <span class="number">0</span>, <span class="number">2</span>, <span class="number">7</span>])</span><br></pre></td></tr></table></figure></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="形状重塑">形状重塑</h2><div class="tabs" id="xzcs"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#xzcs-1"><code>np.reshape()</code></button></li><li class="tab"><button type="button" data-href="#xzcs-2"><code>np.resize()</code></button></li><li class="tab"><button type="button" data-href="#xzcs-3"><code>np.swapaxes()</code></button></li><li class="tab"><button type="button" data-href="#xzcs-4"><code>np.transpose()</code></button></li><li class="tab"><button type="button" data-href="#xzcs-5"><code>np.rollaxis()</code></button></li><li class="tab"><button type="button" data-href="#xzcs-6"><code>np.flatten()</code></button></li><li class="tab"><button type="button" data-href="#xzcs-7"><code>np.expand_dims()</code></button></li><li class="tab"><button type="button" data-href="#xzcs-8"><code>np.squeeze()</code></button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="xzcs-1"><div class="note blue simple"><p><code>np.reshape(a, newshape, order='C')</code><br>函数说明：<br>将多维数组<code>a</code>变形为<code>newshape</code>，一般是直接在<code>ndarray</code>对象上调用该方法，形式为<code>ndarray.reshape(newshape,order='C')</code>（此时既可以直接传递形状元组，也可以将其解包为多个位置参数传递）， 需要注意的是，<code>reshape()</code>函数返回的新数组其实是原多维数组对象<code>a</code>的“视图”，所谓“视图”，即你对视图的修改将原封不动地反映在原始数据中，因此对<code>reshape()</code>函数返回的“新数组”的修改将影响到<code>a</code>（如果<code>a</code>是python对象自然不会影响），如果不希望变形操作影响原数组，则采用<code>np.resize()</code>替代，或者先进行一次深拷贝（<code>np.copy()</code>）<br>参数说明：</p><ul><li><code>a</code>：除了是numpy多维数组对象，也可以是python列表</li><li><code>newshape</code>：设原始形状为<code>(d1,d2,...,dn)</code>，<code>newshape</code>为<code>(d1',d2',...,dn')</code>，其必须满足<code>d1d2...dn=d1'd2'...dn'</code>，且<code>newshape</code>形状元组中允许出现一个<code>-1</code>作为缺省，对应维度的轴长将被自动计算</li><li><code>order</code>：可取值为<code>{'C', 'F', 'A'}</code>，<a href="https://www.zhihu.com/question/295285045?sort=created" class="dyadefaultcolor">按照指定风格从原数组中读取数据以及填充新数组，并将此风格设为新数组的内存布局</a></li></ul></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.reshape([[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>]],(-<span class="number">1</span>,))</span><br><span class="line">array([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">6</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.reshape((<span class="number">2</span>,<span class="number">3</span>))</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.reshape(<span class="number">2</span>,<span class="number">3</span>) <span class="comment">#手动将newshape解包为多个位置参数传递</span></span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.reshape(*(<span class="number">2</span>,<span class="number">3</span>)) <span class="comment">#利用*自动将newshape解包为多个位置参数传递</span></span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_[<span class="number">0</span>,<span class="number">0</span>]=<span class="number">666</span> <span class="comment">#对视图的修改将反映在原数组上，反之对原数组的修改也可以通过视图实时显示</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([<span class="number">666</span>,   <span class="number">1</span>,   <span class="number">2</span>,   <span class="number">3</span>,   <span class="number">4</span>,   <span class="number">5</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a = np.array([[<span class="number">0</span>, <span class="number">1</span>],</span><br><span class="line"><span class="meta">... </span>              [<span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line"><span class="meta">... </span>              [<span class="number">4</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>o=np.reshape(a, (<span class="number">2</span>, <span class="number">3</span>), order=<span class="string">&#x27;F&#x27;</span>) <span class="comment">#第一步，按照列主序读取数组a，得到|0|2|4|1|3|5|，然后第二步，按照列主序顺序将其依次存储在(2,3)形的新数组中，对于第二步的实施其实很简单，首先新数组在内存中连续存储的就是|0|2|4|1|3|5|，只需要再设置一下flags为列主序以及跨度元组strides即可，而strides显然为(4,8)，这也变相告诉了计算机新数组各维度大小，即(2,3)</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>o</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">4</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">1</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>o.flags</span><br><span class="line">  C_CONTIGUOUS : <span class="literal">False</span></span><br><span class="line">  F_CONTIGUOUS : <span class="literal">True</span></span><br><span class="line">  OWNDATA : <span class="literal">False</span></span><br><span class="line">  WRITEABLE : <span class="literal">True</span></span><br><span class="line">  ALIGNED : <span class="literal">True</span></span><br><span class="line">  WRITEBACKIFCOPY : <span class="literal">False</span></span><br><span class="line">  UPDATEIFCOPY : <span class="literal">False</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>o.strides</span><br><span class="line">(<span class="number">4</span>, <span class="number">8</span>)</span><br></pre></td></tr></table></figure><p>需要注意的是，如果<code>reshape()</code>的<code>order</code>参数为<code>C</code>，只有在<code>a</code>为C-contiguous（<code>a.flags['C_CONTIGUOUS']</code>为<code>True</code>）时才会返回视图，否则返回深拷贝，反之，若<code>order</code>为<code>F</code>，则只有在<code>a</code>为F-contiguous（<code>a.flags['F_CONTIGUOUS']</code>为<code>True</code>）时才会返回视图，否则返回深拷贝</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.array([[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>]],order=<span class="string">&#x27;F&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.flags</span><br><span class="line">  C_CONTIGUOUS : <span class="literal">False</span></span><br><span class="line">  F_CONTIGUOUS : <span class="literal">True</span></span><br><span class="line">  OWNDATA : <span class="literal">True</span></span><br><span class="line">  WRITEABLE : <span class="literal">True</span></span><br><span class="line">  ALIGNED : <span class="literal">True</span></span><br><span class="line">  WRITEBACKIFCOPY : <span class="literal">False</span></span><br><span class="line">  UPDATEIFCOPY : <span class="literal">False</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.reshape(<span class="number">3</span>,<span class="number">2</span>)</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">4</span>],</span><br><span class="line">       [<span class="number">5</span>, <span class="number">6</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_[<span class="number">0</span>,<span class="number">0</span>]=<span class="number">666</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.reshape(<span class="number">3</span>,<span class="number">2</span>,order=<span class="string">&#x27;F&#x27;</span>)</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">5</span>],</span><br><span class="line">       [<span class="number">4</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">6</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_[<span class="number">0</span>,<span class="number">0</span>]=<span class="number">666</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">666</span>,   <span class="number">2</span>,   <span class="number">3</span>],</span><br><span class="line">       [  <span class="number">4</span>,   <span class="number">5</span>,   <span class="number">6</span>]])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="xzcs-2"><div class="note blue simple"><p><code>np.resize(a, newshape)</code><br>函数说明：<br>作用同<code>np.reshape()</code>，最大的区别在于<code>np.resize()</code>返回的是一个完全独立的新数组，对其所做的一切修改不会影响原数组，且此时允许指定错误的或者说不匹配的<code>newshape</code>，多余的部分会被丢弃，不足的部分则会复用已有的数据补全（描述能力有限，具体见示例），另外，虽然也可以直接在<code>ndarray</code>对象上调用<code>resize()</code>方法，但<code>ndarray.resize(...)</code>是原址操作，无返回值（返回值为无意义的<code>None</code>），此时<code>newshape</code>形状元组中禁止使用代表缺省维数的<code>-1</code>（<code>np.resize(...)</code>虽然不直接报错，但是结果也不正确，也必须禁止），不匹配的<code>newshape</code>则会导致错误</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">10</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.resize(a,(<span class="number">2</span>,-<span class="number">1</span>))</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_[<span class="number">0</span>,<span class="number">0</span>]=<span class="number">666</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.resize((<span class="number">2</span>,-<span class="number">1</span>))</span><br><span class="line">Traceback (most recent call last):</span><br><span class="line">  File <span class="string">&quot;&lt;stdin&gt;&quot;</span>, line <span class="number">1</span>, <span class="keyword">in</span> &lt;module&gt;</span><br><span class="line">ValueError: negative dimensions <span class="keyword">not</span> allowed</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.resize(a,(<span class="number">8</span>,)) <span class="comment">#丢弃部分</span></span><br><span class="line">array([<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.resize(a,(<span class="number">2</span>,<span class="number">9</span>)) <span class="comment">#不足补全，不足部分将不断重复ndarray.flat中的数据</span></span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>],</span><br><span class="line">       [<span class="number">9</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.resize((<span class="number">2</span>,<span class="number">9</span>))</span><br><span class="line">Traceback (most recent call last):</span><br><span class="line">  File <span class="string">&quot;&lt;stdin&gt;&quot;</span>, line <span class="number">1</span>, <span class="keyword">in</span> &lt;module&gt;</span><br><span class="line">ValueError: cannot resize an array that references <span class="keyword">or</span> <span class="keyword">is</span> referenced</span><br><span class="line">by another array <span class="keyword">in</span> this way.  Use the resize function</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="xzcs-3"><div class="note blue simple"><p><code>np.swapaxes(a, axis1, axis2)</code><br>函数说明：<br>用于交换多维数组的某两个维度，函数返回原数组的“视图”，可以直接在<code>ndarray</code>上调用<code>ndarray.swapaxes(axis1,axis2)</code></p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>x = np.array([[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.swapaxes(x,<span class="number">0</span>,<span class="number">1</span>)</span><br><span class="line">array([[<span class="number">1</span>],</span><br><span class="line">       [<span class="number">2</span>],</span><br><span class="line">       [<span class="number">3</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_[<span class="number">0</span>,<span class="number">0</span>]=<span class="number">666</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x</span><br><span class="line">array([[<span class="number">666</span>,   <span class="number">2</span>,   <span class="number">3</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x = np.array([[[<span class="number">0</span>,<span class="number">1</span>],[<span class="number">2</span>,<span class="number">3</span>]],[[<span class="number">4</span>,<span class="number">5</span>],[<span class="number">6</span>,<span class="number">7</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.swapaxes(x,<span class="number">0</span>,<span class="number">2</span>) <span class="comment">#同np.swapaxes(x,2,0)</span></span><br><span class="line">array([[[<span class="number">0</span>, <span class="number">4</span>],</span><br><span class="line">        [<span class="number">2</span>, <span class="number">6</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">1</span>, <span class="number">5</span>],</span><br><span class="line">        [<span class="number">3</span>, <span class="number">7</span>]]])</span><br></pre></td></tr></table></figure><p>以二维或三维数组为例，将其分别放到二维平面和三维空间坐标系中，<code>swapaxes()</code>操作相当于交换某两个轴的名称</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">from</span> mpl_toolkits.mplot3d.art3d <span class="keyword">import</span> Poly3DCollection,Line3DCollection</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">plt.rcParams[<span class="string">&#x27;font.sans-serif&#x27;</span>]=[<span class="string">&#x27;SimHei&#x27;</span>]</span><br><span class="line">plt.rcParams[<span class="string">&#x27;axes.unicode_minus&#x27;</span>]=<span class="literal">False</span></span><br><span class="line"></span><br><span class="line">x=np.array([[[<span class="number">0</span>,<span class="number">1</span>],[<span class="number">2</span>,<span class="number">3</span>]],[[<span class="number">4</span>,<span class="number">5</span>],[<span class="number">6</span>,<span class="number">7</span>]]])</span><br><span class="line">y=np.swapaxes(x,<span class="number">0</span>,<span class="number">2</span>)</span><br><span class="line"></span><br><span class="line">points=[(<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>),(<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>),(<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>),(<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>),(<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>),(<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>),(<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>),(<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>)]</span><br><span class="line">faces=[(<span class="number">0</span>,<span class="number">4</span>,<span class="number">7</span>,<span class="number">3</span>,<span class="number">0</span>),(<span class="number">0</span>,<span class="number">1</span>,<span class="number">5</span>,<span class="number">4</span>,<span class="number">0</span>),(<span class="number">1</span>,<span class="number">2</span>,<span class="number">6</span>,<span class="number">5</span>,<span class="number">1</span>),(<span class="number">2</span>,<span class="number">3</span>,<span class="number">7</span>,<span class="number">6</span>,<span class="number">2</span>),(<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">4</span>),(<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">0</span>)]</span><br><span class="line">plots=[[points[point_num] <span class="keyword">for</span> point_num <span class="keyword">in</span> face] <span class="keyword">for</span> face <span class="keyword">in</span> faces]</span><br><span class="line"></span><br><span class="line">line3d=Line3DCollection(plots)</span><br><span class="line">ax1=plt.subplot(<span class="number">121</span>,projection=<span class="string">&#x27;3d&#x27;</span>)</span><br><span class="line">ax1.add_collection3d(line3d)</span><br><span class="line">plt.xlabel(<span class="string">&#x27;轴0&#x27;</span>)</span><br><span class="line">plt.ylabel(<span class="string">&#x27;轴1&#x27;</span>)</span><br><span class="line">plt.gca().set_zlabel(<span class="string">&#x27;轴2&#x27;</span>)</span><br><span class="line">plt.xticks([])</span><br><span class="line">plt.yticks([])</span><br><span class="line">plt.gca().set_zticks([])</span><br><span class="line"></span><br><span class="line">line3d=Line3DCollection(plots)</span><br><span class="line">ax2=plt.subplot(<span class="number">122</span>,projection=<span class="string">&#x27;3d&#x27;</span>)</span><br><span class="line">ax2.add_collection3d(line3d)</span><br><span class="line">plt.xlabel(<span class="string">&#x27;轴2&#x27;</span>) <span class="comment">#只需要交换两根轴的名称即可</span></span><br><span class="line">plt.ylabel(<span class="string">&#x27;轴1&#x27;</span>)</span><br><span class="line">plt.gca().set_zlabel(<span class="string">&#x27;轴0&#x27;</span>)</span><br><span class="line">plt.xticks([])</span><br><span class="line">plt.yticks([])</span><br><span class="line">plt.gca().set_zticks([])</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> pos <span class="keyword">in</span> points:</span><br><span class="line">    ax1.text(*pos,<span class="string">f&#x27;<span class="subst">&#123;x[pos]&#125;</span>:<span class="subst">&#123;pos&#125;</span>&#x27;</span>,color=<span class="string">&#x27;red&#x27;</span> <span class="keyword">if</span> pos==(<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>) <span class="keyword">else</span> <span class="string">&#x27;black&#x27;</span>)</span><br><span class="line">    ax2.text(*pos,<span class="string">f&#x27;<span class="subst">&#123;x[pos]&#125;</span>:<span class="subst">&#123;pos&#125;</span>&#x27;</span>,color=<span class="string">&#x27;red&#x27;</span> <span class="keyword">if</span> pos==(<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>) <span class="keyword">else</span> <span class="string">&#x27;black&#x27;</span>)</span><br><span class="line">plt.suptitle(<span class="string">f&#x27;交换数组x的0轴和2轴：y=np.swapaxes(x,0,2)\n x=<span class="subst">&#123;x&#125;</span>\n y=<span class="subst">&#123;y&#125;</span>&#x27;</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="xzcs-4"><div class="note blue simple"><p><code>np.transpose(a, axes=None)</code><br>函数说明：<br>区别于<code>np.swapaxes()</code>只能一次性交换两个维度，该操作用于同时变换<code>n</code>个轴的名称（<code>n≤a.ndim</code>），<code>axes</code>即是一个长度为<code>a.ndim</code>的元组，里面是要转换的维度序号，当其为<code>None</code>时，相当于<code>np.transpose(a,axes=list(reversed(range(len(a.shape)))))</code>，此时可以用于二维数组的转置操作，函数返回的是原数组的“视图”（<code>ndarray</code>对象的<code>T</code>属性返回的也是“视图”），也可以直接在<code>ndarray</code>上调用<code>ndarray.transpose(axes=None)</code>。另外轴变换后得到的数组内存布局将会发生变化，譬如一个二维的列主序数组，transpose后会变成行主序</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>x=np.array([[[<span class="number">0</span>,<span class="number">1</span>],[<span class="number">2</span>,<span class="number">3</span>]],[[<span class="number">4</span>,<span class="number">5</span>],[<span class="number">6</span>,<span class="number">7</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x.transpose() <span class="comment">#显然对于三维数组，axes为None时等同于x.swapaxes(0,2)</span></span><br><span class="line">array([[[<span class="number">0</span>, <span class="number">4</span>],</span><br><span class="line">        [<span class="number">2</span>, <span class="number">6</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">1</span>, <span class="number">5</span>],</span><br><span class="line">        [<span class="number">3</span>, <span class="number">7</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x.transpose((<span class="number">2</span>,<span class="number">1</span>,<span class="number">0</span>))</span><br><span class="line">array([[[<span class="number">0</span>, <span class="number">4</span>],</span><br><span class="line">        [<span class="number">2</span>, <span class="number">6</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">1</span>, <span class="number">5</span>],</span><br><span class="line">        [<span class="number">3</span>, <span class="number">7</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.array([[<span class="number">0</span>,<span class="number">1</span>],[<span class="number">2</span>,<span class="number">3</span>],[<span class="number">4</span>,<span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.transpose()</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">2</span>, <span class="number">4</span>],</span><br><span class="line">       [<span class="number">1</span>, <span class="number">3</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.T <span class="comment">#多维数组的.T属性返回的也是“视图”，所有视图之间实时共享数据</span></span><br><span class="line">array([[<span class="number">0</span>, <span class="number">2</span>, <span class="number">4</span>],</span><br><span class="line">       [<span class="number">1</span>, <span class="number">3</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_[<span class="number">0</span>,<span class="number">0</span>]=<span class="number">666</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">666</span>,   <span class="number">1</span>],</span><br><span class="line">       [  <span class="number">2</span>,   <span class="number">3</span>],</span><br><span class="line">       [  <span class="number">4</span>,   <span class="number">5</span>]])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="xzcs-5"><div class="note blue simple"><p><code>np.rollaxis(a, axis, start=0)</code><br>函数说明：<br>向前或向后滚动特定的轴<code>axis</code>到一个特定位置<code>start</code>，在滚动过程中，其它轴的相对位置不会改变，默认是将某根轴向前滚动到位置0，即变成轴0，向前滚动时要滚动到位置几就将<code>start</code>置为几即可，譬如将轴2滚动到轴1位置处，即为<code>np.rollaxis(a,2,1)</code>，但是向后滚动时需要人为加1，譬如一个三维数组，要将轴0滚动到原本的轴2位置处，应当是<code>np.rollaxis(a,0,3)</code>而非<code>np.rollaxis(a,0,2)</code>，函数返回的仍是“视图”，但是<code>ndarray</code>对象上并无<code>rollaxis()</code>方法属性</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">24</span>).reshape(<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">        [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">        [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>, <span class="number">15</span>],</span><br><span class="line">        [<span class="number">16</span>, <span class="number">17</span>, <span class="number">18</span>, <span class="number">19</span>],</span><br><span class="line">        [<span class="number">20</span>, <span class="number">21</span>, <span class="number">22</span>, <span class="number">23</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.rollaxis(a,<span class="number">0</span>,<span class="number">3</span>)</span><br><span class="line">array([[[ <span class="number">0</span>, <span class="number">12</span>],</span><br><span class="line">        [ <span class="number">1</span>, <span class="number">13</span>],</span><br><span class="line">        [ <span class="number">2</span>, <span class="number">14</span>],</span><br><span class="line">        [ <span class="number">3</span>, <span class="number">15</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">4</span>, <span class="number">16</span>],</span><br><span class="line">        [ <span class="number">5</span>, <span class="number">17</span>],</span><br><span class="line">        [ <span class="number">6</span>, <span class="number">18</span>],</span><br><span class="line">        [ <span class="number">7</span>, <span class="number">19</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">8</span>, <span class="number">20</span>],</span><br><span class="line">        [ <span class="number">9</span>, <span class="number">21</span>],</span><br><span class="line">        [<span class="number">10</span>, <span class="number">22</span>],</span><br><span class="line">        [<span class="number">11</span>, <span class="number">23</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">3</span>, <span class="number">4</span>, <span class="number">2</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.rollaxis(a,<span class="number">0</span>,<span class="number">2</span>)</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">        [<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>, <span class="number">15</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">        [<span class="number">16</span>, <span class="number">17</span>, <span class="number">18</span>, <span class="number">19</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>],</span><br><span class="line">        [<span class="number">20</span>, <span class="number">21</span>, <span class="number">22</span>, <span class="number">23</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">3</span>, <span class="number">2</span>, <span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.rollaxis(a,<span class="number">2</span>,<span class="number">1</span>)</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">4</span>,  <span class="number">8</span>],</span><br><span class="line">        [ <span class="number">1</span>,  <span class="number">5</span>,  <span class="number">9</span>],</span><br><span class="line">        [ <span class="number">2</span>,  <span class="number">6</span>, <span class="number">10</span>],</span><br><span class="line">        [ <span class="number">3</span>,  <span class="number">7</span>, <span class="number">11</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">12</span>, <span class="number">16</span>, <span class="number">20</span>],</span><br><span class="line">        [<span class="number">13</span>, <span class="number">17</span>, <span class="number">21</span>],</span><br><span class="line">        [<span class="number">14</span>, <span class="number">18</span>, <span class="number">22</span>],</span><br><span class="line">        [<span class="number">15</span>, <span class="number">19</span>, <span class="number">23</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">4</span>, <span class="number">3</span>)</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="xzcs-6"><div class="note blue simple"><p><code>ndarray.flatten(order='C')</code><br>函数说明：<br>用于“一维化”多维数组（降维），返回的是原数组的深拷贝</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.array([[<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>],[<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.flatten()</span><br><span class="line">array([<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.flatten(<span class="string">&#x27;F&#x27;</span>)</span><br><span class="line">array([<span class="number">0</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">4</span>, <span class="number">2</span>, <span class="number">5</span>])</span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.ravel()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.ravel(a, order='C')</code><br>函数说明：<br>作用同<code>ndarray.flatten()</code>，区别在于<code>np.ravel()</code>（或<code>ndarray.ravel()</code>）返回的是原数组的“视图”，不过我更倾向于使用<code>ndarray.reshape(-1)</code></p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">6</span>).reshape(<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=a.ravel()</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b[<span class="number">0</span>]=<span class="number">666</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">array([<span class="number">666</span>,   <span class="number">1</span>,   <span class="number">2</span>,   <span class="number">3</span>,   <span class="number">4</span>,   <span class="number">5</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">666</span>,   <span class="number">1</span>,   <span class="number">2</span>],</span><br><span class="line">       [  <span class="number">3</span>,   <span class="number">4</span>,   <span class="number">5</span>]])</span><br></pre></td></tr></table></figure><p>需要注意的是，如果<code>ravel()</code>的<code>order</code>参数为<code>C</code>，只有在<code>a</code>为<span title="a.flags['C_CONTIGUOUS']=True">C-contiguous</span>时才会返回视图，否则返回深拷贝，反之，如果<code>order</code>为<code>F</code>，则只有在<code>a</code>为<span title="a.flags['F_CONTIGUOUS']=True">Fortran-contiguous</span>时才会返回视图，否则返回深拷贝</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">6</span>).reshape(<span class="number">2</span>,<span class="number">3</span>,order=<span class="string">&#x27;F&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">2</span>, <span class="number">4</span>],</span><br><span class="line">       [<span class="number">1</span>, <span class="number">3</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=a.ravel()</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b[<span class="number">0</span>]=<span class="number">666</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">array([<span class="number">666</span>,   <span class="number">2</span>,   <span class="number">4</span>,   <span class="number">1</span>,   <span class="number">3</span>,   <span class="number">5</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">2</span>, <span class="number">4</span>],</span><br><span class="line">       [<span class="number">1</span>, <span class="number">3</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.flags[<span class="string">&#x27;C_CONTIGUOUS&#x27;</span>]</span><br><span class="line"><span class="literal">False</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.flags[<span class="string">&#x27;F_CONTIGUOUS&#x27;</span>]</span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=a.ravel(order=<span class="string">&#x27;F&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b[<span class="number">0</span>]=<span class="number">888</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">array([<span class="number">888</span>,   <span class="number">1</span>,   <span class="number">2</span>,   <span class="number">3</span>,   <span class="number">4</span>,   <span class="number">5</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">888</span>,   <span class="number">2</span>,   <span class="number">4</span>],</span><br><span class="line">       [  <span class="number">1</span>,   <span class="number">3</span>,   <span class="number">5</span>]])</span><br></pre></td></tr></table></figure></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="xzcs-7"><div class="note blue simple"><p><code>np.expand_dims(a, axis)</code><br>函数说明：<br>该函数用于扩展数组<code>a</code>的维度，一次只能增加一个维度，新增维度的轴长为1，函数将返回原数组的“视图”，比较常见的是扩充第一个或最后一个维度，但一般会用<code>a[None,...]</code>或<code>a[...,None]</code>简写达到同样的效果</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">6</span>).reshape(<span class="number">2</span>,-<span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.expand_dims(a,<span class="number">0</span>)</span><br><span class="line">array([[[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">        [<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.expand_dims(a,<span class="number">1</span>)</span><br><span class="line">array([[[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">1</span>, <span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.expand_dims(a,<span class="number">2</span>)</span><br><span class="line">array([[[<span class="number">0</span>],</span><br><span class="line">        [<span class="number">1</span>],</span><br><span class="line">        [<span class="number">2</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">3</span>],</span><br><span class="line">        [<span class="number">4</span>],</span><br><span class="line">        [<span class="number">5</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.expand_dims(a,-<span class="number">1</span>) <span class="comment">#扩充最后一个维度时，axis参数可以写-1</span></span><br><span class="line">array([[[<span class="number">0</span>],</span><br><span class="line">        [<span class="number">1</span>],</span><br><span class="line">        [<span class="number">2</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">3</span>],</span><br><span class="line">        [<span class="number">4</span>],</span><br><span class="line">        [<span class="number">5</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="literal">None</span>,...]</span><br><span class="line">array([[[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">        [<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="literal">None</span>,:,:]</span><br><span class="line">array([[[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">        [<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[:,<span class="literal">None</span>,:]</span><br><span class="line">array([[[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">1</span>, <span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[...,<span class="literal">None</span>]</span><br><span class="line">array([[[<span class="number">0</span>],</span><br><span class="line">        [<span class="number">1</span>],</span><br><span class="line">        [<span class="number">2</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">3</span>],</span><br><span class="line">        [<span class="number">4</span>],</span><br><span class="line">        [<span class="number">5</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[:,:,<span class="literal">None</span>]</span><br><span class="line">array([[[<span class="number">0</span>],</span><br><span class="line">        [<span class="number">1</span>],</span><br><span class="line">        [<span class="number">2</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">3</span>],</span><br><span class="line">        [<span class="number">4</span>],</span><br><span class="line">        [<span class="number">5</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">24</span>).reshape(<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[:,<span class="literal">None</span>,:,<span class="literal">None</span>,:] <span class="comment">#还可以同时写多个None，用于同时扩充多个维度</span></span><br><span class="line">array([[[[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>]],</span><br><span class="line"></span><br><span class="line">         [[ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>]],</span><br><span class="line"></span><br><span class="line">         [[ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]]]],</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">       [[[[<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>, <span class="number">15</span>]],</span><br><span class="line"></span><br><span class="line">         [[<span class="number">16</span>, <span class="number">17</span>, <span class="number">18</span>, <span class="number">19</span>]],</span><br><span class="line"></span><br><span class="line">         [[<span class="number">20</span>, <span class="number">21</span>, <span class="number">22</span>, <span class="number">23</span>]]]]])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="xzcs-8"><div class="note blue simple"><p><code>np.squeeze(a, axis=None)</code><br>函数说明：<br>该函数默认用于删除多维数组<code>a</code>中的所有轴长为1的维度（<code>axis</code>为<code>None</code>），函数将返回原数组的“视图”，也可以直接在<code>ndarray</code>对象上调用该方法，也可以指定<code>axis</code>参数，即删除指定的维度（但该维度的轴长必须为1）</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">24</span>).reshape(<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=a[:,<span class="literal">None</span>,:,<span class="literal">None</span>,:]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b.squeeze().shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b.squeeze(<span class="number">1</span>).shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">4</span>)</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="数组切片和索引">数组切片和索引</h2><div class="tabs" id="szsy"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#szsy-1">切片和索引</button></li><li class="tab"><button type="button" data-href="#szsy-2">高级索引</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="szsy-1"><p>先说说（数值）索引，对数组（单个）元素的索引是通过数字下标进行定位的，譬如<code>a[i][j]</code>表示沿着数组<code>a</code>的第0轴获取第<code>i</code>个位置上的元素，记作<code>b=a[i]</code>，然后再沿着数组<code>b</code>的第0轴获取第<code>j</code>个位置上的元素，就得到<code>a[i][j]</code>，简写形式为<code>a[i,j]</code>，其中逗号用于分隔不同的维度（事实上，不管是此处的数值索引还是后面的切片索引，对于不足的维度说明，譬如<code>a[i]</code>就是只给出了第0维的索引说明，总是会自动在最后使用<code>...</code>对其他维度的索引说明进行补全，譬如<code>a[i]</code>即等同于<code>a[i,...]</code>，<code>...</code>含义后面会说），而切片索引可以同时访问多个元素，有两种使用方式（同原生python），一是创建切片对象<code>slice(start,end,stride)</code>（切片范围不包括<code>end</code>在内），二是使用冒号语法<code>start:end:stride</code>（同样切片范围不包括<code>end</code>在内）替代<code>slice</code>对象，譬如<code>a[i:j]</code>，同样，可以使用逗号作为不同维度的间隔，譬如<code>a[i:j,i:j]</code>表示沿着数组<code>a</code>的第0轴获取第<code>i</code>个位置到第<code>j</code>个位置之前的所有元素，记作<code>b=a[i:j]</code>，然后再沿着数组<code>b</code>的第1轴获取第<code>i</code>个位置到第<code>j</code>个位置之前的所有元素，即<code>b[:,i:j]</code>，要知道每进行一次数值索引，返回的数组维数都会减一，而切片索引的返回结果则始终保持维数不变（许多numpy函数都有一个叫做<code>keepdims</code>的参数，就是这个意思），因此上面<code>a[i][j]</code>的描述也可以改成：首先沿着数组<code>a</code>的第0轴获取第<code>i</code>个位置上的元素且保持维数不变，即得到<code>b=a[i:i+1]</code>，然后再沿着数组<code>b</code>的第1轴获取第<code>j</code>个位置上的元素且保持维数不变，即<code>b[:,j:j+1]</code>，所得相当于<code>[[a[i,j]]]</code>，数值索引和切片索引自然可以混用，譬如<code>a[:,i]</code>（表示获取数组<code>a</code>的第<code>i</code>列），另外，numpy索引还支持<code>...</code>（<code>ellipse</code>对象，须知其在索引中只能出现一次，原生python索引不支持）用于替代一个或多个（逗号间隔且连续的）<code>:</code>，譬如<code>a[i:j,:,:]</code>可以替换成<code>a[i:j,...]</code>、<code>a[:,:,i:j]</code>可以替换成<code>a[...,i:j]</code>、<code>a[:]</code>可以替换成<code>a[...]</code>、<code>a[:,i]</code>可以替换成<code>a[...,i]</code></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=<span class="built_in">list</span>(<span class="built_in">range</span>(<span class="number">10</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[::-<span class="number">1</span>] <span class="comment">#原生python切片索引示例</span></span><br><span class="line">[<span class="number">9</span>, <span class="number">8</span>, <span class="number">7</span>, <span class="number">6</span>, <span class="number">5</span>, <span class="number">4</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">0</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">2</span>:<span class="number">10</span>:<span class="number">2</span>]</span><br><span class="line">[<span class="number">2</span>, <span class="number">4</span>, <span class="number">6</span>, <span class="number">8</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">5</span>:<span class="number">7</span>]</span><br><span class="line">[<span class="number">5</span>, <span class="number">6</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">12</span>).reshape(<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">       [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">       [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">1</span>,<span class="number">2</span>]</span><br><span class="line"><span class="number">6</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">0</span>:<span class="number">2</span>:<span class="number">1</span>]</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[::-<span class="number">1</span>]</span><br><span class="line">array([[ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>],</span><br><span class="line">       [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">       [ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[:<span class="number">2</span>,<span class="number">1</span>:-<span class="number">1</span>] <span class="comment">#numpy切片索引，由于是多个维度，可以通过逗号间隔不同维度的切片</span></span><br><span class="line">array([[<span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">5</span>, <span class="number">6</span>]])</span><br><span class="line">&gt;&gt; a[<span class="built_in">slice</span>(<span class="number">0</span>,<span class="number">2</span>),<span class="built_in">slice</span>(<span class="number">1</span>,-<span class="number">1</span>)]</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">5</span>, <span class="number">6</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[...,<span class="number">2</span>]</span><br><span class="line">array([ <span class="number">2</span>,  <span class="number">6</span>, <span class="number">10</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[...,<span class="number">2</span>:<span class="number">2</span>+<span class="number">1</span>] <span class="comment">#要保持维度一致，有时我会这样写：a[...,[2]]，但这并不总是正确，譬如a[0:0+1,[1]]和a[[0],[1]]结果就有区别，后者的维度依旧没有保持住，可以参见高级索引，前者属于花式索引（一维花式索引和切片索引混用），后者则属于全坐标索引，实际上，在所有维度都是数值索引的情况下，不能全都用括号括起来以进行维度保持，因为全坐标索引返回的结果总是一维数组，除非你在进行全坐标索引的时候指定形状信息，a[[[0]],[[1]]]，索引坐标放在一个(1,1)形状的数组中，返回的索引结果也会按照相应形状组织</span></span><br><span class="line">array([[ <span class="number">2</span>],</span><br><span class="line">       [ <span class="number">6</span>],</span><br><span class="line">       [<span class="number">10</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">0</span>,::]</span><br><span class="line">array([<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">0</span>,...]</span><br><span class="line">array([<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br></pre></td></tr></table></figure><p>Numpy索引还支持一个特殊对象<code>None</code>，之前在介绍<code>np.expand_dims()</code>时顺带展示了相关用法，这里再简单回顾一下：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">10</span>).reshape((<span class="number">2</span>,-<span class="number">1</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_=a[...,<span class="literal">None</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">5</span>, <span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_=a[:,<span class="literal">None</span>] <span class="comment">#None是多出来的一个维度，而a是一个二维数组，因此维度说明应有两处，此处仅出现一处，因此在最后加上...变成a[:,None,...]，也就是a[:,None,:]</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">1</span>, <span class="number">5</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_=a[:,<span class="literal">None</span>,:]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">1</span>, <span class="number">5</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_=a[:,<span class="literal">None</span>,...]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">1</span>, <span class="number">5</span>)</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szsy-2"><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>全坐标索引</span></div>    <div class="hide-content"><p>这算是最简单的一种索引方式，需要将全部待索引元素的坐标按不同维度分别组织起来（过程相当于<code>zip(坐标点1,坐标点2,...)</code>），称为坐标分量（此时是一维的序列），然后将其以逗号间隔用于索引，索引结果将被存放于一个一维数组中，譬如一个二维数组，全坐标索引形式为：<code>ndarray[行索引序列,列索引序列]</code></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.array([[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>],[<span class="number">11</span>,<span class="number">12</span>,<span class="number">13</span>]]) <span class="comment">#要索引第一行第一个元素、第二行第二个元素以及第三行第三个元素，这三个元素的位置坐标分别为：(0,0)、(1,1)、(2,2)</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x=[<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>] <span class="comment">#行索引序列</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>y=[<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>] <span class="comment">#列索引序列</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[x,y] <span class="comment">#全坐标索引总是返回一个一维数组</span></span><br><span class="line">array([ <span class="number">1</span>,  <span class="number">7</span>, <span class="number">13</span>])</span><br></pre></td></tr></table></figure><p>上述坐标分量被放在一个一维列表（数组）中，返回的结果也是一维的，事实上，你可以将坐标分量放在嵌套列表（多维数组）中，索引结果也会按照相应的形状结构组织：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">1</span>,<span class="number">28</span>).reshape((<span class="number">3</span>,<span class="number">3</span>,-<span class="number">1</span>)) <span class="comment">#这是一个(3,3,3)形状的数组，八个顶点上的坐标分别为：(0,0,0),(0,2,0),(0,0,2),(0,2,2),(2,0,0),(2,2,0),(2,0,2),(2,2,2)，下面索引之</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x=[<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>] <span class="comment">#0轴分量</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>y=[<span class="number">0</span>,<span class="number">2</span>,<span class="number">0</span>,<span class="number">2</span>,<span class="number">0</span>,<span class="number">2</span>,<span class="number">0</span>,<span class="number">2</span>] <span class="comment">#1轴分量</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z=[<span class="number">0</span>,<span class="number">0</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">2</span>,<span class="number">2</span>] <span class="comment">#2轴分量</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[x,y,z]</span><br><span class="line">array([ <span class="number">1</span>,  <span class="number">7</span>,  <span class="number">3</span>,  <span class="number">9</span>, <span class="number">19</span>, <span class="number">25</span>, <span class="number">21</span>, <span class="number">27</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x=[[[<span class="number">0</span>,<span class="number">0</span>],[<span class="number">0</span>,<span class="number">0</span>]],[[<span class="number">2</span>,<span class="number">2</span>],[<span class="number">2</span>,<span class="number">2</span>]]] <span class="comment">#如果我们希望返回的8个顶点仍以原始相对位置展示，即索引返回(2,2,2)的三维数组，只需要将坐标分量组织为(2,2,2)形状</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>y=[[[<span class="number">0</span>,<span class="number">0</span>],[<span class="number">2</span>,<span class="number">2</span>]],[[<span class="number">0</span>,<span class="number">0</span>],[<span class="number">2</span>,<span class="number">2</span>]]]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z=[[[<span class="number">0</span>,<span class="number">2</span>],[<span class="number">0</span>,<span class="number">2</span>]],[[<span class="number">0</span>,<span class="number">2</span>],[<span class="number">0</span>,<span class="number">2</span>]]]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[x,y,z]</span><br><span class="line">array([[[ <span class="number">1</span>,  <span class="number">3</span>],</span><br><span class="line">        [ <span class="number">7</span>,  <span class="number">9</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">19</span>, <span class="number">21</span>],</span><br><span class="line">        [<span class="number">25</span>, <span class="number">27</span>]]])</span><br></pre></td></tr></table></figure><p>假设给出了待索引的所有坐标点，可以通过<code>zip()</code>函数简化全坐标分量序列的构造：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">1</span>,<span class="number">28</span>).reshape((<span class="number">3</span>,<span class="number">3</span>,-<span class="number">1</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>points=[(<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>),(<span class="number">0</span>,<span class="number">2</span>,<span class="number">0</span>),(<span class="number">0</span>,<span class="number">0</span>,<span class="number">2</span>),(<span class="number">0</span>,<span class="number">2</span>,<span class="number">2</span>),(<span class="number">2</span>,<span class="number">0</span>,<span class="number">0</span>),(<span class="number">2</span>,<span class="number">2</span>,<span class="number">0</span>),(<span class="number">2</span>,<span class="number">0</span>,<span class="number">2</span>),(<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>)]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x,y,z=<span class="built_in">zip</span>(*points)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[x,y,z]</span><br><span class="line">array([ <span class="number">1</span>,  <span class="number">7</span>,  <span class="number">3</span>,  <span class="number">9</span>, <span class="number">19</span>, <span class="number">25</span>, <span class="number">21</span>, <span class="number">27</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>pos=<span class="built_in">zip</span>(*points)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[[*pos]] <span class="comment">#标准的全坐标索引形式为ndarray[轴0坐标分量,轴1坐标分量,...]，实践发现在这些所有分量外面再套一层中括号，结果不变，即可以写成ndarray[[轴0坐标分量,轴1坐标分量,...]]，因此此处，[*pos]（*的简化容器添加功能）返回[(0, 0, 0, 0, 2, 2, 2, 2), (0, 2, 0, 2, 0, 2, 0, 2), (0, 0, 2, 2, 0, 0, 2, 2)]，可以直接将其用于全坐标索引，为什么不a[*pos]呢？因为该语法非法。套一层括号结果不变，套两层乃至更多层呢？结果是会变的，实际将变成一种花式索引</span></span><br><span class="line">array([ <span class="number">1</span>,  <span class="number">7</span>,  <span class="number">3</span>,  <span class="number">9</span>, <span class="number">19</span>, <span class="number">25</span>, <span class="number">21</span>, <span class="number">27</span>])</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>布尔索引</span></div>    <div class="hide-content"><p>布尔索引通过构建一个布尔型多维数组（称为“掩码数组”），用于数组元素的过滤（过滤出的元素会被放在一个一维数组中，假设过滤元素是标量，那么返回的将是一维数组，如果过滤元素是向量，则会返回二维数组），譬如条件过滤<code>a[a&gt;0]</code>将返回数组<code>a</code>中所有大于0的元素（<code>a&gt;0</code>可以得到一个与<code>a</code>同形的掩码数组，因而过滤出的元素是标量，最终该布尔索引将返回一个一维数组），须知掩码数组的形状（记为<code>ms</code>，设长度为<code>m</code>）应和待索引数组的形状（记为<code>ns</code>，设长度为<code>n</code>）具有“前向一致性”（我胡诌的名词，一般掩码数组应是<code>ndarray</code>对象，如果是python列表则有可能会出错），即<code>ms</code>应构成<code>ns</code>的前<code>m</code>项，且满足<code>m≤n</code>，譬如<code>ns=(2,3,4)</code>，那么<code>ms</code>只能是<code>(2)</code>、<code>(2,3)</code>或<code>(2,3,4)</code>的其中一种，特别地，当进行一维布尔索引时（指布尔掩码数组是一维的），可以以逗号间隔多个维度，且可以和（单个）数值索引、切片索引混用，但注意只能在其中一个维度上使用布尔掩码（长度需和当前维度的轴长一致），和全坐标索引自然不能混用，另外和（一维）花式索引也不能混用，否则结果错误，具体见下示例：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">10</span>).reshape((<span class="number">2</span>,-<span class="number">1</span>)) <span class="comment">#现给定一个二维数组，输出其中所有大于3的元素</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>],</span><br><span class="line">       [<span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">a</span>): <span class="comment">#手动构建与待索引数组同形的二维布尔数组：对待索引数组中的每一个元素进行判断，符合条件为True，不符合为False</span></span><br><span class="line"><span class="meta">... </span>    s=a.shape</span><br><span class="line"><span class="meta">... </span>    <span class="keyword">return</span> np.array([<span class="literal">True</span> <span class="keyword">if</span> i&gt;<span class="number">3</span> <span class="keyword">else</span> <span class="literal">False</span> <span class="keyword">for</span> i <span class="keyword">in</span> a.reshape((-<span class="number">1</span>))]).reshape(s)</span><br><span class="line">...</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[f(a)]</span><br><span class="line">array([<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a&gt;<span class="number">3</span> <span class="comment">#ndarray对象上的关系运算将返回一个布尔型数组，满足关系的为True，不满足为False</span></span><br><span class="line">array([[<span class="literal">False</span>, <span class="literal">False</span>, <span class="literal">False</span>, <span class="literal">False</span>,  <span class="literal">True</span>],</span><br><span class="line">       [ <span class="literal">True</span>,  <span class="literal">True</span>,  <span class="literal">True</span>,  <span class="literal">True</span>,  <span class="literal">True</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[a&gt;<span class="number">3</span>]</span><br><span class="line">array([<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=[<span class="literal">True</span>,<span class="literal">False</span>] <span class="comment">#待索引数组形状为(2,5)，此掩码数组的形状为(2,)，这是允许的，含义是沿待索引二维数组的0轴进行元素过滤选取，具体的，此处表示第一行符合条件，而第二行不符合条件</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[b]</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">0</span>,[<span class="literal">True</span>,<span class="literal">False</span>,<span class="literal">False</span>,<span class="literal">False</span>,<span class="literal">True</span>]] <span class="comment">#以逗号间隔不同维度的索引，其中第0维是（单个）数值索引，第1维是（一维）布尔索引，如果改成a[[True,True],[True,False,False,False,True]]，结果是没意义的，尽管不会直接报错，因为布尔索引在不同维度上至多只能使用一次，再譬如改成a[[0,1],[True,False,False,False,True]]，返回array([0, 9])结果也是没意义的，第0维上其实是（一维）花式索引，和布尔索引不能混用</span></span><br><span class="line">array([<span class="number">0</span>, <span class="number">4</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[[<span class="literal">True</span>,<span class="literal">False</span>]][:,[<span class="literal">True</span>,<span class="literal">False</span>,<span class="literal">False</span>,<span class="literal">False</span>,<span class="literal">True</span>]] <span class="comment">#如果要对不同维度分别进行布尔索引，应像这样使用，交换顺序也正确，a[:,[True,False,False,False,True]][[True,False]]</span></span><br><span class="line">array([[<span class="number">0</span>, <span class="number">4</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">24</span>).reshape(<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">        [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">        [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>, <span class="number">15</span>],</span><br><span class="line">        [<span class="number">16</span>, <span class="number">17</span>, <span class="number">18</span>, <span class="number">19</span>],</span><br><span class="line">        [<span class="number">20</span>, <span class="number">21</span>, <span class="number">22</span>, <span class="number">23</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[np.array([[<span class="literal">True</span>,<span class="literal">False</span>,<span class="literal">False</span>],[<span class="literal">False</span>,<span class="literal">True</span>,<span class="literal">True</span>]])] <span class="comment">#待索引数组形状为(2,3,4)，布尔掩码数组形状是(2,3)，这是允许的，表示沿着0轴和1轴构成的“面”进行过滤，过滤出的元素是长度为4的一维数组，过滤出的元素将被放在一个一维数组中，因此返回的结果将是(n,4)形状的，其中n是过滤出的元素个数</span></span><br><span class="line">array([[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">       [<span class="number">16</span>, <span class="number">17</span>, <span class="number">18</span>, <span class="number">19</span>],</span><br><span class="line">       [<span class="number">20</span>, <span class="number">21</span>, <span class="number">22</span>, <span class="number">23</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[[[<span class="literal">True</span>,<span class="literal">False</span>,<span class="literal">False</span>],[<span class="literal">False</span>,<span class="literal">True</span>,<span class="literal">True</span>]]] <span class="comment">#同上，只不过掩码数组是list类型，此时出错，而之前如一维的布尔掩码数组则允许是list类型，有点莫名</span></span><br><span class="line">Traceback (most recent call last):</span><br><span class="line">  File <span class="string">&quot;&lt;stdin&gt;&quot;</span>, line <span class="number">1</span>, <span class="keyword">in</span> &lt;module&gt;</span><br><span class="line">IndexError: boolean index did <span class="keyword">not</span> <span class="keyword">match</span> indexed array along dimension <span class="number">0</span>; dimension <span class="keyword">is</span> <span class="number">2</span> but corresponding boolean dimension <span class="keyword">is</span> <span class="number">3</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[[<span class="literal">True</span>,<span class="literal">True</span>],:,[<span class="literal">True</span>,<span class="literal">True</span>,<span class="literal">False</span>,<span class="literal">False</span>]] <span class="comment">#注意这是一个错误示例，输出不符合预期（因为一维布尔索引只能出现一次，不能出现在多个维度上），按理说，由于数组a轴0长度为2，该索引应该相当于a[...,[True,True,False,False]]，观察输出，后者正常</span></span><br><span class="line">array([[ <span class="number">0</span>,  <span class="number">4</span>,  <span class="number">8</span>],</span><br><span class="line">       [<span class="number">13</span>, <span class="number">17</span>, <span class="number">21</span>]])</span><br></pre></td></tr></table></figure><p>使用布尔索引可以“较为方便”地操作“表”结构（其实就是二维或三维的numpy数组，三维即表示“多层叠加的表”），为此，还需要准备有字段数组，用于标识“表”不同维度所代表的信息，譬如下面我们预备构建一个(2,3,3)形的三维数组，其中(3,3)的子数组记录的是所有3个学生3门科目的成绩信息，第0维的2表示期中和期末两个阶段的成绩，另构建三个字段数组，第一个表示“时间”维度信息，第二个表示“学生”维度信息，第三个表示“科目”维度信息：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;学生成绩单</span></span><br><span class="line"><span class="string">                            语文      数学    英语</span></span><br><span class="line"><span class="string">期中：Daiyang：  80       78      70</span></span><br><span class="line"><span class="string">            Muggle:      90       82      86</span></span><br><span class="line"><span class="string">            Huamulan:   87       78      83</span></span><br><span class="line"><span class="string">期末：Daiyang：  78       76      85</span></span><br><span class="line"><span class="string">            Muggle:      88       91      79</span></span><br><span class="line"><span class="string">            Huamulan:   92       89      90</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">scores=np.array([[[<span class="number">80</span>,<span class="number">78</span>,<span class="number">70</span>],[<span class="number">90</span>,<span class="number">82</span>,<span class="number">86</span>],[<span class="number">87</span>,<span class="number">78</span>,<span class="number">83</span>]],</span><br><span class="line">                 [[<span class="number">78</span>,<span class="number">76</span>,<span class="number">85</span>],[<span class="number">88</span>,<span class="number">91</span>,<span class="number">79</span>],[<span class="number">92</span>,<span class="number">89</span>,<span class="number">90</span>]]])</span><br><span class="line"></span><br><span class="line">periods=np.array([<span class="string">&#x27;Midterm&#x27;</span>,<span class="string">&#x27;Endterm&#x27;</span>])</span><br><span class="line">names=np.array([<span class="string">&#x27;Daiyang&#x27;</span>,<span class="string">&#x27;Muggle&#x27;</span>,<span class="string">&#x27;Huamulan&#x27;</span>])</span><br><span class="line">subjects=np.array([<span class="string">&#x27;Chinese&#x27;</span>,<span class="string">&#x27;Math&#x27;</span>,<span class="string">&#x27;English&#x27;</span>])</span><br></pre></td></tr></table></figure><p>要获取Muggle期中的三科成绩：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>scores[periods==<span class="string">&#x27;Midterm&#x27;</span>].squeeze()[names==<span class="string">&#x27;Muggle&#x27;</span>]</span><br><span class="line">array([[<span class="number">90</span>, <span class="number">82</span>, <span class="number">86</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>scores[periods==<span class="string">&#x27;Midterm&#x27;</span>][:,names==<span class="string">&#x27;Muggle&#x27;</span>] <span class="comment">#这种方式看起来更好一点</span></span><br><span class="line">array([[[<span class="number">90</span>, <span class="number">82</span>, <span class="number">86</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>scores[:,names==<span class="string">&#x27;Muggle&#x27;</span>][periods==<span class="string">&#x27;Midterm&#x27;</span>] <span class="comment">#交换顺序也正确</span></span><br><span class="line">array([[[<span class="number">90</span>, <span class="number">82</span>, <span class="number">86</span>]]])</span><br></pre></td></tr></table></figure><p>要获取所有人的期末英语成绩：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>scores[periods==<span class="string">&#x27;Endterm&#x27;</span>][:,:,subjects==<span class="string">&#x27;English&#x27;</span>]</span><br><span class="line">array([[[<span class="number">85</span>],</span><br><span class="line">        [<span class="number">79</span>],</span><br><span class="line">        [<span class="number">90</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>scores[...,subjects==<span class="string">&#x27;English&#x27;</span>][periods==<span class="string">&#x27;Endterm&#x27;</span>]</span><br><span class="line">array([[[<span class="number">85</span>],</span><br><span class="line">        [<span class="number">79</span>],</span><br><span class="line">        [<span class="number">90</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>scores[periods==<span class="string">&#x27;Endterm&#x27;</span>].squeeze().T[subjects==<span class="string">&#x27;English&#x27;</span>]</span><br><span class="line">array([[<span class="number">85</span>, <span class="number">79</span>, <span class="number">90</span>]])</span><br></pre></td></tr></table></figure><p>要获取Muggle期中期末的数学成绩：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>scores[:,names==<span class="string">&#x27;Muggle&#x27;</span>][...,subjects==<span class="string">&#x27;Math&#x27;</span>]</span><br><span class="line">array([[[<span class="number">82</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">91</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>scores.swapaxes(<span class="number">0</span>,<span class="number">1</span>)[names==<span class="string">&#x27;Muggle&#x27;</span>].squeeze().T[subjects==<span class="string">&#x27;Math&#x27;</span>]</span><br><span class="line">array([[<span class="number">82</span>, <span class="number">91</span>]])</span><br></pre></td></tr></table></figure><p>要获取Daiyang和Huamulan期末的语文成绩：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>scores[periods==<span class="string">&#x27;Endterm&#x27;</span>][:,(names==<span class="string">&#x27;Daiyang&#x27;</span>)|(names==<span class="string">&#x27;Huamulan&#x27;</span>)][...,subjects==<span class="string">&#x27;Chinese&#x27;</span>]</span><br><span class="line">array([[[<span class="number">78</span>],</span><br><span class="line">        [<span class="number">92</span>]]])</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>花式索引</span></div>    <div class="hide-content"><p>何为花式索引？设待索引数组<code>a</code>为二维，给定两个整数序列<code>s1</code>和<code>s2</code>，含义上，<code>s1</code>选中了二维数组中的某些行，<code>s2</code>选中了二维数组中的某些列，现要获取这些行列交线的交点所在位置的元素，这就是花式索引，很简单，通过<code>a[np.ix_(s1,s2)]</code>即可获得，所得结果数组形状为<code>(len(s1),len(s2))</code>，换句话说，这两个整数序列<code>s1</code>和<code>s2</code>的笛卡尔积就是将要定位的全部元素的二维位置坐标，再譬如三维数组的花式索引，给定三个整数序列<code>s1</code>、<code>s2</code>、<code>s3</code>，这三个整数序列的笛卡尔积就是将要定位的全部元素的三维位置坐标，可以通过<code>a[np.ix_(s1,s2,s3)]</code>快速获取，返回的数组形状显然就是<code>(len(s1),len(s2),len(s3))</code>，事实上，对于任意一个待索引的<code>n</code>维数组，传入<code>np.ix_()</code>的整数序列数量≤<code>n</code>即可，仍以三维待索引数组<code>a</code>为例（将其视为由诸多一维数组元素构成的二维数组，数组元素<code>a[i][j]</code>即是一个一维数组），<code>a[np.ix_(s1,s2)]</code>表示在轴0和轴1构成的“面”上进行花式索引，由于索引的元素本身就是一维数组，因此该花式索引将返回三维数组，形状为<code>(len(s1),len(s2),a.shape[2])</code>，特别地，当传入<code>np.ix_()</code>的整数序列数量为1时，表示特殊的一维花式索引（由于<code>np.ix_(s,)</code>将返回<code>s</code>本身，所以一维花式索引<code>a[np.ix_(s,)]</code>可以简写成<code>a[s]</code>），此时可以以逗号间隔不同的维度，但是只能在其中一个维度上使用（一维）花式索引，其可以和（单个）数值索引、切片索引混用，和全坐标索引自然不能混用，另外也不能和（一维）布尔索引混用，否则结果错误（整体十分类似于上面介绍的布尔索引）</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">12</span>).reshape(<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">       [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">       [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[np.ix_([<span class="number">0</span>,<span class="number">1</span>],[<span class="number">1</span>,<span class="number">3</span>])]</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">5</span>, <span class="number">7</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.arange(<span class="number">24</span>).reshape(<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">        [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">        [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>, <span class="number">15</span>],</span><br><span class="line">        [<span class="number">16</span>, <span class="number">17</span>, <span class="number">18</span>, <span class="number">19</span>],</span><br><span class="line">        [<span class="number">20</span>, <span class="number">21</span>, <span class="number">22</span>, <span class="number">23</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b[np.ix_([<span class="number">0</span>,<span class="number">1</span>],[<span class="number">1</span>],[<span class="number">1</span>,<span class="number">3</span>])]</span><br><span class="line">array([[[ <span class="number">5</span>,  <span class="number">7</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">17</span>, <span class="number">19</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b[np.ix_([<span class="number">1</span>],[<span class="number">0</span>,<span class="number">1</span>])] <span class="comment">#在三维数组轴0和轴1构成的“面”上进行花式索引</span></span><br><span class="line">array([[[<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>, <span class="number">15</span>],</span><br><span class="line">        [<span class="number">16</span>, <span class="number">17</span>, <span class="number">18</span>, <span class="number">19</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.rollaxis(b,<span class="number">1</span>,<span class="number">3</span>)[np.ix_([<span class="number">0</span>,<span class="number">1</span>],[<span class="number">2</span>,<span class="number">3</span>])] <span class="comment">#如果要在轴0和轴2构成的“面”上进行花式索引的话，需要先变换数组的轴，使原来的轴2滚动到轴1的位置上</span></span><br><span class="line">array([[[ <span class="number">2</span>,  <span class="number">6</span>, <span class="number">10</span>],</span><br><span class="line">        [ <span class="number">3</span>,  <span class="number">7</span>, <span class="number">11</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">14</span>, <span class="number">18</span>, <span class="number">22</span>],</span><br><span class="line">        [<span class="number">15</span>, <span class="number">19</span>, <span class="number">23</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[np.ix_([<span class="number">0</span>,<span class="number">2</span>])]</span><br><span class="line">array([[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">       [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[[<span class="number">0</span>,<span class="number">2</span>]] <span class="comment">#同上，因为np.ix_([0,2])将返回np.array([0,2])，其实也就是[0,2]。这是一维花式索引，允许以逗号为间隔指定多个维度的索引方式，其等同于a[[0,2],...]</span></span><br><span class="line">array([[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">       [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[:,[<span class="number">0</span>,<span class="number">2</span>]] <span class="comment">#一维花式索引可以和切片索引混用</span></span><br><span class="line">array([[ <span class="number">0</span>,  <span class="number">2</span>],</span><br><span class="line">       [ <span class="number">4</span>,  <span class="number">6</span>],</span><br><span class="line">       [ <span class="number">8</span>, <span class="number">10</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">1</span>,[<span class="number">0</span>,<span class="number">2</span>]] <span class="comment">#一维花式索引可以和（单个）数值索引混用</span></span><br><span class="line">array([<span class="number">4</span>, <span class="number">6</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b[:,<span class="number">1</span>,[<span class="number">0</span>,<span class="number">3</span>]] <span class="comment">#同上</span></span><br><span class="line">array([[ <span class="number">4</span>,  <span class="number">7</span>],</span><br><span class="line">       [<span class="number">16</span>, <span class="number">19</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b[[<span class="number">0</span>,<span class="number">1</span>],:,[<span class="number">0</span>,<span class="number">1</span>]] <span class="comment">#注意这是一个错误示例，输出不符合预期（因为一维花式索引只能出现一次，不能出现在多个维度上），按理说，由于数组b轴0长度为2，此处不应该相当于b[...,[0,1]]么？观察两者输出，后者正常</span></span><br><span class="line">array([[ <span class="number">0</span>,  <span class="number">4</span>,  <span class="number">8</span>],</span><br><span class="line">       [<span class="number">13</span>, <span class="number">17</span>, <span class="number">21</span>]])</span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>笛卡尔积计算</span></div>    <div class="hide-content"><p>废话不多说，直接看代码吧：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;任意数量的序列的笛卡尔积，递归法求解</span></span><br><span class="line"><span class="string">编写思路：</span></span><br><span class="line"><span class="string">1.函数返回的是什么？返回的形式总为：[(),(),...,()]</span></span><br><span class="line"><span class="string">2.一般步骤是什么？对于N个序列的“笛卡尔积”，只要求出前N-1个，其结果记为t（形如[(),(),...,()]，设其长度为s），那么与第N个序列（[e0,e1,...,en]）再做一次“笛卡尔积”的结果将为：[(*t[0],e0),...,(*t[s],e0),(*t[0],e1),...,(*t[s],e1),(*t[0],e2),...,(*t[s],e2),......,(*t[0],en),...,(*t[s],en)]</span></span><br><span class="line"><span class="string">3.递归的终点是什么（问题分解的最小规模）？只有一个序列（记为seq）的“笛卡尔积”，返回结果就是：[(e,) for e in seq]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">cross_product</span>(<span class="params">*arrs</span>):</span><br><span class="line">    ret=[]</span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">len</span>(arrs)==<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> [(i,) <span class="keyword">for</span> i <span class="keyword">in</span> arrs[<span class="number">0</span>]]</span><br><span class="line">    t=cross_product(*arrs[:-<span class="number">1</span>])</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> t:</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> arrs[-<span class="number">1</span>]:</span><br><span class="line">            ret.append((*i,j))</span><br><span class="line">    <span class="keyword">return</span> ret</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(cross_product([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])) <span class="comment">#个数3</span></span><br><span class="line"><span class="built_in">print</span>(cross_product([<span class="number">1</span>,<span class="number">2</span>],[<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>])) <span class="comment">#个数2*3=6</span></span><br><span class="line"><span class="built_in">print</span>(cross_product([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>],[<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>])) <span class="comment">#个数3*3*3=27</span></span><br></pre></td></tr></table></figure></div></div>特别地，<code>np.ix_()</code>还允许接收布尔型序列<code>boolean_sequence</code>，它将被自动转化为<code>np.nonzero(boolean_sequence))</code>，也就是序列中为真值<code>True</code>的下标，还是以之前的“学生成绩单”为案例，再要获取Muggle期中的三科成绩：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>scores[np.ix_(periods==<span class="string">&#x27;Midterm&#x27;</span>,names==<span class="string">&#x27;Muggle&#x27;</span>)]</span><br><span class="line">array([[[<span class="number">90</span>, <span class="number">82</span>, <span class="number">86</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>scores[np.ix_(periods==<span class="string">&#x27;Midterm&#x27;</span>,names==<span class="string">&#x27;Muggle&#x27;</span>,subjects==<span class="string">&#x27;Math&#x27;</span>)] <span class="comment">#进一步获取Muggle的期中数学成绩</span></span><br><span class="line">array([[[<span class="number">82</span>]]])</span><br></pre></td></tr></table></figure>再要获取所有人的期末英语成绩：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.rollaxis(scores,<span class="number">1</span>,<span class="number">3</span>)[np.ix_(periods==<span class="string">&#x27;Endterm&#x27;</span>,subjects==<span class="string">&#x27;English&#x27;</span>)]</span><br><span class="line">array([[[<span class="number">85</span>, <span class="number">79</span>, <span class="number">90</span>]]])</span><br></pre></td></tr></table></figure>掌握技巧就会很容易写：将要进行条件选择的字段提前，不需要的一律置后，譬如上面的例子，<code>periods</code>和<code>subjects</code>两个字段需要进行条件选择，而<code>names</code>字段（“所有人”嘛）不需要，因此将<code>names</code>字段滚动到最后一个轴位置处，其他两个字段也就相对提前了，再举个例子，要获取Muggle的所有成绩，只有<code>names</code>字段需要条件选择，因此只需要将该字段提到最前即可：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.rollaxis(scores,<span class="number">1</span>)[np.ix_(names==<span class="string">&#x27;Muggle&#x27;</span>)] <span class="comment">#或np.rollaxis(scores,1)[names==&#x27;Muggle&#x27;]</span></span><br><span class="line">array([[[<span class="number">90</span>, <span class="number">82</span>, <span class="number">86</span>],</span><br><span class="line">        [<span class="number">88</span>, <span class="number">91</span>, <span class="number">79</span>]]])</span><br></pre></td></tr></table></figure>再要获取Muggle期中期末的数学成绩：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.rollaxis(scores,<span class="number">0</span>,<span class="number">3</span>)[np.ix_(names==<span class="string">&#x27;Muggle&#x27;</span>,subjects==<span class="string">&#x27;Math&#x27;</span>)]</span><br><span class="line">array([[[<span class="number">82</span>, <span class="number">91</span>]]])</span><br></pre></td></tr></table></figure>再要获取Daiyang和Huamulan期末的语文成绩：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>scores[np.ix_(periods==<span class="string">&#x27;Endterm&#x27;</span>,(names==<span class="string">&#x27;Daiyang&#x27;</span>)|(names==<span class="string">&#x27;Huamulan&#x27;</span>),subjects==<span class="string">&#x27;Chinese&#x27;</span>)]</span><br><span class="line">array([[[<span class="number">78</span>],</span><br><span class="line">        [<span class="number">92</span>]]])</span><br></pre></td></tr></table></figure><p>最后再看一种特殊的（一维）花式索引，在上述一维花式索引使用的基础上，譬如<code>a[s]</code>，其中<code>s</code>是一个一维序列，事实上，<code>s</code>可以reshape成任意形状（必须是<code>ndarray</code>对象），此时<code>a[s]</code>返回的结果相当于<code>t=a[s.flatten()];a[s]=t.reshape(*s.shape,*t.shape[1:])</code>，再譬如<code>a[:,s]</code>的返回结果相当于<code>t=a[:,s.flatten()];a[:,s]=t.reshape(*t.shape[:-1],*s.shape)</code>，看个示例：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">6</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[np.array([[<span class="number">0</span>,<span class="number">3</span>],[<span class="number">1</span>,<span class="number">4</span>],[<span class="number">2</span>,<span class="number">5</span>]])]</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">1</span>, <span class="number">4</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s=np.array([[<span class="number">0</span>,<span class="number">3</span>],[<span class="number">1</span>,<span class="number">4</span>],[<span class="number">2</span>,<span class="number">5</span>]]);t=a[s.flatten()];t.reshape(*s.shape,*t.shape[<span class="number">1</span>:]) <span class="comment">#验证</span></span><br><span class="line">array([[<span class="number">0</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">1</span>, <span class="number">4</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">12</span>).reshape(<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">       [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">       [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[np.array([[<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>],[<span class="number">2</span>,<span class="number">1</span>,<span class="number">0</span>]])]</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">        [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">        [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>],</span><br><span class="line">        [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">        [ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[:,np.array([[<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>],[<span class="number">2</span>,<span class="number">1</span>,<span class="number">0</span>]])]</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>],</span><br><span class="line">        [ <span class="number">2</span>,  <span class="number">1</span>,  <span class="number">0</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>],</span><br><span class="line">        [ <span class="number">6</span>,  <span class="number">5</span>,  <span class="number">4</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>],</span><br><span class="line">        [<span class="number">10</span>,  <span class="number">9</span>,  <span class="number">8</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s=np.array([[<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>],[<span class="number">2</span>,<span class="number">1</span>,<span class="number">0</span>]]);t=a[:,s.flatten()];t.reshape(*t.shape[:-<span class="number">1</span>],*s.shape) <span class="comment">#验证</span></span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>],</span><br><span class="line">        [ <span class="number">2</span>,  <span class="number">1</span>,  <span class="number">0</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>],</span><br><span class="line">        [ <span class="number">6</span>,  <span class="number">5</span>,  <span class="number">4</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>],</span><br><span class="line">        [<span class="number">10</span>,  <span class="number">9</span>,  <span class="number">8</span>]]])</span><br></pre></td></tr></table></figure><p>看一个利用该原理的示例，构建循环队列：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">circular_queue</span>(<span class="params">arr</span>):</span><br><span class="line">    t=<span class="built_in">list</span>(<span class="built_in">range</span>(<span class="built_in">len</span>(arr)))</span><br><span class="line">    inds=<span class="built_in">list</span>(<span class="built_in">zip</span>(*[(t+t[:-<span class="number">1</span>])[i:] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(t))]))</span><br><span class="line">    <span class="keyword">return</span> np.array(arr)[np.array(inds)]</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(circular_queue([<span class="number">4</span>,<span class="number">4</span>,<span class="number">6</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">7</span>]))</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">[[4 4 6 3 2 7]</span></span><br><span class="line"><span class="string"> [4 6 3 2 7 4]</span></span><br><span class="line"><span class="string"> [6 3 2 7 4 4]</span></span><br><span class="line"><span class="string"> [3 2 7 4 4 6]</span></span><br><span class="line"><span class="string"> [2 7 4 4 6 3]</span></span><br><span class="line"><span class="string"> [7 4 4 6 3 2]]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="数组元素迭代">数组元素迭代</h2><div class="tabs" id="szysdd"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#szysdd-1"><code>np.nditer()</code></button></li><li class="tab"><button type="button" data-href="#szysdd-2"><code>ndarray.flat</code></button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="szysdd-1"><div class="note blue simple"><p><code>np.nditer(a, order, flags, op_flags, ...)</code><br>函数说明：<br>对一个多维数组使用<code>for</code>循环迭代只能遍历第0维上的元素，要迭代所有元素，需使用<code>flatten()</code>等函数展平（一维化）数组，并且可以指定访问风格，行主序或列主序，numpy为我们提供了一个专门的函数<code>nditer()</code>，通过该函数将创建一个在多维数组上的元素迭代器<br>参数说明（部分）：</p><ul><li><code>order</code>：指定数组元素的迭代风格，行主序或列主序</li><li><code>flags</code>参数（部分）可取值（一个字符串序列，可以同时指定以下多个值）：<ul><li><code>c_index</code>：表示跟踪C顺序的索引（从0开始计数），索引值通过函数返回的迭代器的<code>index</code>属性获取，即便实际是以F风格（<code>order</code>参数）迭代数组元素，给出的也是C风格索引。注意<code>c_index</code>和<code>f_index</code>两者只能取其一</li><li><code>f_index</code>：表示跟踪F顺序的索引，同上</li><li><code>multi_index</code>：表示跟踪迭代元素的全（位置）坐标，通过函数返回的迭代器的<code>multi_index</code>属性获取</li><li><code>external_loop</code>（没懂）：其将多维数组<code>a</code>视为由诸多一维数组元素构成的数组，若指定<code>order='F'</code>，那么迭代次数将为<code>reduce(lambda x,y:x*y,a.shape[1:])</code>，此时第0维上的向量被视为单个元素，若指定<code>order='C'</code>，那么迭代次数将为1，访问的元素就是<code>np.flatten(a)</code>，一个一维数组，这有何用？</li></ul></li><li><code>op_flags</code>：默认取值<code>readonly</code>，即视待遍历的数组为只读对象，为了在遍历数组的同时实现对数组元素值的修改，需指定为<code>readwrite</code>或<code>writeonly</code></li></ul></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>元素迭代器的属性和方法</span></div>    <div class="hide-content"><p>函数所返回的迭代器上的（部分）属性和方法：</p><ul><li><code>finished</code>：判断元素是否迭代完毕，也可以通过迭代器对象的<code>iternext()</code>方法的返回值来判断</li><li><code>iterindex</code>：返回当前迭代位置处元素的索引，至于是C风格还是F风格由<code>order</code>参数决定</li><li><code>has_index</code>：如果返回<code>True</code>，表示迭代器是指定<code>c_index</code>或<code>f_index</code>标志（<code>flags</code>参数）创建的，此时属性<code>index</code>才是可获得的</li><li><code>index</code>：同<code>iterindex</code>，只不过具体的风格是由<code>flags</code>参数决定，且只有当<code>has_index</code>属性为<code>True</code>时，可以使用该属性，否则引发<code>ValueError</code>异常</li><li><code>has_multi_index</code>：如果返回<code>True</code>，表示迭代器是指定<code>multi_index</code>标志（<code>flags</code>参数）创建的，此时属性<code>multi_index</code>才是可获得的</li><li><code>multi_index</code>：返回当前迭代位置处元素的全坐标（即该元素在原始数组中的位置坐标），只有当<code>has_multi_index</code>属性为<code>True</code>时，可以使用该属性，否则引发<code>ValueError</code>异常</li><li><code>itersize</code>：返回迭代器中元素的个数（还有<code>ndim</code>和<code>shape</code>属性，我还没弄明白它们的输出，譬如<code>nditer(np.arange(12).reshape(3,-1),flags=['f_index']).shape</code>为什么是<code>(4,3)</code>，而将其中的<code>f_index</code>改成<code>c_index</code>输出又变成<code>(12,)</code>？）</li><li><code>iternext()</code>：表示执行一次内部迭代，但不返回迭代元素，只返回<code>True</code>或<code>False</code>，用于判断当前迭代器是否已尽，返回<code>False</code>表示没有元素可供迭代了（继续执行<code>iternext()</code>方法仍会返回<code>False</code>，调用<code>iterable[0]</code>则会出错，除非调用<code>reset()</code>方法重置状态以从头开始迭代），而要获取当前迭代位置处的元素，可以通过下标0索引该迭代器（即<code>iterator[0]</code>，事实上，你可以使用<code>nditer()</code>并行迭代多个多维数组对象，于是第二个多维数组的元素可以通过<code>iterable[1]</code>获取，以此类推。注意在使用<code>nditer()</code>创建迭代器后，立即就可调用<code>iterable[0]</code>来获取第一个迭代元素，而无需先调用<code>iternext()</code>方法）的方式获取。除了使用<code>iternext()</code>，常规的迭代方法则是使用<code>for</code>循环遍历迭代器（自动调用迭代器对象的<code>__next__()</code>方法），当然也可以手动调用<code>__next__()</code>方法（此时需自行捕捉<code>StopIteration</code>异常）</li><li><code>reset()</code>：重置迭代器的状态</li><li><code>copy()</code>：返回迭代器在当前状态下的一个副本</li></ul></div></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;### nditer() ###&#x27;</span>)</span><br><span class="line">a=np.arange(<span class="number">6</span>).reshape((<span class="number">2</span>,<span class="number">3</span>),order=<span class="string">&#x27;F&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> np.nditer(a,order=<span class="string">&#x27;C&#x27;</span>): <span class="comment">#默认order为&#x27;K&#x27;，其将会按照a的布局进行访问，打印0,1,2,3,4,5,</span></span><br><span class="line">    <span class="built_in">print</span>(i,end=<span class="string">&#x27;,&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;### read_write mode ###&#x27;</span>)</span><br><span class="line"><span class="comment">#读写模式</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> np.nditer(a,op_flags=(<span class="string">&#x27;readwrite&#x27;</span>,),order=<span class="string">&#x27;C&#x27;</span>):</span><br><span class="line">    i*=<span class="number">2</span></span><br><span class="line">    <span class="built_in">print</span>(i,end=<span class="string">&#x27;,&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"><span class="built_in">print</span>(a) <span class="comment">#可以看到原始数组也已经被修改了</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;### while+iternext() ###&#x27;</span>)</span><br><span class="line"><span class="comment">#通过while循环不断输出迭代器对象的索引属性值</span></span><br><span class="line">a=np.array([<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>,<span class="number">7</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">6</span>,<span class="number">8</span>]).reshape((<span class="number">2</span>,<span class="number">2</span>,-<span class="number">1</span>))</span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line">it=np.nditer(a,flags=[<span class="string">&#x27;f_index&#x27;</span>])</span><br><span class="line"><span class="built_in">print</span>(it.ndim,it.shape,it.itersize)</span><br><span class="line"><span class="keyword">while</span> <span class="keyword">not</span> it.finished:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;[F]index-%d: %d [C]index-%d&quot;</span> % (it.index,it[<span class="number">0</span>],it.iterindex)) <span class="comment">#index属性跟踪F顺序的索引，即使当前实际是以C风格访问数组元素</span></span><br><span class="line">    it.iternext()</span><br><span class="line">it=np.nditer(a,flags=[<span class="string">&#x27;multi_index&#x27;</span>])</span><br><span class="line"><span class="keyword">while</span> <span class="keyword">not</span> it.finished:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;index-%s: %d&quot;</span> % (it.multi_index,it[<span class="number">0</span>])) <span class="comment">#全位置坐标</span></span><br><span class="line">    it.iternext()</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;### external_loop ###&#x27;</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> np.nditer(a,flags=[<span class="string">&#x27;external_loop&#x27;</span>],order=<span class="string">&#x27;F&#x27;</span>):</span><br><span class="line">    <span class="built_in">print</span>(i,end=<span class="string">&#x27;,&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> np.nditer(a,flags=[<span class="string">&#x27;external_loop&#x27;</span>],order=<span class="string">&#x27;C&#x27;</span>): <span class="comment">#有什么用？</span></span><br><span class="line">    <span class="built_in">print</span>(i,end=<span class="string">&#x27;,&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;### copy() ###&#x27;</span>)</span><br><span class="line">it=np.nditer(np.arange(<span class="number">24</span>).reshape(<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>))</span><br><span class="line"><span class="built_in">print</span>(it.__next__())</span><br><span class="line"><span class="built_in">print</span>(it.__next__())</span><br><span class="line">it2=it.copy() <span class="comment">#副本保存了原件的状态</span></span><br><span class="line"><span class="built_in">print</span>(it2.__next__())</span><br><span class="line"><span class="built_in">print</span>(it.__next__())</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;### return of iternext() ###&#x27;</span>)</span><br><span class="line">it=np.nditer(np.array([<span class="number">12</span>,<span class="number">13</span>]))</span><br><span class="line"><span class="built_in">print</span>(it.iternext())</span><br><span class="line"><span class="built_in">print</span>(it.__next__())</span><br><span class="line"><span class="built_in">print</span>(it.iternext())</span><br><span class="line"><span class="built_in">print</span>(it.iternext())</span><br><span class="line"><span class="built_in">print</span>(it.iternext())</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">### nditer() ###</span></span><br><span class="line"><span class="string">[[0 2 4]</span></span><br><span class="line"><span class="string"> [1 3 5]]</span></span><br><span class="line"><span class="string">0,2,4,1,3,5,</span></span><br><span class="line"><span class="string">### read_write mode ###</span></span><br><span class="line"><span class="string">0,4,8,2,6,10,</span></span><br><span class="line"><span class="string">[[ 0  4  8]</span></span><br><span class="line"><span class="string"> [ 2  6 10]]</span></span><br><span class="line"><span class="string">### while+iternext() ###</span></span><br><span class="line"><span class="string">[[[1 3]</span></span><br><span class="line"><span class="string">  [5 7]]</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string"> [[2 4]</span></span><br><span class="line"><span class="string">  [6 8]]]</span></span><br><span class="line"><span class="string">3 (2, 2, 2) 8</span></span><br><span class="line"><span class="string">[F]index-0: 1 [C]index-0</span></span><br><span class="line"><span class="string">[F]index-4: 3 [C]index-1</span></span><br><span class="line"><span class="string">[F]index-2: 5 [C]index-2</span></span><br><span class="line"><span class="string">[F]index-6: 7 [C]index-3</span></span><br><span class="line"><span class="string">[F]index-1: 2 [C]index-4</span></span><br><span class="line"><span class="string">[F]index-5: 4 [C]index-5</span></span><br><span class="line"><span class="string">[F]index-3: 6 [C]index-6</span></span><br><span class="line"><span class="string">[F]index-7: 8 [C]index-7</span></span><br><span class="line"><span class="string">index-(0, 0, 0): 1</span></span><br><span class="line"><span class="string">index-(0, 0, 1): 3</span></span><br><span class="line"><span class="string">index-(0, 1, 0): 5</span></span><br><span class="line"><span class="string">index-(0, 1, 1): 7</span></span><br><span class="line"><span class="string">index-(1, 0, 0): 2</span></span><br><span class="line"><span class="string">index-(1, 0, 1): 4</span></span><br><span class="line"><span class="string">index-(1, 1, 0): 6</span></span><br><span class="line"><span class="string">index-(1, 1, 1): 8</span></span><br><span class="line"><span class="string">### external_loop ###</span></span><br><span class="line"><span class="string">[1 2],[5 6],[3 4],[7 8],</span></span><br><span class="line"><span class="string">[1 3 5 7 2 4 6 8],</span></span><br><span class="line"><span class="string">### copy() ###</span></span><br><span class="line"><span class="string">0</span></span><br><span class="line"><span class="string">1</span></span><br><span class="line"><span class="string">2</span></span><br><span class="line"><span class="string">2</span></span><br><span class="line"><span class="string">### return of iternext() ###</span></span><br><span class="line"><span class="string">True</span></span><br><span class="line"><span class="string">13</span></span><br><span class="line"><span class="string">False</span></span><br><span class="line"><span class="string">False</span></span><br><span class="line"><span class="string">False</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>并行迭代，如果两个数组是同形的（弱化条件为两者可以广播至同一形状），那么<code>nditer()</code>能够同时迭代它们：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a=np.arange(<span class="number">0</span>,<span class="number">60</span>,<span class="number">5</span>).reshape(<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line">b=np.array([<span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>,  <span class="number">4</span>])</span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line"><span class="built_in">print</span>(b)</span><br><span class="line"><span class="comment">#b（形状为(1,4)）可以广播至与a的相同形状(3,4)</span></span><br><span class="line"><span class="keyword">for</span> ia,ib <span class="keyword">in</span> np.nditer([a,b]):</span><br><span class="line">    <span class="built_in">print</span>(ia,<span class="string">&#x27;,&#x27;</span>,ib)</span><br><span class="line"></span><br><span class="line">it=np.nditer([a,b],flags=[<span class="string">&#x27;multi_index&#x27;</span>])</span><br><span class="line"><span class="keyword">while</span> <span class="keyword">not</span> it.finished:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;pos:<span class="subst">&#123;it.multi_index&#125;</span>,item(a):<span class="subst">&#123;it[<span class="number">0</span>]&#125;</span>,item(b):<span class="subst">&#123;it[<span class="number">1</span>]&#125;</span>&#x27;</span>)</span><br><span class="line">    it.iternext()</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">[[ 0  5 10 15]</span></span><br><span class="line"><span class="string"> [20 25 30 35]</span></span><br><span class="line"><span class="string"> [40 45 50 55]]</span></span><br><span class="line"><span class="string">[1 2 3 4]</span></span><br><span class="line"><span class="string">0 , 1</span></span><br><span class="line"><span class="string">5 , 2</span></span><br><span class="line"><span class="string">10 , 3</span></span><br><span class="line"><span class="string">15 , 4</span></span><br><span class="line"><span class="string">20 , 1</span></span><br><span class="line"><span class="string">25 , 2</span></span><br><span class="line"><span class="string">30 , 3</span></span><br><span class="line"><span class="string">35 , 4</span></span><br><span class="line"><span class="string">40 , 1</span></span><br><span class="line"><span class="string">45 , 2</span></span><br><span class="line"><span class="string">50 , 3</span></span><br><span class="line"><span class="string">55 , 4</span></span><br><span class="line"><span class="string">pos:(0, 0),item(a):0,item(b):1</span></span><br><span class="line"><span class="string">pos:(0, 1),item(a):5,item(b):2</span></span><br><span class="line"><span class="string">pos:(0, 2),item(a):10,item(b):3</span></span><br><span class="line"><span class="string">pos:(0, 3),item(a):15,item(b):4</span></span><br><span class="line"><span class="string">pos:(1, 0),item(a):20,item(b):1</span></span><br><span class="line"><span class="string">pos:(1, 1),item(a):25,item(b):2</span></span><br><span class="line"><span class="string">pos:(1, 2),item(a):30,item(b):3</span></span><br><span class="line"><span class="string">pos:(1, 3),item(a):35,item(b):4</span></span><br><span class="line"><span class="string">pos:(2, 0),item(a):40,item(b):1</span></span><br><span class="line"><span class="string">pos:(2, 1),item(a):45,item(b):2</span></span><br><span class="line"><span class="string">pos:(2, 2),item(a):50,item(b):3</span></span><br><span class="line"><span class="string">pos:(2, 3),item(a):55,item(b):4</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szysdd-2"><p>该属性返回多维数组的元素迭代器（一个<code>flatiter</code>对象，由于是迭代器对象，用完即弃），遵循C风格，也可以作为一个一维数组“视图”使用，支持切片索引、花式索引等，<code>flatiter</code>对象上有一个<code>copy()</code>方法将其转为（一维的）<code>ndarray</code>对象（深拷贝），其还有三个主要属性：</p><ul><li><code>base</code>：返回<code>flatiter</code>对象的原始数组引用</li><li><code>index</code>：返回当前迭代元素的索引（从0开始计数）</li><li><code>coords</code>：返回当前迭代元素在原数组中的全坐标</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a=np.arange(<span class="number">10</span>).reshape((<span class="number">2</span>,-<span class="number">1</span>))</span><br><span class="line">b=a.flat</span><br><span class="line"><span class="built_in">print</span>(b.base <span class="keyword">is</span> a)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> b:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;元素:&#x27;</span>,i,<span class="string">&#x27;索引:&#x27;</span>,b.index,<span class="string">&#x27;位置坐标:&#x27;</span>,b.coords)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">True</span></span><br><span class="line"><span class="string">元素: 0 索引: 1 位置坐标: (0, 1)</span></span><br><span class="line"><span class="string">元素: 1 索引: 2 位置坐标: (0, 2)</span></span><br><span class="line"><span class="string">元素: 2 索引: 3 位置坐标: (0, 3)</span></span><br><span class="line"><span class="string">元素: 3 索引: 4 位置坐标: (0, 4)</span></span><br><span class="line"><span class="string">元素: 4 索引: 5 位置坐标: (1, 0)</span></span><br><span class="line"><span class="string">元素: 5 索引: 6 位置坐标: (1, 1)</span></span><br><span class="line"><span class="string">元素: 6 索引: 7 位置坐标: (1, 2)</span></span><br><span class="line"><span class="string">元素: 7 索引: 8 位置坐标: (1, 3)</span></span><br><span class="line"><span class="string">元素: 8 索引: 9 位置坐标: (1, 4)</span></span><br><span class="line"><span class="string">元素: 9 索引: 10 位置坐标: (2, 0)</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>上述输出不正确，这里不建议通过<code>for</code>循环的方式去获取索引或坐标，因为<code>flatiter</code>只有调用一次<code>__next__()</code>方法后才能获取到（第一个）迭代元素，而调用后其<code>index</code>和<code>coords</code>属性又会立即更新（变成第二个迭代元素的索引和坐标），因此必须在<code>next()</code>前获取<code>index</code>和<code>coords</code>，<code>for</code>循环无法控制<code>next()</code>调用的时机，因此可以通过<code>while</code>方式并手动调用<code>next()</code>迭代元素：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> itertools <span class="keyword">import</span> count</span><br><span class="line">a=np.arange(<span class="number">10</span>).reshape((<span class="number">2</span>,-<span class="number">1</span>))</span><br><span class="line">b=a.flat</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> count():</span><br><span class="line">    s=<span class="string">f&#x27;<span class="subst">&#123;b.index&#125;</span>,<span class="subst">&#123;b.coords&#125;</span>&#x27;</span></span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        <span class="built_in">print</span>(s,b.__next__())</span><br><span class="line">    <span class="keyword">except</span> StopIteration <span class="keyword">as</span> e:</span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">0,(0, 0) 0</span></span><br><span class="line"><span class="string">1,(0, 1) 1</span></span><br><span class="line"><span class="string">2,(0, 2) 2</span></span><br><span class="line"><span class="string">3,(0, 3) 3</span></span><br><span class="line"><span class="string">4,(0, 4) 4</span></span><br><span class="line"><span class="string">5,(1, 0) 5</span></span><br><span class="line"><span class="string">6,(1, 1) 6</span></span><br><span class="line"><span class="string">7,(1, 2) 7</span></span><br><span class="line"><span class="string">8,(1, 3) 8</span></span><br><span class="line"><span class="string">9,(1, 4) 9</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p><code>ndarray.flat</code>本身也可以作为展平后的一维数组“视图”使用：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a=np.arange(<span class="number">10</span>).reshape((<span class="number">2</span>,-<span class="number">1</span>))</span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line"><span class="built_in">print</span>(a.flat[[<span class="number">2</span>,<span class="number">5</span>,<span class="number">7</span>]]) <span class="comment">#对一维数组的花式索引</span></span><br><span class="line">a.flat[[<span class="number">3</span>,<span class="number">6</span>]]=<span class="number">55</span> <span class="comment">#对“视图”的修改将影响原数组</span></span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line">a.flat.copy()[<span class="number">0</span>]=<span class="number">78</span> <span class="comment">#copy()深复制，不影响原数组</span></span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line">a.flat=[i <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">100</span>,<span class="number">200</span>)] <span class="comment">#可以将一个一维数组或列表赋给flat属性（长度不一致时会自动截取前n项），这常用于一个多维数组元素的修改</span></span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">[[0 1 2 3 4]</span></span><br><span class="line"><span class="string"> [5 6 7 8 9]]</span></span><br><span class="line"><span class="string">[2 5 7]</span></span><br><span class="line"><span class="string">[[ 0  1  2 55  4]</span></span><br><span class="line"><span class="string"> [ 5 55  7  8  9]]</span></span><br><span class="line"><span class="string">[[ 0  1  2 55  4]</span></span><br><span class="line"><span class="string"> [ 5 55  7  8  9]]</span></span><br><span class="line"><span class="string">[[100 101 102 103 104]</span></span><br><span class="line"><span class="string"> [105 106 107 108 109]]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="广播机制">广播机制</h2><div class="tabs" id="gbjz"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#gbjz-1"><code>np.broadcast()</code></button></li><li class="tab"><button type="button" data-href="#gbjz-2"><code>np.broadcast_to()</code></button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="gbjz-1"><p>广播机制是处理不同维度数组间操作的一个非常重要的手段，要知道两个不同的多维数组能够进行操作的基本条件是其形状相同，当形状不同时，但符合广播的条件，则会自动对这两个或其中一个多维数组进行维度补齐并进行元素复制（补齐维数）<br>广播的规则：</p><ol><li>让所有输入数组都向其中维数最大（<code>shape</code>最长）的数组看齐，<code>shape</code>中不足的部分在前面加1补齐维度</li><li>输出数组的<code>shape</code>根据所有输入数组<code>shape</code>的各个轴上的最大值得到</li><li>如果输入数组的某个轴和输出数组的对应轴的长度相同或者不同但其中一方长度为1时，这些输入数组被认为能够广播至输出数组的形状，即符合广播的条件，否则抛出异常</li><li>当输入数组的某个轴的长度为1且输出数组对应轴长大于1时，将沿着此轴复制第一个元素来进一步补齐维数</li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">a=np.arange(<span class="number">24</span>).reshape((<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>))</span><br><span class="line">b1=np.arange(<span class="number">4</span>).reshape((-<span class="number">1</span>))</span><br><span class="line">b2=np.arange(<span class="number">12</span>).reshape((<span class="number">3</span>,-<span class="number">1</span>))</span><br><span class="line">c1=a+b1 <span class="comment">#首先维度补齐：b1.reshape((1,1,4))，确定输出数组形状：(2,3,4)，判断能够进行广播，最后进行元素复制</span></span><br><span class="line">c2=a+b2 <span class="comment">#同上，维度补齐后得到b2.reshape((1,3,4))，输出数组形状仍是(2,3,4)，且符合广播的条件</span></span><br><span class="line"></span><br><span class="line">a=np.arange(<span class="number">8</span>).reshape((<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>,<span class="number">4</span>))</span><br><span class="line">b=np.arange(<span class="number">12</span>).reshape((<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">3</span>,-<span class="number">1</span>))</span><br><span class="line">c=a+b <span class="comment">#a补齐维度a.reshape((1,1,2,1,4))，b补齐维度b.reshape((1,1,1,3,4))，再确定输出数组形状(1,1,2,3,4)，显然也符合广播条件</span></span><br></pre></td></tr></table></figure><div class="note blue simple"><p><code>np.broadcast(*arrs)</code><br>函数说明：<br>函数可以接受任意数量（设为<code>n</code>）的输入数组，并产生基于这些输入数组的“广播对象”作为函数返回值，这个广播对象有一些属性和方法，其中<code>shape</code>和<code>ndim</code>（或<code>nd</code>）分别获取经广播机制作用后的输出数组的形状和维数，而<code>iters</code>属性返回一个长度为<code>n</code>（数量可由<code>numiter</code>属性获取）的由诸多<code>flatiter</code>对象构成的元组，这些<code>flatiter</code>（用完即弃）分别代表那些输入数组经广播（维度补齐和元素复制）后的数据内容，此外，广播对象本身也是一个迭代器（用完即弃），相当于并行迭代前面的<code>flatiter</code>对象，为了复用广播对象，其有一个<code>reset()</code>方法能够重置初始的迭代状态</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>x=np.array([[<span class="number">1</span>], [<span class="number">2</span>], [<span class="number">3</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>y=np.array([<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>broadcast_obj=np.broadcast(x,y) <span class="comment">#两个输入数组x和y的形状分别为(3,1)和(5,)，于是输出数组的形状可以确定为(3,5)，并且符合广播条件，于是x和y分别沿着第1轴和第0轴按列复制和按行复制元素</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">type</span>(broadcast_obj)</span><br><span class="line">&lt;<span class="keyword">class</span> <span class="string">&#x27;numpy.broadcast&#x27;</span>&gt;</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>broadcast_obj.shape</span><br><span class="line">(<span class="number">3</span>, <span class="number">5</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>broadcast_obj.nd</span><br><span class="line"><span class="number">2</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a,b=broadcast_obj.iters</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">list</span>(a)</span><br><span class="line">[<span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">3</span>, <span class="number">3</span>, <span class="number">3</span>, <span class="number">3</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">list</span>(b) <span class="comment">#之后再执行list(a)或list(b)只会得到空列表[]，除非执行重置reset()</span></span><br><span class="line">[<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>broadcast_obj.reset()</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>[(i,j) <span class="keyword">for</span> i,j <span class="keyword">in</span> broadcast_obj]</span><br><span class="line">[(<span class="number">1</span>, <span class="number">4</span>), (<span class="number">1</span>, <span class="number">5</span>), (<span class="number">1</span>, <span class="number">6</span>), (<span class="number">1</span>, <span class="number">7</span>), (<span class="number">1</span>, <span class="number">8</span>), (<span class="number">2</span>, <span class="number">4</span>), (<span class="number">2</span>, <span class="number">5</span>), (<span class="number">2</span>, <span class="number">6</span>), (<span class="number">2</span>, <span class="number">7</span>), (<span class="number">2</span>, <span class="number">8</span>), (<span class="number">3</span>, <span class="number">4</span>), (<span class="number">3</span>, <span class="number">5</span>), (<span class="number">3</span>, <span class="number">6</span>), (<span class="number">3</span>, <span class="number">7</span>), (<span class="number">3</span>, <span class="number">8</span>)]</span><br></pre></td></tr></table></figure>手动实现两个多维数组的相加操作：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>x=np.array([[<span class="number">1</span>], [<span class="number">2</span>], [<span class="number">3</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>y=np.array([<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x+y</span><br><span class="line">array([[ <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>],</span><br><span class="line">       [ <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>],</span><br><span class="line">       [ <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>bo=np.broadcast(x,y)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z=np.empty(bo.shape,dtype=<span class="string">&#x27;i4&#x27;</span>) <span class="comment">#创建一个空的结果数组</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z.flat=[x+y <span class="keyword">for</span> i,j <span class="keyword">in</span> bo]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>z</span><br><span class="line">array([[ <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>],</span><br><span class="line">       [ <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>],</span><br><span class="line">       [ <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="gbjz-2"><div class="note blue simple"><p><code>np.broadcast_to(array, shape, subok=False)</code><br>函数说明：<br>用于将一个数组广播至一个指定的形状</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.broadcast_to(np.array([[<span class="number">1</span>], [<span class="number">2</span>], [<span class="number">3</span>]]),(<span class="number">3</span>,<span class="number">5</span>))</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">3</span>, <span class="number">3</span>, <span class="number">3</span>, <span class="number">3</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.broadcast_to(np.array([<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>]),(<span class="number">3</span>,<span class="number">5</span>))</span><br><span class="line">array([[<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>],</span><br><span class="line">       [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>],</span><br><span class="line">       [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>]])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="数组拼接与分割">数组拼接与分割</h2><div class="tabs" id="szdd"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#szdd-1">数组拼接</button></li><li class="tab"><button type="button" data-href="#szdd-2">数组分割</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="szdd-1"><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.concatenate()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.concatenate((a1, a2, ...), axis=0, out=None)</code><br>函数说明：<br>用于沿指定轴（<code>axis</code>）连接多个数组对象（<code>a1</code>，<code>a2</code>，…），<code>a1</code>、<code>a2</code>等数组的形状完全相同固然最好（此时，可以沿任意轴进行连接），即使不相同，也必须满足“除了将要连接的那个轴的长度可以不一致外，其余轴长必须完全相同”的条件（举例：<code>shape1=(2,3,4,5)</code>，<code>shape2=(2,3,7,5)</code>，则连接轴只能设为2轴，否则出错，且显然输出形状为<code>(2,3,11,5)</code>），特别地，<code>axis</code>置为<code>None</code>时，<code>a1</code>、<code>a2</code>等数组首先会被“展平”（一维化）开来，然后沿0轴连接，<code>out</code>参数指定结果存放的数组</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.array([[<span class="number">1</span>,<span class="number">2</span>],[<span class="number">3</span>,<span class="number">4</span>]]) <span class="comment">#形状为(2,2)</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.array([[<span class="number">5</span>,<span class="number">6</span>]]) <span class="comment">#形状为(1,2)，显然这两个数组只能沿第0轴连接</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.concatenate((a,b),axis=<span class="number">0</span>)</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">4</span>],</span><br><span class="line">       [<span class="number">5</span>, <span class="number">6</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.concatenate((a,b),axis=<span class="literal">None</span>)</span><br><span class="line">array([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.concatenate((a,b.T),axis=<span class="number">1</span>) <span class="comment">#b转置后形状变为(2,1)，此时只能沿着第1轴连接</span></span><br><span class="line">array([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">5</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">4</span>, <span class="number">6</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">24</span>).reshape((<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.arange(<span class="number">24</span>,<span class="number">56</span>).reshape((<span class="number">2</span>,<span class="number">4</span>,<span class="number">4</span>)) <span class="comment">#显然a和b只能沿着第1轴连接，输出数组形状为(2,7,4)</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.concatenate((a,b),axis=<span class="number">1</span>)</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">        [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">        [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>],</span><br><span class="line">        [<span class="number">24</span>, <span class="number">25</span>, <span class="number">26</span>, <span class="number">27</span>],</span><br><span class="line">        [<span class="number">28</span>, <span class="number">29</span>, <span class="number">30</span>, <span class="number">31</span>],</span><br><span class="line">        [<span class="number">32</span>, <span class="number">33</span>, <span class="number">34</span>, <span class="number">35</span>],</span><br><span class="line">        [<span class="number">36</span>, <span class="number">37</span>, <span class="number">38</span>, <span class="number">39</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>, <span class="number">15</span>],</span><br><span class="line">        [<span class="number">16</span>, <span class="number">17</span>, <span class="number">18</span>, <span class="number">19</span>],</span><br><span class="line">        [<span class="number">20</span>, <span class="number">21</span>, <span class="number">22</span>, <span class="number">23</span>],</span><br><span class="line">        [<span class="number">40</span>, <span class="number">41</span>, <span class="number">42</span>, <span class="number">43</span>],</span><br><span class="line">        [<span class="number">44</span>, <span class="number">45</span>, <span class="number">46</span>, <span class="number">47</span>],</span><br><span class="line">        [<span class="number">48</span>, <span class="number">49</span>, <span class="number">50</span>, <span class="number">51</span>],</span><br><span class="line">        [<span class="number">52</span>, <span class="number">53</span>, <span class="number">54</span>, <span class="number">55</span>]]])</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.stack()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.stack(arrays, axis=0, out=None)</code><br>函数说明：<br>沿新轴堆叠数组。用于堆叠的各数组形状必须完全一致，注意<code>stack()</code>总是会增加一个维度（最简单的就是二维数组的堆叠，结果将变成三维数组），“新轴”由参数<code>axis</code>指定，<code>axis</code>的取值为<code>0~len(shape)+1</code>，若取值<code>len(shape)+1</code>表示在最后新增一个维度，譬如有两个待堆叠数组，形状为<code>(2,3,4)</code>，若指定<code>axis</code>为3，返回的新数组形状将为<code>(2,3,4,2)</code></p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">12</span>).reshape(<span class="number">3</span>,-<span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.arange(<span class="number">12</span>,<span class="number">24</span>).reshape(<span class="number">3</span>,-<span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.stack((a,b))</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">        [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">        [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>, <span class="number">15</span>],</span><br><span class="line">        [<span class="number">16</span>, <span class="number">17</span>, <span class="number">18</span>, <span class="number">19</span>],</span><br><span class="line">        [<span class="number">20</span>, <span class="number">21</span>, <span class="number">22</span>, <span class="number">23</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.stack((a,b),axis=<span class="number">2</span>)</span><br><span class="line">array([[[ <span class="number">0</span>, <span class="number">12</span>],</span><br><span class="line">        [ <span class="number">1</span>, <span class="number">13</span>],</span><br><span class="line">        [ <span class="number">2</span>, <span class="number">14</span>],</span><br><span class="line">        [ <span class="number">3</span>, <span class="number">15</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">4</span>, <span class="number">16</span>],</span><br><span class="line">        [ <span class="number">5</span>, <span class="number">17</span>],</span><br><span class="line">        [ <span class="number">6</span>, <span class="number">18</span>],</span><br><span class="line">        [ <span class="number">7</span>, <span class="number">19</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">8</span>, <span class="number">20</span>],</span><br><span class="line">        [ <span class="number">9</span>, <span class="number">21</span>],</span><br><span class="line">        [<span class="number">10</span>, <span class="number">22</span>],</span><br><span class="line">        [<span class="number">11</span>, <span class="number">23</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_.shape</span><br><span class="line">(<span class="number">3</span>, <span class="number">4</span>, <span class="number">2</span>)</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.vstack()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.vstack((a1,a2,...))</code><br>函数说明：<br>不同于<code>np.stack()</code>，<code>vstack()</code>垂直堆叠（不改变维数）总是沿着第0轴连接（<code>concatenate()</code>）多个数组，<code>a1</code>、<code>a2</code>等除0轴外其余轴长必须保持一致，之所以叫“垂直”堆叠，是假设<code>a1</code>、<code>a2</code>等都是二维数组时，第0轴正是那根垂直的轴，特别地，要对一维数组进行“垂直堆叠”，等同于<code>np.vstack((a1[None,:],a2[None,:],...))</code>，因此这些一维数组的长度必须相同（只有在这种特殊情况下，堆叠后的数组维数发生改变）</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.array((<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.array((<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.vstack((a,b))</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.vstack((a[<span class="literal">None</span>,:],b[<span class="literal">None</span>,:]))</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.vstack((np.arange(<span class="number">8</span>).reshape(<span class="number">2</span>,<span class="number">4</span>),np.arange(<span class="number">4</span>).reshape(<span class="number">1</span>,<span class="number">4</span>)))</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>],</span><br><span class="line">       [<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]])</span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.row_stack()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.row_stack((a1,a2,...))</code><br>函数说明：<br>按行堆叠，等同于<code>np.vstack((a1,a2,...))</code></p></div></div></div></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.hstack()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.hstack((a1,a2,...))</code><br>函数说明：<br>类似于<code>np.vstack()</code>，<code>hstack()</code>水平堆叠（不改变维数）总是沿着第1轴连接（<code>concatenate()</code>）多个数组，<code>a1</code>、<code>a2</code>等除1轴外其余轴长必须保持一致，特别地，要对一维数组进行“水平”堆叠，仍等同于<code>np.hstack((a1[None,:],a2[None,:],...))</code>，因此对这些一维数组的长度没有限制</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.array((<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.array((<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.hstack((a,b))</span><br><span class="line">array([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>c=np.arange(<span class="number">4</span>,<span class="number">10</span>).reshape(<span class="number">3</span>,<span class="number">2</span>,order=<span class="string">&#x27;F&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.hstack((a[:,<span class="literal">None</span>],c))</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">4</span>, <span class="number">7</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">5</span>, <span class="number">8</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">6</span>, <span class="number">9</span>]])</span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.column_stack()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.column_stack((a1,a2,...))</code><br>函数说明：<br>按列堆叠，等同于<code>np.hstack((a1,a2,...))</code></p></div></div></div></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.dstack()</code></span></div>    <div class="hide-content"><p>类似于<code>np.vstack()</code>或<code>np.hstack()</code>，<code>dstack()</code>深度堆叠（不改变维数）总是沿着第2轴连接（<code>concatenate()</code>）多个数组，<code>a1</code>、<code>a2</code>等除2轴外其余轴长必须保持一致，特别地，要对一维数组进行“深度”堆叠，等同于<code>np.dstack((a1[None,:,None],a2[None,:,None],...))</code>，因此这些一维数组的长度必须相同（只有在这种特殊情况下，堆叠后的数组维数发生改变）</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">24</span>).reshape(<span class="number">3</span>,<span class="number">4</span>,<span class="number">2</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.arange(<span class="number">12</span>).reshape(<span class="number">3</span>,<span class="number">4</span>,<span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.dstack((a,b))</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">0</span>],</span><br><span class="line">        [ <span class="number">2</span>,  <span class="number">3</span>,  <span class="number">1</span>],</span><br><span class="line">        [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">2</span>],</span><br><span class="line">        [ <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">3</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">8</span>,  <span class="number">9</span>,  <span class="number">4</span>],</span><br><span class="line">        [<span class="number">10</span>, <span class="number">11</span>,  <span class="number">5</span>],</span><br><span class="line">        [<span class="number">12</span>, <span class="number">13</span>,  <span class="number">6</span>],</span><br><span class="line">        [<span class="number">14</span>, <span class="number">15</span>,  <span class="number">7</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">16</span>, <span class="number">17</span>,  <span class="number">8</span>],</span><br><span class="line">        [<span class="number">18</span>, <span class="number">19</span>,  <span class="number">9</span>],</span><br><span class="line">        [<span class="number">20</span>, <span class="number">21</span>, <span class="number">10</span>],</span><br><span class="line">        [<span class="number">22</span>, <span class="number">23</span>, <span class="number">11</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.arange(<span class="number">3</span>,<span class="number">6</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.dstack((a,b))</span><br><span class="line">array([[[<span class="number">0</span>, <span class="number">3</span>],</span><br><span class="line">        [<span class="number">1</span>, <span class="number">4</span>],</span><br><span class="line">        [<span class="number">2</span>, <span class="number">5</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.dstack((a[<span class="literal">None</span>,:,<span class="literal">None</span>],b[<span class="literal">None</span>,:,<span class="literal">None</span>]))</span><br><span class="line">array([[[<span class="number">0</span>, <span class="number">3</span>],</span><br><span class="line">        [<span class="number">1</span>, <span class="number">4</span>],</span><br><span class="line">        [<span class="number">2</span>, <span class="number">5</span>]]])</span><br></pre></td></tr></table></figure></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szdd-2"><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.split()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.split(arr, indices_or_sections, axis=0)</code><br>函数说明：<br>用于沿指定的轴<code>axis</code>将数组分割为多个子数组。参数<code>indices_or_sections</code>可以是整数，也可以是一个整数列表，分别表示不同的切割方式，当为整数<code>n</code>时，沿指定轴<code>axis</code>将数组<code>arr</code>平均切割为<code>n</code>份，如果该轴长度不足以均分为<code>n</code>等份时，将抛出异常，当为整数列表时，其中每一个整数表示一处切割的位置，譬如<code>[2,5,7]</code>表示分别在轴长刻度为2、5、7处进行切割（并得到四个子数组），具体的，第一份从刻度0开始但不包括刻度2，第二份从刻度2开始但不包括刻度5，第三份从刻度5开始但不包括刻度7，最后一份从刻度7开始直至最后（有可能是空数组），特别地，如果指定的切割位置超出轴长，则返回空的子数组而不会报错</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">9</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.split(a,<span class="number">3</span>)</span><br><span class="line">[array([<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>]), array([<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]), array([<span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>])]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.arange(<span class="number">16</span>).reshape(<span class="number">2</span>,-<span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">array([[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>,  <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">       [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>, <span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>, <span class="number">15</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.split(b,[<span class="number">2</span>,<span class="number">5</span>,<span class="number">7</span>],axis=<span class="number">1</span>)</span><br><span class="line">[array([[<span class="number">0</span>, <span class="number">1</span>],</span><br><span class="line">       [<span class="number">8</span>, <span class="number">9</span>]]), array([[ <span class="number">2</span>,  <span class="number">3</span>,  <span class="number">4</span>],</span><br><span class="line">       [<span class="number">10</span>, <span class="number">11</span>, <span class="number">12</span>]]), array([[ <span class="number">5</span>,  <span class="number">6</span>],</span><br><span class="line">       [<span class="number">13</span>, <span class="number">14</span>]]), array([[ <span class="number">7</span>],</span><br><span class="line">       [<span class="number">15</span>]])]</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.vsplit()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.vsplit(arr, indices_or_sections)</code><br>函数说明：<br>垂直分割，特指沿0轴切割，注意不能对一维数组执行该操作（至少是二维）</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">8</span>).reshape((<span class="number">4</span>,-<span class="number">1</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.vsplit(a,<span class="number">2</span>)</span><br><span class="line">[array([[<span class="number">0</span>, <span class="number">1</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">3</span>]]), array([[<span class="number">4</span>, <span class="number">5</span>],</span><br><span class="line">       [<span class="number">6</span>, <span class="number">7</span>]])]</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.hsplit()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.hsplit(arr, indices_or_sections)</code><br>函数说明：<br>水平分割，特指沿1轴切割，特别地，要对一维数组进行“水平”切割，相当于但不完全等同于<code>np.hsplit(arr[None,:], indices_or_sections)</code>（此处返回的子数组是二维的），返回的子数组仍是一维的</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.hsplit(np.arange(<span class="number">8</span>).reshape(<span class="number">2</span>,-<span class="number">1</span>),[<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line">[array([[<span class="number">0</span>, <span class="number">1</span>],</span><br><span class="line">       [<span class="number">4</span>, <span class="number">5</span>]]), array([[<span class="number">2</span>],</span><br><span class="line">       [<span class="number">6</span>]]), array([[<span class="number">3</span>],</span><br><span class="line">       [<span class="number">7</span>]])]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.hsplit(np.arange(<span class="number">8</span>),<span class="number">4</span>)</span><br><span class="line">[array([<span class="number">0</span>, <span class="number">1</span>]), array([<span class="number">2</span>, <span class="number">3</span>]), array([<span class="number">4</span>, <span class="number">5</span>]), array([<span class="number">6</span>, <span class="number">7</span>])]</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.dsplit()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.dsplit(arr, indices_or_sections)</code><br>函数说明：<br>深度分割，特指沿2轴切割，注意不对对一维或二维数组执行该操作（至少是三维）</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">24</span>).reshape(<span class="number">4</span>,<span class="number">3</span>,-<span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>],</span><br><span class="line">        [ <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">        [ <span class="number">4</span>,  <span class="number">5</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">        [ <span class="number">8</span>,  <span class="number">9</span>],</span><br><span class="line">        [<span class="number">10</span>, <span class="number">11</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">12</span>, <span class="number">13</span>],</span><br><span class="line">        [<span class="number">14</span>, <span class="number">15</span>],</span><br><span class="line">        [<span class="number">16</span>, <span class="number">17</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">18</span>, <span class="number">19</span>],</span><br><span class="line">        [<span class="number">20</span>, <span class="number">21</span>],</span><br><span class="line">        [<span class="number">22</span>, <span class="number">23</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.dsplit(a,<span class="number">2</span>)</span><br><span class="line">[array([[[ <span class="number">0</span>],</span><br><span class="line">        [ <span class="number">2</span>],</span><br><span class="line">        [ <span class="number">4</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">6</span>],</span><br><span class="line">        [ <span class="number">8</span>],</span><br><span class="line">        [<span class="number">10</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">12</span>],</span><br><span class="line">        [<span class="number">14</span>],</span><br><span class="line">        [<span class="number">16</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">18</span>],</span><br><span class="line">        [<span class="number">20</span>],</span><br><span class="line">        [<span class="number">22</span>]]]), array([[[ <span class="number">1</span>],</span><br><span class="line">        [ <span class="number">3</span>],</span><br><span class="line">        [ <span class="number">5</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">7</span>],</span><br><span class="line">        [ <span class="number">9</span>],</span><br><span class="line">        [<span class="number">11</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">13</span>],</span><br><span class="line">        [<span class="number">15</span>],</span><br><span class="line">        [<span class="number">17</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">19</span>],</span><br><span class="line">        [<span class="number">21</span>],</span><br><span class="line">        [<span class="number">23</span>]]])]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>_[<span class="number">0</span>].shape</span><br><span class="line">(<span class="number">4</span>, <span class="number">3</span>, <span class="number">1</span>)</span><br></pre></td></tr></table></figure></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="数组增删改查">数组增删改查</h2><div class="tabs" id="szzsgc"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#szzsgc-1"><code>np.append()</code></button></li><li class="tab"><button type="button" data-href="#szzsgc-2"><code>np.delete()</code></button></li><li class="tab"><button type="button" data-href="#szzsgc-3"><code>np.insert()</code></button></li><li class="tab"><button type="button" data-href="#szzsgc-4"><code>np.unique()</code></button></li><li class="tab"><button type="button" data-href="#szzsgc-5"><code>np.sort()</code></button></li><li class="tab"><button type="button" data-href="#szzsgc-6"><code>np.max()</code></button></li><li class="tab"><button type="button" data-href="#szzsgc-7"><code>np.min()</code></button></li><li class="tab"><button type="button" data-href="#szzsgc-8"><code>np.sum()</code></button></li><li class="tab"><button type="button" data-href="#szzsgc-9"><code>np.cumprod()</code></button></li><li class="tab"><button type="button" data-href="#szzsgc-10"><code>np.nonzero()</code></button></li><li class="tab"><button type="button" data-href="#szzsgc-11"><code>np.where()</code></button></li><li class="tab"><button type="button" data-href="#szzsgc-12"><code>np.extract()</code></button></li><li class="tab"><button type="button" data-href="#szzsgc-13"><code>np.place()</code></button></li><li class="tab"><button type="button" data-href="#szzsgc-14"><code>np.partition()</code></button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="szzsgc-1"><div class="note blue simple"><p><code>np.append(arr, values, axis=None)</code><br>函数说明：<br>用于沿指定轴<code>axis</code>向数组中追加数据<code>values</code>（多维数组对象），该操作基本同<code>np.concatenate()</code>函数，要追加的子数组<code>values</code>的形状和<code>arr</code>的形状除<code>axis</code>轴长度可以不一致外，其余轴长必须一致，另外当<code>axis</code>置为<code>None</code>时（默认值），会将一维化的<code>arr</code>和<code>values</code>连接成一个一维数组并返回</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.append(np.arange(<span class="number">4</span>).reshape(<span class="number">2</span>,-<span class="number">1</span>),np.arange(<span class="number">6</span>).reshape(<span class="number">2</span>,<span class="number">3</span>),axis=<span class="number">1</span>)</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">3</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.append(np.arange(<span class="number">4</span>).reshape(<span class="number">2</span>,-<span class="number">1</span>),np.arange(<span class="number">6</span>).reshape(<span class="number">2</span>,<span class="number">3</span>),axis=<span class="literal">None</span>)</span><br><span class="line">array([<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szzsgc-2"><div class="note blue simple"><p><code>np.delete(arr, obj, axis=None)</code><br>函数说明：<br>用于沿指定轴<code>axis</code>删除特定位置处的子数组。<code>obj</code>参数可以是整数（指定要删除的刻度位置处的元素）、切片或整数列表（指定要删除的多个刻度对应位置处的元素），特别地，当<code>axis</code>置为<code>None</code>时（默认值），将会首先“展平”（一维化）<code>arr</code>数组</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>arr=np.array([[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>],[<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>],[<span class="number">9</span>,<span class="number">10</span>,<span class="number">11</span>,<span class="number">12</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>arr</span><br><span class="line">array([[ <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>,  <span class="number">4</span>],</span><br><span class="line">       [ <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>],</span><br><span class="line">       [ <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>, <span class="number">12</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.delete(arr,[<span class="number">0</span>,<span class="number">2</span>]) <span class="comment">#axis为None，则先展平再删除</span></span><br><span class="line">array([ <span class="number">2</span>,  <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>, <span class="number">12</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.delete(arr,[<span class="number">0</span>,<span class="number">2</span>],axis=<span class="number">0</span>) <span class="comment">#沿着第0轴删除第0个元素和第2个元素</span></span><br><span class="line">array([[<span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.delete(arr,[<span class="number">0</span>,<span class="number">2</span>],axis=<span class="number">1</span>)</span><br><span class="line">array([[ <span class="number">2</span>,  <span class="number">4</span>],</span><br><span class="line">       [ <span class="number">6</span>,  <span class="number">8</span>],</span><br><span class="line">       [<span class="number">10</span>, <span class="number">12</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.delete(arr,<span class="built_in">slice</span>(<span class="number">0</span>,<span class="number">2</span>),axis=<span class="number">0</span>)</span><br><span class="line">array([[ <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>, <span class="number">12</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.delete(arr,np.s_[:<span class="number">2</span>],axis=<span class="number">0</span>) <span class="comment">#这种切片方式更简便，效果同上</span></span><br><span class="line">array([[ <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>, <span class="number">12</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.delete(arr,np.s_[::],axis=<span class="number">1</span>) <span class="comment">#表示全部删除，返回一个空数组</span></span><br><span class="line">array([], shape=(<span class="number">3</span>, <span class="number">0</span>), dtype=int32)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.delete(arr,np.s_[::<span class="number">2</span>],axis=<span class="number">1</span>)</span><br><span class="line">array([[ <span class="number">2</span>,  <span class="number">4</span>],</span><br><span class="line">       [ <span class="number">6</span>,  <span class="number">8</span>],</span><br><span class="line">       [<span class="number">10</span>, <span class="number">12</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.s_[::<span class="number">2</span>]</span><br><span class="line"><span class="built_in">slice</span>(<span class="literal">None</span>, <span class="literal">None</span>, <span class="number">2</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.delete(arr,np.ix_(np.<span class="built_in">max</span>(arr,axis=<span class="number">0</span>)&gt;<span class="number">10</span>),axis=<span class="number">1</span>) <span class="comment">#删除arr数组中那些列中最大值大于10的列</span></span><br><span class="line">array([[ <span class="number">1</span>,  <span class="number">2</span>],</span><br><span class="line">       [ <span class="number">5</span>,  <span class="number">6</span>],</span><br><span class="line">       [ <span class="number">9</span>, <span class="number">10</span>]])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szzsgc-3"><div class="note blue simple"><p><code>np.insert(arr, obj, values, axis=None)</code><br>函数说明：<br>此操作类似于<code>np.append()</code>，可以认为<code>append()</code>是<code>insert()</code>的一个特例（在末尾插入子数组），参数<code>obj</code>可以是整数（在指定刻度位置处插入子数组<code>values</code>）、切片对象或整数列表（在指定的多个刻度位置处插入子数组<code>values</code>），具体的，当<code>obj</code>为切片或整数列表时，<code>values</code>的形状和<code>arr</code>的形状除了满足“除<code>axis</code>所在轴长度可以不一致外其余轴长必须相同”的条件外（基本原则），还需要满足“<code>values</code>的<code>axis</code>所在轴长要么是1，要么是切片或整数列表的长度”的条件，当<code>obj</code>为整数时，<code>values</code>的形状除了需要满足基本原则，还需要满足“<code>values</code>的<code>axis</code>所在轴长必须为1”的条件，最后还要删除这个多余的长度为1的<code>axis</code>维（<code>squeeze()</code>），当<code>obj</code>为单整数序列时，<code>values</code>的形状只需要满足基本原则即可。特别地，<code>axis</code>参数可以为<code>None</code>时（默认值），表示会将<code>arr</code>一维化展开，其余的，正常按照前述规则，就像在一维数组中插入数据一样</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">12</span>).reshape(<span class="number">2</span>,<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>],</span><br><span class="line">        [ <span class="number">3</span>,  <span class="number">4</span>,  <span class="number">5</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>],</span><br><span class="line">        [ <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.insert(a,[<span class="number">0</span>,<span class="number">1</span>],np.arange(<span class="number">12</span>,<span class="number">18</span>).reshape(<span class="number">2</span>,<span class="number">1</span>,<span class="number">3</span>),<span class="number">1</span>) <span class="comment">#由于obj为整数列表，根据规则，插入数据values的形状只能是(2,1,3)或(2,2,3)，当其为(2,1,3)时，表示沿1轴来看，values相当于单个元素，当沿着1轴在刻度0位置处插入数据values后，似乎没有元素可供插入刻度1位置处了，这时会复制一份一模一样的数据插在刻度1位置处</span></span><br><span class="line">array([[[<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>],</span><br><span class="line">        [ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>],</span><br><span class="line">        [<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>],</span><br><span class="line">        [ <span class="number">3</span>,  <span class="number">4</span>,  <span class="number">5</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">15</span>, <span class="number">16</span>, <span class="number">17</span>],</span><br><span class="line">        [ <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>],</span><br><span class="line">        [<span class="number">15</span>, <span class="number">16</span>, <span class="number">17</span>],</span><br><span class="line">        [ <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.arange(<span class="number">12</span>,<span class="number">24</span>).reshape(<span class="number">2</span>,<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line">array([[[<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>],</span><br><span class="line">        [<span class="number">15</span>, <span class="number">16</span>, <span class="number">17</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">18</span>, <span class="number">19</span>, <span class="number">20</span>],</span><br><span class="line">        [<span class="number">21</span>, <span class="number">22</span>, <span class="number">23</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.insert(a,[<span class="number">0</span>,<span class="number">1</span>],_,<span class="number">1</span>) <span class="comment">#当values形状为(2,2,3)时，沿1轴来看，values相当于有两个元素，于是分别插在原数组的刻度0和刻度1位置处</span></span><br><span class="line">array([[[<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>],</span><br><span class="line">        [ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>],</span><br><span class="line">        [<span class="number">15</span>, <span class="number">16</span>, <span class="number">17</span>],</span><br><span class="line">        [ <span class="number">3</span>,  <span class="number">4</span>,  <span class="number">5</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">18</span>, <span class="number">19</span>, <span class="number">20</span>],</span><br><span class="line">        [ <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>],</span><br><span class="line">        [<span class="number">21</span>, <span class="number">22</span>, <span class="number">23</span>],</span><br><span class="line">        [ <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.insert(a,<span class="number">1</span>,np.arange(<span class="number">12</span>,<span class="number">18</span>).reshape(<span class="number">2</span>,<span class="number">3</span>),<span class="number">1</span>) <span class="comment">#此处obj是单整数，根据规则，插入数据values的形状只能是(2,1,3)，且要删除axis所在轴（长度为1），于是形状只能是(2,3)，为什么要减去这个维度呢？之前在介绍数值索引时说过，数值索引总是会导致维度减1，譬如给定一个二维数组，a=np.arange(12).reshape(3,4)，a[:,0]或a[0]的结果总是一维的，因此在向二维数组a的某列或某行赋值时，也必须是一维的，即a[:,0]=np.array([666,777,888])，如果写成a[:,0]=np.array([666,777,888])[:,None]就会出错，同理，此处的insert()函数在obj为单整数时候，也是这个道理</span></span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>],</span><br><span class="line">        [<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>],</span><br><span class="line">        [ <span class="number">3</span>,  <span class="number">4</span>,  <span class="number">5</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>],</span><br><span class="line">        [<span class="number">15</span>, <span class="number">16</span>, <span class="number">17</span>],</span><br><span class="line">        [ <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.insert(np.arange(<span class="number">12</span>).reshape(<span class="number">3</span>,<span class="number">4</span>),<span class="number">1</span>,np.array([<span class="number">666</span>,<span class="number">777</span>,<span class="number">888</span>]),<span class="number">1</span>) <span class="comment">#根据规则，插入数据values的形状只能是(3,1)，去除axis所在轴（长度为1），于是形状只能是(3,)</span></span><br><span class="line">array([[  <span class="number">0</span>, <span class="number">666</span>,   <span class="number">1</span>,   <span class="number">2</span>,   <span class="number">3</span>],</span><br><span class="line">       [  <span class="number">4</span>, <span class="number">777</span>,   <span class="number">5</span>,   <span class="number">6</span>,   <span class="number">7</span>],</span><br><span class="line">       [  <span class="number">8</span>, <span class="number">888</span>,   <span class="number">9</span>,  <span class="number">10</span>,  <span class="number">11</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.insert(a,[<span class="number">1</span>],np.arange(<span class="number">12</span>,<span class="number">18</span>).reshape(<span class="number">2</span>,<span class="number">1</span>,<span class="number">3</span>),<span class="number">1</span>) <span class="comment">#如果obj是单整数序列呢？这个比较特殊，此时插入数据values的形状为(2,x,3)即可，其中x任意</span></span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>],</span><br><span class="line">        [<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>],</span><br><span class="line">        [ <span class="number">3</span>,  <span class="number">4</span>,  <span class="number">5</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>],</span><br><span class="line">        [<span class="number">15</span>, <span class="number">16</span>, <span class="number">17</span>],</span><br><span class="line">        [ <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.insert(a,[<span class="number">1</span>],np.arange(<span class="number">12</span>,<span class="number">42</span>).reshape(<span class="number">2</span>,<span class="number">5</span>,<span class="number">3</span>),<span class="number">1</span>)</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>],</span><br><span class="line">        [<span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>],</span><br><span class="line">        [<span class="number">15</span>, <span class="number">16</span>, <span class="number">17</span>],</span><br><span class="line">        [<span class="number">18</span>, <span class="number">19</span>, <span class="number">20</span>],</span><br><span class="line">        [<span class="number">21</span>, <span class="number">22</span>, <span class="number">23</span>],</span><br><span class="line">        [<span class="number">24</span>, <span class="number">25</span>, <span class="number">26</span>],</span><br><span class="line">        [ <span class="number">3</span>,  <span class="number">4</span>,  <span class="number">5</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>],</span><br><span class="line">        [<span class="number">27</span>, <span class="number">28</span>, <span class="number">29</span>],</span><br><span class="line">        [<span class="number">30</span>, <span class="number">31</span>, <span class="number">32</span>],</span><br><span class="line">        [<span class="number">33</span>, <span class="number">34</span>, <span class="number">35</span>],</span><br><span class="line">        [<span class="number">36</span>, <span class="number">37</span>, <span class="number">38</span>],</span><br><span class="line">        [<span class="number">39</span>, <span class="number">40</span>, <span class="number">41</span>],</span><br><span class="line">        [ <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.flatten()</span><br><span class="line">array([ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>,  <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.insert(a,[<span class="number">2</span>,<span class="number">5</span>],[<span class="number">88</span>])</span><br><span class="line">array([ <span class="number">0</span>,  <span class="number">1</span>, <span class="number">88</span>,  <span class="number">2</span>,  <span class="number">3</span>,  <span class="number">4</span>, <span class="number">88</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.insert(a,[<span class="number">2</span>,<span class="number">5</span>],[<span class="number">66</span>,<span class="number">88</span>])</span><br><span class="line">array([ <span class="number">0</span>,  <span class="number">1</span>, <span class="number">66</span>,  <span class="number">2</span>,  <span class="number">3</span>,  <span class="number">4</span>, <span class="number">88</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.insert(a,[<span class="number">2</span>,<span class="number">5</span>,<span class="number">7</span>],[<span class="number">66</span>,<span class="number">88</span>,<span class="number">99</span>])</span><br><span class="line">array([ <span class="number">0</span>,  <span class="number">1</span>, <span class="number">66</span>,  <span class="number">2</span>,  <span class="number">3</span>,  <span class="number">4</span>, <span class="number">88</span>,  <span class="number">5</span>,  <span class="number">6</span>, <span class="number">99</span>,  <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.insert(a,np.s_[::<span class="number">3</span>],[<span class="number">66</span>,<span class="number">77</span>,<span class="number">88</span>,<span class="number">99</span>])</span><br><span class="line">array([<span class="number">66</span>,  <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>, <span class="number">77</span>,  <span class="number">3</span>,  <span class="number">4</span>,  <span class="number">5</span>, <span class="number">88</span>,  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>, <span class="number">99</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.insert(a,[<span class="number">2</span>],[<span class="number">66</span>,<span class="number">99</span>,<span class="number">100</span>])</span><br><span class="line">array([  <span class="number">0</span>,   <span class="number">1</span>,  <span class="number">66</span>,  <span class="number">99</span>, <span class="number">100</span>,   <span class="number">2</span>,   <span class="number">3</span>,   <span class="number">4</span>,   <span class="number">5</span>,   <span class="number">6</span>,   <span class="number">7</span>,   <span class="number">8</span>,   <span class="number">9</span>,</span><br><span class="line">        <span class="number">10</span>,  <span class="number">11</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.insert(a,<span class="number">2</span>,[<span class="number">66</span>,<span class="number">99</span>,<span class="number">100</span>]) <span class="comment">#这里也比较特殊，对于一维，obj为单整数，不仅可以插入[666]（长度为1的一维数组），也可以插入[666,777,888]（任意长度）</span></span><br><span class="line">array([  <span class="number">0</span>,   <span class="number">1</span>,  <span class="number">66</span>,  <span class="number">99</span>, <span class="number">100</span>,   <span class="number">2</span>,   <span class="number">3</span>,   <span class="number">4</span>,   <span class="number">5</span>,   <span class="number">6</span>,   <span class="number">7</span>,   <span class="number">8</span>,   <span class="number">9</span>,</span><br><span class="line">        <span class="number">10</span>,  <span class="number">11</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.insert(a,<span class="number">2</span>,[<span class="number">66</span>])</span><br><span class="line">array([ <span class="number">0</span>,  <span class="number">1</span>, <span class="number">66</span>,  <span class="number">2</span>,  <span class="number">3</span>,  <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szzsgc-4"><div class="note blue simple"><p><code>np.unique(arr, return_index=False, return_inverse=False, return_counts=False, axis=None)</code><br>函数说明：<br>用于去除数组<code>arr</code>中的重复元素，返回以升序排序的去重值数组（由于<code>axis</code>默认为<code>None</code>，因此会首先一维化<code>arr</code>，并最终返回一个去重的一维数组）<br>参数说明：</p><ul><li><code>axis</code>：沿<code>axis</code>轴对数组元素进行去重，举个例子，当<code>arr</code>为二维数组，<code>axis</code>为<code>1</code>，表示要去重的元素是二维数组中的列向量，反之，<code>axis</code>为0，表示要去重的元素是二维数组中的行向量。<code>axis</code>置为<code>None</code>时，表示将<code>arr</code>一维化</li><li><code>return_index</code>：若为<code>True</code>，同时返回去重数组中元素在原始数组中的位置下标</li><li><code>return_inverse</code>：若为<code>True</code>，同时返回原始数组中元素在去重数组中的位置下标</li><li><code>return_counts</code>：若为<code>True</code>，同时返回去重数组中元素在原始数组中出现的次数</li></ul></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.array([<span class="number">6</span>,<span class="number">7</span>,<span class="number">6</span>,<span class="number">6</span>,<span class="number">5</span>,<span class="number">2</span>,<span class="number">9</span>,<span class="number">8</span>,<span class="number">2</span>,<span class="number">5</span>]).reshape(<span class="number">2</span>,-<span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">6</span>, <span class="number">7</span>, <span class="number">6</span>, <span class="number">6</span>, <span class="number">5</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">9</span>, <span class="number">8</span>, <span class="number">2</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.unique(a)</span><br><span class="line">array([<span class="number">2</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>r,ind=np.unique(a,axis=<span class="number">1</span>,return_index=<span class="literal">True</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>r</span><br><span class="line">array([[<span class="number">5</span>, <span class="number">6</span>, <span class="number">6</span>, <span class="number">7</span>],</span><br><span class="line">       [<span class="number">5</span>, <span class="number">2</span>, <span class="number">8</span>, <span class="number">9</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>ind</span><br><span class="line">array([<span class="number">4</span>, <span class="number">0</span>, <span class="number">2</span>, <span class="number">1</span>], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>r,ind,cs=np.unique(a,axis=<span class="number">1</span>,return_inverse=<span class="literal">True</span>,return_counts=<span class="literal">True</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>r</span><br><span class="line">array([[<span class="number">5</span>, <span class="number">6</span>, <span class="number">6</span>, <span class="number">7</span>],</span><br><span class="line">       [<span class="number">5</span>, <span class="number">2</span>, <span class="number">8</span>, <span class="number">9</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>ind</span><br><span class="line">array([<span class="number">1</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">0</span>], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>cs</span><br><span class="line">array([<span class="number">1</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">1</span>], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>r[:,ind] <span class="comment">#（一维）花式索引重构原始数组</span></span><br><span class="line">array([[<span class="number">6</span>, <span class="number">7</span>, <span class="number">6</span>, <span class="number">6</span>, <span class="number">5</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">9</span>, <span class="number">8</span>, <span class="number">2</span>, <span class="number">5</span>]])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szzsgc-5"><div class="note blue simple"><p><code>np.sort(a, axis=-1, kind='quicksort', order=None)</code><br>函数说明：<br>用于沿指定轴对输入数组进行排序。默认是沿着最后一个轴（<code>axis=-1</code>）进行排序，如果<code>axis</code>置为<code>None</code>，则先一维化展平数组<code>a</code>，然后再进行排序（最终将返回一个一维数组），<code>kind</code>参数指定排序算法，还可取值<code>mergesort</code>（归并排序）和<code>heapsort</code>（堆排序），此处的<code>order</code>参数并非有关内存布局，而是用于自定义结构化数据类型时，设置不同字段参与排序时的优先级（<code>order</code>列表中字段的优先级从左至右依次降低），没有出现在<code>order</code>的字段，其优先级低于<code>order</code>中的字段，且按照定义结构化数据类型<code>dtype</code>时的字段顺序依次降低</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a = np.array([[<span class="number">1</span>,<span class="number">4</span>],[<span class="number">3</span>,<span class="number">1</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">4</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">1</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(a)</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">4</span>],</span><br><span class="line">       [<span class="number">1</span>, <span class="number">3</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(a,axis=<span class="number">1</span>)</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">4</span>],</span><br><span class="line">       [<span class="number">1</span>, <span class="number">3</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(a,axis=<span class="number">0</span>)</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">1</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">4</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(a,axis=<span class="literal">None</span>)</span><br><span class="line">array([<span class="number">1</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">4</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>dtype = [(<span class="string">&#x27;name&#x27;</span>, <span class="string">&#x27;S10&#x27;</span>), (<span class="string">&#x27;height&#x27;</span>, <span class="built_in">float</span>), (<span class="string">&#x27;age&#x27;</span>, <span class="built_in">int</span>)]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>values = [(<span class="string">&#x27;Arthur&#x27;</span>, <span class="number">1.8</span>, <span class="number">41</span>), (<span class="string">&#x27;Lancelot&#x27;</span>, <span class="number">1.9</span>, <span class="number">38</span>), (<span class="string">&#x27;Galahad&#x27;</span>, <span class="number">1.7</span>, <span class="number">38</span>)]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a = np.array(values, dtype=dtype)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(a, order=<span class="string">&#x27;height&#x27;</span>)</span><br><span class="line">array([(<span class="string">b&#x27;Galahad&#x27;</span>, <span class="number">1.7</span>, <span class="number">38</span>), (<span class="string">b&#x27;Arthur&#x27;</span>, <span class="number">1.8</span>, <span class="number">41</span>),</span><br><span class="line">       (<span class="string">b&#x27;Lancelot&#x27;</span>, <span class="number">1.9</span>, <span class="number">38</span>)],</span><br><span class="line">      dtype=[(<span class="string">&#x27;name&#x27;</span>, <span class="string">&#x27;S10&#x27;</span>), (<span class="string">&#x27;height&#x27;</span>, <span class="string">&#x27;&lt;f8&#x27;</span>), (<span class="string">&#x27;age&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(a, order=[<span class="string">&#x27;age&#x27;</span>, <span class="string">&#x27;height&#x27;</span>])</span><br><span class="line">array([(<span class="string">b&#x27;Galahad&#x27;</span>, <span class="number">1.7</span>, <span class="number">38</span>), (<span class="string">b&#x27;Lancelot&#x27;</span>, <span class="number">1.9</span>, <span class="number">38</span>),</span><br><span class="line">       (<span class="string">b&#x27;Arthur&#x27;</span>, <span class="number">1.8</span>, <span class="number">41</span>)],</span><br><span class="line">      dtype=[(<span class="string">&#x27;name&#x27;</span>, <span class="string">&#x27;S10&#x27;</span>), (<span class="string">&#x27;height&#x27;</span>, <span class="string">&#x27;&lt;f8&#x27;</span>), (<span class="string">&#x27;age&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(a)</span><br><span class="line">array([(<span class="string">b&#x27;Arthur&#x27;</span>, <span class="number">1.8</span>, <span class="number">41</span>), (<span class="string">b&#x27;Galahad&#x27;</span>, <span class="number">1.7</span>, <span class="number">38</span>),</span><br><span class="line">       (<span class="string">b&#x27;Lancelot&#x27;</span>, <span class="number">1.9</span>, <span class="number">38</span>)],</span><br><span class="line">      dtype=[(<span class="string">&#x27;name&#x27;</span>, <span class="string">&#x27;S10&#x27;</span>), (<span class="string">&#x27;height&#x27;</span>, <span class="string">&#x27;&lt;f8&#x27;</span>), (<span class="string">&#x27;age&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="string">b&#x27;Arthur&#x27;</span>&lt;<span class="string">b&#x27;Galahad&#x27;</span>&lt;<span class="string">b&#x27;Lancelot&#x27;</span></span><br><span class="line"><span class="literal">True</span></span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.argsort()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.argsort(a, axis=-1, kind='quicksort', order=None)</code><br>函数说明：<br>函数返回的是数组值从小到大排列的下标序列，参数同<code>np.sort()</code></p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>x=np.random.randint(<span class="number">0</span>,<span class="number">24</span>,<span class="number">6</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>y = np.argsort(x)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x[y] <span class="comment">#（一维）花式索引构造升序排列的结果</span></span><br><span class="line">array([ <span class="number">4</span>, <span class="number">13</span>, <span class="number">16</span>, <span class="number">16</span>, <span class="number">21</span>, <span class="number">23</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x = np.array([[<span class="number">0</span>, <span class="number">3</span>], [<span class="number">2</span>, <span class="number">2</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">2</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.argsort(x, axis=<span class="number">0</span>)</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>],</span><br><span class="line">       [<span class="number">1</span>, <span class="number">0</span>]], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x[_,np.broadcast_to(np.arange(x.shape[<span class="number">1</span>]),x.shape)] <span class="comment">#全坐标索引构造二维数组沿0轴升序排列的结果</span></span><br><span class="line">array([[<span class="number">0</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">3</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.argsort(x, axis=<span class="number">1</span>)</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>],</span><br><span class="line">       [<span class="number">0</span>, <span class="number">1</span>]], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x[np.broadcast_to(np.arange(x.shape[<span class="number">0</span>])[:,<span class="literal">None</span>],x.shape),_] <span class="comment">#全坐标索引构造二维数组沿1轴升序排列的结果</span></span><br><span class="line">array([[<span class="number">0</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">2</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.argsort(x, axis=<span class="literal">None</span>)</span><br><span class="line">array([<span class="number">0</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x.flatten()[_]</span><br><span class="line">array([<span class="number">0</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>pos = np.unravel_index(np.argsort(x, axis=<span class="literal">None</span>), x.shape)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x[pos] <span class="comment">#全坐标索引</span></span><br><span class="line">array([<span class="number">0</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x = np.array([(<span class="number">1</span>, <span class="number">0</span>), (<span class="number">0</span>, <span class="number">1</span>)], dtype=[(<span class="string">&#x27;x&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>), (<span class="string">&#x27;y&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.argsort(x, order=(<span class="string">&#x27;x&#x27;</span>,<span class="string">&#x27;y&#x27;</span>))</span><br><span class="line">array([<span class="number">1</span>, <span class="number">0</span>], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.argsort(x, order=(<span class="string">&#x27;y&#x27;</span>,<span class="string">&#x27;x&#x27;</span>))</span><br><span class="line">array([<span class="number">0</span>, <span class="number">1</span>], dtype=int64)</span><br></pre></td></tr></table></figure>上面使用了一个叫做<code>unravel_index(indices, dims, order='C')</code>的函数，是干嘛用的？将一个多维数组按C或F风格（<code>order</code>参数）“展平”为一维数组后，可以通过取值范围为<code>[0,len(arr.flat)-1]</code>的下标<code>i</code>来索引任意元素，那么现在的下标索引<code>i</code>（指定参数<code>indices</code>，其也可以是一个整数列表）所指向的数组元素在原数组（指定形状参数<code>dims</code>）中的位置坐标又是几何？函数<code>np.unravel_index()</code>就是为了解决这个问题的，看个例子：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">6</span>).reshape(<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.flatten(order=<span class="string">&#x27;C&#x27;</span>) <span class="comment">#按C风格展平，其中第1、3、5个元素在原始数组中的坐标为：np.unravel_index([1,3,5],(2,3))</span></span><br><span class="line">array([<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.flatten(order=<span class="string">&#x27;F&#x27;</span>) <span class="comment">#按F风格展平，其中第1、3、5个元素在原始数组中的坐标为：np.unravel_index([1,3,5],(2,3),order=&#x27;F&#x27;)</span></span><br><span class="line">array([<span class="number">0</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">4</span>, <span class="number">2</span>, <span class="number">5</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.unravel_index(<span class="number">3</span>,(<span class="number">2</span>,<span class="number">3</span>))</span><br><span class="line">(<span class="number">1</span>, <span class="number">0</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.unravel_index([<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>],(<span class="number">2</span>,<span class="number">3</span>))</span><br><span class="line">(array([<span class="number">0</span>, <span class="number">1</span>, <span class="number">1</span>], dtype=int64), array([<span class="number">1</span>, <span class="number">0</span>, <span class="number">2</span>], dtype=int64))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.unravel_index([<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>],(<span class="number">2</span>,<span class="number">3</span>),order=<span class="string">&#x27;F&#x27;</span>)</span><br><span class="line">(array([<span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>], dtype=int64), array([<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>], dtype=int64))</span><br></pre></td></tr></table></figure>上面列举了一维数组和二维数组的情况下如何根据<code>argsort()</code>的结果构造<code>sort()</code>的结果，下面再看看三维数组的情况：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>x=np.random.randint(<span class="number">0</span>,<span class="number">100</span>,<span class="number">24</span>).reshape(<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(x,axis=-<span class="number">1</span>) <span class="comment">#等同于np.sort(x,axis=2)</span></span><br><span class="line">array([[[<span class="number">39</span>, <span class="number">57</span>, <span class="number">60</span>, <span class="number">99</span>],</span><br><span class="line">        [<span class="number">26</span>, <span class="number">35</span>, <span class="number">38</span>, <span class="number">85</span>],</span><br><span class="line">        [ <span class="number">8</span>, <span class="number">12</span>, <span class="number">35</span>, <span class="number">85</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">30</span>, <span class="number">66</span>, <span class="number">86</span>, <span class="number">88</span>],</span><br><span class="line">        [<span class="number">21</span>, <span class="number">49</span>, <span class="number">66</span>, <span class="number">80</span>],</span><br><span class="line">        [ <span class="number">3</span>, <span class="number">45</span>, <span class="number">47</span>, <span class="number">70</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.argsort(x,axis=-<span class="number">1</span>)</span><br><span class="line">array([[[<span class="number">3</span>, <span class="number">2</span>, <span class="number">0</span>, <span class="number">1</span>],</span><br><span class="line">        [<span class="number">3</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">0</span>],</span><br><span class="line">        [<span class="number">0</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">3</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">0</span>],</span><br><span class="line">        [<span class="number">3</span>, <span class="number">0</span>, <span class="number">2</span>, <span class="number">1</span>],</span><br><span class="line">        [<span class="number">0</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">1</span>]]], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x[np.broadcast_to(np.arange(<span class="number">2</span>)[:,<span class="literal">None</span>,<span class="literal">None</span>],x.shape),np.broadcast_to(np.arange(<span class="number">3</span>)[<span class="literal">None</span>,:,<span class="literal">None</span>],x.shape),_] <span class="comment">#全坐标索引构造三维数组沿2轴升序排列的结果</span></span><br><span class="line">array([[[<span class="number">39</span>, <span class="number">57</span>, <span class="number">60</span>, <span class="number">99</span>],</span><br><span class="line">        [<span class="number">26</span>, <span class="number">35</span>, <span class="number">38</span>, <span class="number">85</span>],</span><br><span class="line">        [ <span class="number">8</span>, <span class="number">12</span>, <span class="number">35</span>, <span class="number">85</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">30</span>, <span class="number">66</span>, <span class="number">86</span>, <span class="number">88</span>],</span><br><span class="line">        [<span class="number">21</span>, <span class="number">49</span>, <span class="number">66</span>, <span class="number">80</span>],</span><br><span class="line">        [ <span class="number">3</span>, <span class="number">45</span>, <span class="number">47</span>, <span class="number">70</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(x,axis=<span class="number">1</span>)</span><br><span class="line">array([[[ <span class="number">8</span>, <span class="number">35</span>, <span class="number">12</span>, <span class="number">26</span>],</span><br><span class="line">        [<span class="number">60</span>, <span class="number">38</span>, <span class="number">35</span>, <span class="number">39</span>],</span><br><span class="line">        [<span class="number">85</span>, <span class="number">99</span>, <span class="number">57</span>, <span class="number">85</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">3</span>, <span class="number">70</span>, <span class="number">30</span>, <span class="number">21</span>],</span><br><span class="line">        [<span class="number">49</span>, <span class="number">80</span>, <span class="number">47</span>, <span class="number">45</span>],</span><br><span class="line">        [<span class="number">88</span>, <span class="number">86</span>, <span class="number">66</span>, <span class="number">66</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.argsort(x,axis=<span class="number">1</span>)</span><br><span class="line">array([[[<span class="number">2</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">1</span>],</span><br><span class="line">        [<span class="number">0</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">0</span>],</span><br><span class="line">        [<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">2</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">2</span>, <span class="number">2</span>, <span class="number">0</span>, <span class="number">1</span>],</span><br><span class="line">        [<span class="number">1</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">2</span>],</span><br><span class="line">        [<span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>]]], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x[np.broadcast_to(np.arange(<span class="number">2</span>)[:,<span class="literal">None</span>,<span class="literal">None</span>],x.shape),_,np.broadcast_to(np.arange(<span class="number">4</span>)[<span class="literal">None</span>,<span class="literal">None</span>,:],x.shape)] <span class="comment">#全坐标索引构造三维数组沿1轴升序排列的结果</span></span><br><span class="line">array([[[ <span class="number">8</span>, <span class="number">35</span>, <span class="number">12</span>, <span class="number">26</span>],</span><br><span class="line">        [<span class="number">60</span>, <span class="number">38</span>, <span class="number">35</span>, <span class="number">39</span>],</span><br><span class="line">        [<span class="number">85</span>, <span class="number">99</span>, <span class="number">57</span>, <span class="number">85</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">3</span>, <span class="number">70</span>, <span class="number">30</span>, <span class="number">21</span>],</span><br><span class="line">        [<span class="number">49</span>, <span class="number">80</span>, <span class="number">47</span>, <span class="number">45</span>],</span><br><span class="line">        [<span class="number">88</span>, <span class="number">86</span>, <span class="number">66</span>, <span class="number">66</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(x,axis=<span class="number">0</span>)</span><br><span class="line">array([[[<span class="number">60</span>, <span class="number">86</span>, <span class="number">30</span>, <span class="number">39</span>],</span><br><span class="line">        [<span class="number">49</span>, <span class="number">38</span>, <span class="number">35</span>, <span class="number">21</span>],</span><br><span class="line">        [ <span class="number">3</span>, <span class="number">35</span>, <span class="number">12</span>, <span class="number">45</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">88</span>, <span class="number">99</span>, <span class="number">57</span>, <span class="number">66</span>],</span><br><span class="line">        [<span class="number">85</span>, <span class="number">80</span>, <span class="number">66</span>, <span class="number">26</span>],</span><br><span class="line">        [ <span class="number">8</span>, <span class="number">70</span>, <span class="number">47</span>, <span class="number">85</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.argsort(x,axis=<span class="number">0</span>)</span><br><span class="line">array([[[<span class="number">0</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">0</span>],</span><br><span class="line">        [<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>],</span><br><span class="line">        [<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>],</span><br><span class="line">        [<span class="number">0</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">0</span>],</span><br><span class="line">        [<span class="number">0</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">0</span>]]], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x[_,np.broadcast_to(np.arange(<span class="number">3</span>)[<span class="literal">None</span>,:,<span class="literal">None</span>],x.shape),np.broadcast_to(np.arange(<span class="number">4</span>)[<span class="literal">None</span>,<span class="literal">None</span>,:],x.shape)] <span class="comment">#全坐标索引构造三维数组沿0轴升序排列的结果</span></span><br><span class="line">array([[[<span class="number">60</span>, <span class="number">86</span>, <span class="number">30</span>, <span class="number">39</span>],</span><br><span class="line">        [<span class="number">49</span>, <span class="number">38</span>, <span class="number">35</span>, <span class="number">21</span>],</span><br><span class="line">        [ <span class="number">3</span>, <span class="number">35</span>, <span class="number">12</span>, <span class="number">45</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">88</span>, <span class="number">99</span>, <span class="number">57</span>, <span class="number">66</span>],</span><br><span class="line">        [<span class="number">85</span>, <span class="number">80</span>, <span class="number">66</span>, <span class="number">26</span>],</span><br><span class="line">        [ <span class="number">8</span>, <span class="number">70</span>, <span class="number">47</span>, <span class="number">85</span>]]])</span><br></pre></td></tr></table></figure>上述写法还是太麻烦，可以借助<code>np.meshgrid()</code>简化坐标分量的构造（试问，还有更好更简便的写法吗？）：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>y,x,z=np.meshgrid(<span class="built_in">range</span>(<span class="number">3</span>),<span class="built_in">range</span>(<span class="number">2</span>),<span class="built_in">range</span>(<span class="number">4</span>)) <span class="comment">#三个坐标分量，要通过meshgrid()构造任意形状多维数组的坐标分量，譬如shape=(s0,s1,s2,...,sn)，则有axis1,axis0,axis2,...,axisn=meshgrid(range(s1),range(s0),range(s3),...,range(sn))，即第0轴和第1轴比较特殊，是顺序反过来的</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(a,axis=-<span class="number">1</span>)</span><br><span class="line">array([[[<span class="number">33</span>, <span class="number">71</span>, <span class="number">90</span>, <span class="number">90</span>],</span><br><span class="line">        [<span class="number">41</span>, <span class="number">51</span>, <span class="number">56</span>, <span class="number">71</span>],</span><br><span class="line">        [<span class="number">23</span>, <span class="number">66</span>, <span class="number">70</span>, <span class="number">87</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">32</span>, <span class="number">41</span>, <span class="number">62</span>, <span class="number">86</span>],</span><br><span class="line">        [<span class="number">48</span>, <span class="number">71</span>, <span class="number">75</span>, <span class="number">80</span>],</span><br><span class="line">        [<span class="number">54</span>, <span class="number">73</span>, <span class="number">83</span>, <span class="number">92</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.argsort(a,axis=-<span class="number">1</span>)</span><br><span class="line">array([[[<span class="number">2</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">3</span>],</span><br><span class="line">        [<span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">0</span>],</span><br><span class="line">        [<span class="number">2</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">3</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">3</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">0</span>],</span><br><span class="line">        [<span class="number">0</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">3</span>],</span><br><span class="line">        [<span class="number">2</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">0</span>]]], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[x,y,_]</span><br><span class="line">array([[[<span class="number">33</span>, <span class="number">71</span>, <span class="number">90</span>, <span class="number">90</span>],</span><br><span class="line">        [<span class="number">41</span>, <span class="number">51</span>, <span class="number">56</span>, <span class="number">71</span>],</span><br><span class="line">        [<span class="number">23</span>, <span class="number">66</span>, <span class="number">70</span>, <span class="number">87</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">32</span>, <span class="number">41</span>, <span class="number">62</span>, <span class="number">86</span>],</span><br><span class="line">        [<span class="number">48</span>, <span class="number">71</span>, <span class="number">75</span>, <span class="number">80</span>],</span><br><span class="line">        [<span class="number">54</span>, <span class="number">73</span>, <span class="number">83</span>, <span class="number">92</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(a,axis=<span class="number">1</span>)</span><br><span class="line">array([[[<span class="number">66</span>, <span class="number">56</span>, <span class="number">23</span>, <span class="number">51</span>],</span><br><span class="line">        [<span class="number">71</span>, <span class="number">70</span>, <span class="number">33</span>, <span class="number">87</span>],</span><br><span class="line">        [<span class="number">71</span>, <span class="number">90</span>, <span class="number">41</span>, <span class="number">90</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">48</span>, <span class="number">41</span>, <span class="number">54</span>, <span class="number">32</span>],</span><br><span class="line">        [<span class="number">86</span>, <span class="number">73</span>, <span class="number">62</span>, <span class="number">80</span>],</span><br><span class="line">        [<span class="number">92</span>, <span class="number">75</span>, <span class="number">71</span>, <span class="number">83</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.argsort(a,axis=<span class="number">1</span>)</span><br><span class="line">array([[[<span class="number">2</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">1</span>],</span><br><span class="line">        [<span class="number">0</span>, <span class="number">2</span>, <span class="number">0</span>, <span class="number">2</span>],</span><br><span class="line">        [<span class="number">1</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">1</span>, <span class="number">0</span>, <span class="number">2</span>, <span class="number">0</span>],</span><br><span class="line">        [<span class="number">0</span>, <span class="number">2</span>, <span class="number">0</span>, <span class="number">1</span>],</span><br><span class="line">        [<span class="number">2</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">2</span>]]], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[x,_,z]</span><br><span class="line">array([[[<span class="number">66</span>, <span class="number">56</span>, <span class="number">23</span>, <span class="number">51</span>],</span><br><span class="line">        [<span class="number">71</span>, <span class="number">70</span>, <span class="number">33</span>, <span class="number">87</span>],</span><br><span class="line">        [<span class="number">71</span>, <span class="number">90</span>, <span class="number">41</span>, <span class="number">90</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">48</span>, <span class="number">41</span>, <span class="number">54</span>, <span class="number">32</span>],</span><br><span class="line">        [<span class="number">86</span>, <span class="number">73</span>, <span class="number">62</span>, <span class="number">80</span>],</span><br><span class="line">        [<span class="number">92</span>, <span class="number">75</span>, <span class="number">71</span>, <span class="number">83</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(a,axis=<span class="number">0</span>)</span><br><span class="line">array([[[<span class="number">71</span>, <span class="number">41</span>, <span class="number">33</span>, <span class="number">32</span>],</span><br><span class="line">        [<span class="number">48</span>, <span class="number">56</span>, <span class="number">41</span>, <span class="number">51</span>],</span><br><span class="line">        [<span class="number">66</span>, <span class="number">70</span>, <span class="number">23</span>, <span class="number">83</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">86</span>, <span class="number">90</span>, <span class="number">62</span>, <span class="number">90</span>],</span><br><span class="line">        [<span class="number">71</span>, <span class="number">75</span>, <span class="number">71</span>, <span class="number">80</span>],</span><br><span class="line">        [<span class="number">92</span>, <span class="number">73</span>, <span class="number">54</span>, <span class="number">87</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.argsort(a,axis=<span class="number">0</span>)</span><br><span class="line">array([[[<span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="number">1</span>],</span><br><span class="line">        [<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>],</span><br><span class="line">        [<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">1</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>],</span><br><span class="line">        [<span class="number">0</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>],</span><br><span class="line">        [<span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">0</span>]]], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[_,y,z]</span><br><span class="line">array([[[<span class="number">71</span>, <span class="number">41</span>, <span class="number">33</span>, <span class="number">32</span>],</span><br><span class="line">        [<span class="number">48</span>, <span class="number">56</span>, <span class="number">41</span>, <span class="number">51</span>],</span><br><span class="line">        [<span class="number">66</span>, <span class="number">70</span>, <span class="number">23</span>, <span class="number">83</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">86</span>, <span class="number">90</span>, <span class="number">62</span>, <span class="number">90</span>],</span><br><span class="line">        [<span class="number">71</span>, <span class="number">75</span>, <span class="number">71</span>, <span class="number">80</span>],</span><br><span class="line">        [<span class="number">92</span>, <span class="number">73</span>, <span class="number">54</span>, <span class="number">87</span>]]])</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.msort()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.msort(a)</code><br>函数说明：<br>用于沿数组<code>a</code>的第0轴进行排序，相当于<code>np.sort(a, axis=0)</code></p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.random.randint(<span class="number">0</span>,<span class="number">24</span>,<span class="number">12</span>).reshape(<span class="number">3</span>,-<span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">15</span>,  <span class="number">8</span>, <span class="number">23</span>, <span class="number">12</span>],</span><br><span class="line">       [<span class="number">14</span>,  <span class="number">1</span>, <span class="number">17</span>, <span class="number">13</span>],</span><br><span class="line">       [ <span class="number">5</span>,  <span class="number">4</span>, <span class="number">14</span>,  <span class="number">8</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.msort(a)</span><br><span class="line">array([[ <span class="number">5</span>,  <span class="number">1</span>, <span class="number">14</span>,  <span class="number">8</span>],</span><br><span class="line">       [<span class="number">14</span>,  <span class="number">4</span>, <span class="number">17</span>, <span class="number">12</span>],</span><br><span class="line">       [<span class="number">15</span>,  <span class="number">8</span>, <span class="number">23</span>, <span class="number">13</span>]])</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.lexsort()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.lexsort(keys, axis=-1)</code><br>函数说明：<br>参数<code>keys</code>是一个元组（越靠后优先级越高），包含多个（至少两个）排序键（一维序列），<code>lexsort()</code>将会执行多重排序，其实就相当于<code>sorted(zip(keys[::-1]),key=lambda x:x)</code>，只不过<code>lexsort()</code>返回的是排序后的下标索引列表</p></div>看个例子，现有一个学生姓名列表，另外还有这些学生对应的语文成绩列表、数学成绩列表、英语成绩列表以及语数英总分列表，要对学生进行优劣排序，规则：首先按照总分降序排序，当总分相同时按照语文成绩降序排序，如果又出现相同，再依次按照数学、英语成绩降序排序，根据这些成绩排序结果，最终将得到学生的优劣先后，代码如下：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>names=[<span class="string">&#x27;daiyang&#x27;</span>,<span class="string">&#x27;daixiaodong&#x27;</span>,<span class="string">&#x27;zhouqifei&#x27;</span>,<span class="string">&#x27;dongjiazhou&#x27;</span>,<span class="string">&#x27;liushaoliang&#x27;</span>,<span class="string">&#x27;zhouzifeng&#x27;</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>totals=[<span class="number">337</span>,<span class="number">333</span>,<span class="number">345</span>,<span class="number">345</span>,<span class="number">337</span>,<span class="number">333</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>chinese=[<span class="number">103</span>,<span class="number">90</span>,<span class="number">108</span>,<span class="number">108</span>,<span class="number">103</span>,<span class="number">86</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>math=[<span class="number">156</span>,<span class="number">162</span>,<span class="number">155</span>,<span class="number">135</span>,<span class="number">156</span>,<span class="number">160</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>english=[<span class="number">78</span>,<span class="number">81</span>,<span class="number">82</span>,<span class="number">102</span>,<span class="number">78</span>,<span class="number">87</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>inds=np.lexsort((english,math,chinese,totals))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>inds</span><br><span class="line">array([<span class="number">5</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="number">4</span>, <span class="number">3</span>, <span class="number">2</span>], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.array(names)[inds] <span class="comment">#花式索引，这里其实是升序排列</span></span><br><span class="line">array([<span class="string">&#x27;zhouzifeng&#x27;</span>, <span class="string">&#x27;daixiaodong&#x27;</span>, <span class="string">&#x27;daiyang&#x27;</span>, <span class="string">&#x27;liushaoliang&#x27;</span>,</span><br><span class="line">       <span class="string">&#x27;dongjiazhou&#x27;</span>, <span class="string">&#x27;zhouqifei&#x27;</span>], dtype=<span class="string">&#x27;&lt;U12&#x27;</span>)</span><br></pre></td></tr></table></figure>也可以自定义结构化数组，并利用`np.argsort()`实现：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">t=list2structarray(<span class="built_in">list</span>(<span class="built_in">zip</span>(totals,chinese,math,english)),dtype=<span class="string">&#x27;i4,i4,i4,i4&#x27;</span>)</span><br><span class="line">inds=np.argsort(t)[::-<span class="number">1</span>] <span class="comment">#按降序排列的下标索引</span></span><br><span class="line"><span class="built_in">print</span>(inds)</span><br><span class="line"><span class="built_in">print</span>(np.array(names)[inds])</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">[2 3 4 0 1 5]</span></span><br><span class="line"><span class="string">[&#x27;zhouqifei&#x27; &#x27;dongjiazhou&#x27; &#x27;liushaoliang&#x27; &#x27;daiyang&#x27; &#x27;daixiaodong&#x27;</span></span><br><span class="line"><span class="string"> &#x27;zhouzifeng&#x27;]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.sort_complex()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.sort_complex(a)</code><br>函数说明:<br>对复数数组按照先实部后虚部的顺序进行排序，注意是沿最后一维进行排序</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a = np.sort_complex([<span class="number">1</span> + <span class="number">2j</span>, <span class="number">2</span> - <span class="number">1j</span>, <span class="number">3</span> - <span class="number">2j</span>, <span class="number">3</span> - <span class="number">3j</span>, <span class="number">3</span> + <span class="number">5j</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.random.shuffle(a)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([<span class="number">3.</span>-<span class="number">2.j</span>, <span class="number">2.</span>-<span class="number">1.j</span>, <span class="number">3.</span>+<span class="number">5.j</span>, <span class="number">6.</span>+<span class="number">2.j</span>, <span class="number">6.</span>+<span class="number">1.j</span>, <span class="number">3.</span>-<span class="number">3.j</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=a.reshape(<span class="number">2</span>,-<span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">array([[<span class="number">3.</span>-<span class="number">2.j</span>, <span class="number">2.</span>-<span class="number">1.j</span>, <span class="number">3.</span>+<span class="number">5.j</span>],</span><br><span class="line">       [<span class="number">6.</span>+<span class="number">2.j</span>, <span class="number">6.</span>+<span class="number">1.j</span>, <span class="number">3.</span>-<span class="number">3.j</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort_complex(b)</span><br><span class="line">array([[<span class="number">2.</span>-<span class="number">1.j</span>, <span class="number">3.</span>-<span class="number">2.j</span>, <span class="number">3.</span>+<span class="number">5.j</span>],</span><br><span class="line">       [<span class="number">3.</span>-<span class="number">3.j</span>, <span class="number">6.</span>+<span class="number">1.j</span>, <span class="number">6.</span>+<span class="number">2.j</span>]])</span><br></pre></td></tr></table></figure></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szzsgc-6"><div class="note blue simple"><p><code>np.max(a, axis=None, out=None, keepdims=False)</code><br>函数说明：<br>该操作返回数组的最大值（<code>axis=None</code>的默认行为）或者沿轴的最大值（结果数组的维数可能会减1，以<code>(m,n)</code>形二维数组为例，若沿0轴获取最大值，即获取数组中每个列向量中的最大值，所得结果数组形状将变为<code>(n,)</code>，除非<code>keepdims</code>设为<code>True</code>，此时结果数组维数将变为<code>(1,n)</code>，仍为二维），另外也可以直接在<code>ndarray</code>对象上调用该方法。<code>out</code>参数用于存放结果数组，<code>keepdims</code>参数表示是否维持数组的维数不变。实际上，<code>axis</code>还可以是一个元组，以<code>(m,n,q)</code>形三维数组为例说明，若沿着<code>axis=(0,1)</code>获取最大值，即获取数组中（沿2轴的）每个“面”中的最大值，所得结果数组形状将变为<code>(q,)</code>，除非<code>keepdims</code>为<code>True</code>，此时结果数组维数将变为<code>(1,1,q)</code>，仍保持三维。最后提醒一下，<code>np.max()</code>还可以写成<code>np.amax()</code>，两个函数就是一回事</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.random.randint(<span class="number">0</span>,<span class="number">24</span>,<span class="number">12</span>).reshape(<span class="number">3</span>,-<span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">12</span>, <span class="number">11</span>,  <span class="number">6</span>, <span class="number">21</span>],</span><br><span class="line">       [<span class="number">12</span>, <span class="number">17</span>,  <span class="number">5</span>, <span class="number">16</span>],</span><br><span class="line">       [<span class="number">10</span>, <span class="number">14</span>, <span class="number">13</span>, <span class="number">17</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.<span class="built_in">max</span>(a)</span><br><span class="line"><span class="number">21</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.<span class="built_in">max</span>()</span><br><span class="line"><span class="number">21</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.<span class="built_in">max</span>(a,axis=<span class="number">0</span>)</span><br><span class="line">array([<span class="number">12</span>, <span class="number">17</span>, <span class="number">13</span>, <span class="number">21</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.<span class="built_in">max</span>(a,axis=<span class="number">1</span>,keepdims=<span class="literal">True</span>)</span><br><span class="line">array([[<span class="number">21</span>],</span><br><span class="line">       [<span class="number">17</span>],</span><br><span class="line">       [<span class="number">17</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.random.randint(<span class="number">0</span>,<span class="number">24</span>,<span class="number">24</span>).reshape(<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[[ <span class="number">7</span>,  <span class="number">2</span>,  <span class="number">0</span>, <span class="number">19</span>],</span><br><span class="line">        [<span class="number">20</span>, <span class="number">22</span>, <span class="number">17</span>, <span class="number">23</span>],</span><br><span class="line">        [<span class="number">11</span>, <span class="number">23</span>, <span class="number">14</span>, <span class="number">14</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">11</span>, <span class="number">16</span>, <span class="number">16</span>, <span class="number">12</span>],</span><br><span class="line">        [<span class="number">13</span>,  <span class="number">9</span>, <span class="number">17</span>,  <span class="number">0</span>],</span><br><span class="line">        [ <span class="number">8</span>,  <span class="number">5</span>, <span class="number">15</span>, <span class="number">18</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.<span class="built_in">max</span>(a,axis=(<span class="number">0</span>,<span class="number">1</span>))</span><br><span class="line">array([<span class="number">20</span>, <span class="number">23</span>, <span class="number">17</span>, <span class="number">23</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.<span class="built_in">max</span>(a,axis=(<span class="number">0</span>,<span class="number">1</span>),keepdims=<span class="literal">True</span>)</span><br><span class="line">array([[[<span class="number">20</span>, <span class="number">23</span>, <span class="number">17</span>, <span class="number">23</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.<span class="built_in">max</span>(a[:,:,<span class="number">0</span>]) <span class="comment">#沿2轴的首个“面”</span></span><br><span class="line"><span class="number">20</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.<span class="built_in">max</span>(a[:,:,<span class="number">1</span>])</span><br><span class="line"><span class="number">23</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.<span class="built_in">max</span>(a[:,:,<span class="number">2</span>])</span><br><span class="line"><span class="number">17</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.<span class="built_in">max</span>(a[:,:,<span class="number">3</span>]) <span class="comment">#沿2轴的最后一个“面”</span></span><br><span class="line"><span class="number">23</span></span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.argmax()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.argmax(a, axis=None, out=None)</code><br>函数说明：<br>返回数组或沿轴最大值的下标索引，参数见<code>np.max()</code>，只要说的是，当<code>axis</code>为<code>None</code>时（默认值），表示先将<code>a</code>展平，然后在一维化的数组<code>a</code>中寻找最大值并返回此时的下标，另外也可以直接在<code>ndarray</code>对象上调用该方法</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.array([[<span class="number">30</span>,<span class="number">40</span>,<span class="number">70</span>],[<span class="number">80</span>,<span class="number">20</span>,<span class="number">10</span>],[<span class="number">50</span>,<span class="number">90</span>,<span class="number">60</span>],[<span class="number">12</span>,<span class="number">56</span>,<span class="number">3</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.argmax()</span><br><span class="line"><span class="number">7</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.flat[_]</span><br><span class="line"><span class="number">90</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.<span class="built_in">max</span>()</span><br><span class="line"><span class="number">90</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.argmax(axis=<span class="number">0</span>)</span><br><span class="line">array([<span class="number">1</span>, <span class="number">2</span>, <span class="number">0</span>], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[_,np.arange(a.shape[<span class="number">1</span>])] <span class="comment">#全坐标索引</span></span><br><span class="line">array([<span class="number">80</span>, <span class="number">90</span>, <span class="number">70</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.<span class="built_in">max</span>(axis=<span class="number">0</span>)</span><br><span class="line">array([<span class="number">80</span>, <span class="number">90</span>, <span class="number">70</span>])</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.maximum()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.maximum(arr1, arr2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])</code><br>函数说明：<br>用于比较两个数组对象（<code>arr1</code>和<code>arr2</code>这两个数组必须是同形状或者可以广播至同一形状）并返回一个新数组，其中存储了两个数组对应位置上的较大值。其余参数暂时先不管了</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.random.randint(<span class="number">20</span>,size=(<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.random.randint(<span class="number">20</span>,size=(<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[[ <span class="number">8</span>, <span class="number">12</span>,  <span class="number">1</span>, <span class="number">16</span>],</span><br><span class="line">        [ <span class="number">6</span>, <span class="number">17</span>,  <span class="number">5</span>,  <span class="number">2</span>],</span><br><span class="line">        [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">18</span>, <span class="number">11</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">15</span>, <span class="number">15</span>, <span class="number">12</span>,  <span class="number">1</span>],</span><br><span class="line">        [ <span class="number">8</span>,  <span class="number">4</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">        [<span class="number">16</span>, <span class="number">12</span>,  <span class="number">6</span>,  <span class="number">0</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">array([[[<span class="number">18</span>, <span class="number">12</span>,  <span class="number">2</span>, <span class="number">18</span>],</span><br><span class="line">        [ <span class="number">7</span>, <span class="number">16</span>,  <span class="number">7</span>,  <span class="number">2</span>],</span><br><span class="line">        [ <span class="number">2</span>,  <span class="number">3</span>, <span class="number">11</span>,  <span class="number">2</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">6</span>, <span class="number">17</span>,  <span class="number">5</span>, <span class="number">17</span>],</span><br><span class="line">        [ <span class="number">3</span>,  <span class="number">4</span>, <span class="number">14</span>,  <span class="number">0</span>],</span><br><span class="line">        [ <span class="number">3</span>, <span class="number">15</span>,  <span class="number">2</span>, <span class="number">11</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s=np.empty_like(a)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.maximum(a,b,out=s)</span><br><span class="line">array([[[<span class="number">18</span>, <span class="number">12</span>,  <span class="number">2</span>, <span class="number">18</span>],</span><br><span class="line">        [ <span class="number">7</span>, <span class="number">17</span>,  <span class="number">7</span>,  <span class="number">2</span>],</span><br><span class="line">        [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">18</span>, <span class="number">11</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">15</span>, <span class="number">17</span>, <span class="number">12</span>, <span class="number">17</span>],</span><br><span class="line">        [ <span class="number">8</span>,  <span class="number">4</span>, <span class="number">14</span>,  <span class="number">3</span>],</span><br><span class="line">        [<span class="number">16</span>, <span class="number">15</span>,  <span class="number">6</span>, <span class="number">11</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s</span><br><span class="line">array([[[<span class="number">18</span>, <span class="number">12</span>,  <span class="number">2</span>, <span class="number">18</span>],</span><br><span class="line">        [ <span class="number">7</span>, <span class="number">17</span>,  <span class="number">7</span>,  <span class="number">2</span>],</span><br><span class="line">        [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">18</span>, <span class="number">11</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">15</span>, <span class="number">17</span>, <span class="number">12</span>, <span class="number">17</span>],</span><br><span class="line">        [ <span class="number">8</span>,  <span class="number">4</span>, <span class="number">14</span>,  <span class="number">3</span>],</span><br><span class="line">        [<span class="number">16</span>, <span class="number">15</span>,  <span class="number">6</span>, <span class="number">11</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.eye(<span class="number">2</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=[<span class="number">0.5</span>, <span class="number">2</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.maximum(a,b) <span class="comment">#b形状为(2,)，而a形状为(2,2)，因此b发生广播，首先补齐维度变为(1,2)，然后沿0轴复制元素进一步补齐维数，于是b相当于[[0.5,2],[0.5,2]]，可通过np.broadcast_to(b,(2,2))验证</span></span><br><span class="line">array([[<span class="number">1.</span> , <span class="number">2.</span> ],</span><br><span class="line">       [<span class="number">0.5</span>, <span class="number">2.</span> ]])</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.nanmax()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.nanmax(a, axis=None, out=None, keepdims=False)</code><br>函数说明：<br>只要数组中有一个元素为<code>NaN</code>（通常是无意义的异常值），则相应的<code>np.max()</code>比较得到的最大值也将为<code>NaN</code>，若要忽略<code>NaN</code>值，则使用<code>np.nanmax()</code>代替<code>np.max()</code>，该函数具体的用法参照<code>np.max()</code>即可</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.random.randint(<span class="number">0</span>,<span class="number">24</span>,<span class="number">12</span>).reshape(<span class="number">3</span>,-<span class="number">1</span>).astype(<span class="string">&#x27;float&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">1</span>,<span class="number">2</span>]=np.nan</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">2</span>,<span class="number">0</span>]=np.nan</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[ <span class="number">9.</span>, <span class="number">19.</span>,  <span class="number">5.</span>, <span class="number">23.</span>],</span><br><span class="line">       [ <span class="number">6.</span>,  <span class="number">3.</span>, nan, <span class="number">13.</span>],</span><br><span class="line">       [nan, <span class="number">15.</span>, <span class="number">17.</span>,  <span class="number">2.</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.<span class="built_in">max</span>(a)</span><br><span class="line">nan</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.<span class="built_in">max</span>(a,axis=<span class="number">1</span>)</span><br><span class="line">array([<span class="number">23.</span>, nan, nan])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.nanmax(a)</span><br><span class="line"><span class="number">23.0</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.nanmax(a,axis=<span class="number">1</span>)</span><br><span class="line">array([<span class="number">23.</span>, <span class="number">13.</span>, <span class="number">17.</span>])</span><br></pre></td></tr></table></figure></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szzsgc-7"><div class="note blue simple"><p><code>np.min(axis=None, out=None, keepdims=False)</code><br>函数说明：<br>等同于函数<code>np.amin()</code>，具体参见<code>np.max()</code>，只不过一个求最大一个求最小而已</p></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.argmin()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.argmin(a, axis=None, out=None)</code><br>函数说明：<br>具体参见<code>np.argmax()</code></p></div></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.minimum()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.numpy.minimum(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) = &lt;ufunc 'minimum'&gt;</code><br>函数说明：<br>具体参见<code>np.maximum()</code></p></div></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.nanmin()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.nanmin(a, axis=None, out=None, keepdims=False)</code><br>函数说明：<br>具体参见<code>np.nanmax()</code></p></div></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szzsgc-8"><div class="note blue simple"><p><code>np.sum(a, axis=None, dtype=None, out=None, keepdims=False)</code><br>函数说明：<br>求和运算，类似于<code>np.max()</code>、<code>np.min()</code>，都是“聚合”操作，参数含义也都一样，就不多说了。可以直接在<code>ndarray</code>对象上调用该方法</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">24</span>).reshape(<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.<span class="built_in">sum</span>()</span><br><span class="line"><span class="number">276</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.<span class="built_in">sum</span>(axis=<span class="number">0</span>)</span><br><span class="line">array([[<span class="number">12</span>, <span class="number">14</span>, <span class="number">16</span>, <span class="number">18</span>],</span><br><span class="line">       [<span class="number">20</span>, <span class="number">22</span>, <span class="number">24</span>, <span class="number">26</span>],</span><br><span class="line">       [<span class="number">28</span>, <span class="number">30</span>, <span class="number">32</span>, <span class="number">34</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.<span class="built_in">sum</span>(axis=(<span class="number">1</span>,<span class="number">2</span>))</span><br><span class="line">array([ <span class="number">66</span>, <span class="number">210</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">0</span>].<span class="built_in">sum</span>()</span><br><span class="line"><span class="number">66</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[<span class="number">1</span>].<span class="built_in">sum</span>()</span><br><span class="line"><span class="number">210</span></span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.cumsum()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.cumsum(a, axis=None, dtype=None, out=None)</code><br>函数说明：<br>计算数组或沿轴元素的累加，当<code>axis</code>为<code>None</code>时，会先展平一维化数组，然后再计算累加，所得也会是一个一维数组。可以直接在<code>ndarray</code>对象上调用该方法</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.flatten() <span class="comment">#继续上面的代码</span></span><br><span class="line">array([ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>,  <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>, <span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>, <span class="number">15</span>, <span class="number">16</span>,</span><br><span class="line">       <span class="number">17</span>, <span class="number">18</span>, <span class="number">19</span>, <span class="number">20</span>, <span class="number">21</span>, <span class="number">22</span>, <span class="number">23</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.cumsum()</span><br><span class="line">array([  <span class="number">0</span>,   <span class="number">1</span>,   <span class="number">3</span>,   <span class="number">6</span>,  <span class="number">10</span>,  <span class="number">15</span>,  <span class="number">21</span>,  <span class="number">28</span>,  <span class="number">36</span>,  <span class="number">45</span>,  <span class="number">55</span>,  <span class="number">66</span>,  <span class="number">78</span>,</span><br><span class="line">        <span class="number">91</span>, <span class="number">105</span>, <span class="number">120</span>, <span class="number">136</span>, <span class="number">153</span>, <span class="number">171</span>, <span class="number">190</span>, <span class="number">210</span>, <span class="number">231</span>, <span class="number">253</span>, <span class="number">276</span>], dtype=int32)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.cumsum(axis=<span class="number">2</span>)</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">3</span>,  <span class="number">6</span>],</span><br><span class="line">        [ <span class="number">4</span>,  <span class="number">9</span>, <span class="number">15</span>, <span class="number">22</span>],</span><br><span class="line">        [ <span class="number">8</span>, <span class="number">17</span>, <span class="number">27</span>, <span class="number">38</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">12</span>, <span class="number">25</span>, <span class="number">39</span>, <span class="number">54</span>],</span><br><span class="line">        [<span class="number">16</span>, <span class="number">33</span>, <span class="number">51</span>, <span class="number">70</span>],</span><br><span class="line">        [<span class="number">20</span>, <span class="number">41</span>, <span class="number">63</span>, <span class="number">86</span>]]], dtype=int32)</span><br></pre></td></tr></table></figure></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szzsgc-9"><div class="note blue simple"><p><code>np.cumprod(a, axis=None, dtype=None, out=None)</code><br>函数说明：<br>计算数组或沿轴元素的累乘，当<code>axis</code>为<code>None</code>时，会先展平一维化数组，然后再计算累乘，所得也会是一个一维数组。可以直接在<code>ndarray</code>对象上调用该方法</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.random.randint(<span class="number">0</span>,<span class="number">5</span>,<span class="number">12</span>).reshape(<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">3</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">0</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">3</span>, <span class="number">3</span>, <span class="number">1</span>],</span><br><span class="line">       [<span class="number">1</span>, <span class="number">3</span>, <span class="number">0</span>, <span class="number">4</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.flatten()</span><br><span class="line">array([<span class="number">3</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="number">3</span>, <span class="number">3</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">0</span>, <span class="number">4</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.cumprod(a)</span><br><span class="line">array([<span class="number">3</span>, <span class="number">3</span>, <span class="number">3</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>], dtype=int32)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.cumprod(a,axis=<span class="number">0</span>)</span><br><span class="line">array([[<span class="number">3</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">0</span>],</span><br><span class="line">       [<span class="number">9</span>, <span class="number">3</span>, <span class="number">3</span>, <span class="number">0</span>],</span><br><span class="line">       [<span class="number">9</span>, <span class="number">9</span>, <span class="number">0</span>, <span class="number">0</span>]], dtype=int32)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.cumprod(a,axis=<span class="number">1</span>)</span><br><span class="line">array([[ <span class="number">3</span>,  <span class="number">3</span>,  <span class="number">3</span>,  <span class="number">0</span>],</span><br><span class="line">       [ <span class="number">3</span>,  <span class="number">9</span>, <span class="number">27</span>, <span class="number">27</span>],</span><br><span class="line">       [ <span class="number">1</span>,  <span class="number">3</span>,  <span class="number">0</span>,  <span class="number">0</span>]], dtype=int32)</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szzsgc-10"><div class="note blue simple"><p><code>np.nonzero(a)</code><br>函数说明：<br>用于返回数组<code>a</code>中非零元素的下标索引（按坐标分量返回），根据此下标索引可以获取所有非零元素并以一维数组返回，若要直接返回数组中的非零元素，直接<code>a[a!=0]</code>。该函数常用于查找条件为真的数组元素索引，譬如，给定数组<code>a</code>，条件<code>a&gt;3</code>返回一个布尔数组，由于<code>False</code>就是整数0（有<code>False==0</code>成立），所以<code>np.nonzero(a&gt;3)</code>将返回符合条件的数组元素的下标索引。另外也可以直接在<code>ndarray</code>对象上调用<code>nonzero()</code>方法</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.random.randint(<span class="number">0</span>,<span class="number">24</span>,<span class="number">12</span>).reshape(<span class="number">3</span>,-<span class="number">1</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">20</span>, <span class="number">12</span>,  <span class="number">1</span>,  <span class="number">0</span>],</span><br><span class="line">       [<span class="number">11</span>,  <span class="number">3</span>, <span class="number">13</span>,  <span class="number">4</span>],</span><br><span class="line">       [ <span class="number">4</span>, <span class="number">11</span>, <span class="number">22</span>, <span class="number">21</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.nonzero(_)</span><br><span class="line">(array([<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">2</span>], dtype=int64), array([<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>], dtype=int64))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[_] <span class="comment">#全坐标索引获取非零元素</span></span><br><span class="line">array([<span class="number">20</span>, <span class="number">12</span>,  <span class="number">1</span>, <span class="number">11</span>,  <span class="number">3</span>, <span class="number">13</span>,  <span class="number">4</span>,  <span class="number">4</span>, <span class="number">11</span>, <span class="number">22</span>, <span class="number">21</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[a!=<span class="number">0</span>] <span class="comment">#布尔索引获取非零元组</span></span><br><span class="line">array([<span class="number">20</span>, <span class="number">12</span>,  <span class="number">1</span>, <span class="number">11</span>,  <span class="number">3</span>, <span class="number">13</span>,  <span class="number">4</span>,  <span class="number">4</span>, <span class="number">11</span>, <span class="number">22</span>, <span class="number">21</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a[np.nonzero(a&gt;<span class="number">3</span>)] <span class="comment">#等同于：a[a&gt;3]</span></span><br><span class="line">array([<span class="number">20</span>, <span class="number">12</span>, <span class="number">11</span>, <span class="number">13</span>,  <span class="number">4</span>,  <span class="number">4</span>, <span class="number">11</span>, <span class="number">22</span>, <span class="number">21</span>])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szzsgc-11"><div class="note blue simple"><p><code>np.where(condition, [x, y])</code><br>函数说明：<br>分两种情况（其中<code>condition</code>将返回一个布尔数组）：</p><ol><li><code>np.where(condition)</code>：此时等同于<code>condition.nonzero()</code></li><li><code>np.where(condition,x,y)</code>：首先创建一个空的结果数组，形状同<code>condition</code>，如果<code>condition</code>某个位置的元素为<code>True</code>，表示符合条件，则从<code>x</code>中对应位置处取出元素并放到结果数组中的相应位置，如果<code>condition</code>某个位置的元素为<code>False</code>，表示不符合条件，则从<code>y</code>中对应位置处取出元素并放到结果数组中的相应位置。并不要求<code>x</code>、<code>y</code>和<code>condition</code>的形状完全一致，但是其应能广播至同一形状</li></ol></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.where([[<span class="number">0</span>, <span class="number">1</span>],[<span class="number">1</span>, <span class="number">0</span>]])</span><br><span class="line">(array([<span class="number">0</span>, <span class="number">1</span>], dtype=int64), array([<span class="number">1</span>, <span class="number">0</span>], dtype=int64))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.array([[<span class="number">0</span>, <span class="number">1</span>],[<span class="number">1</span>, <span class="number">0</span>]]).nonzero()</span><br><span class="line">(array([<span class="number">0</span>, <span class="number">1</span>], dtype=int64), array([<span class="number">1</span>, <span class="number">0</span>], dtype=int64))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.where([[<span class="literal">True</span>, <span class="literal">False</span>],</span><br><span class="line"><span class="meta">... </span>          [<span class="literal">True</span>, <span class="literal">True</span>]],</span><br><span class="line"><span class="meta">... </span>         [[<span class="number">1</span>, <span class="number">2</span>],</span><br><span class="line"><span class="meta">... </span>          [<span class="number">3</span>, <span class="number">4</span>]],</span><br><span class="line"><span class="meta">... </span>         [[<span class="number">9</span>, <span class="number">8</span>],</span><br><span class="line"><span class="meta">... </span>          [<span class="number">7</span>, <span class="number">6</span>]])</span><br><span class="line">array([[<span class="number">1</span>, <span class="number">8</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">4</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.array([<span class="number">1</span>,<span class="number">5</span>,<span class="number">2</span>,<span class="number">7</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x=[[<span class="number">11</span>,<span class="number">12</span>,<span class="number">13</span>,<span class="number">14</span>],[<span class="number">15</span>,<span class="number">16</span>,<span class="number">17</span>,<span class="number">18</span>]]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>y=[-<span class="number">1</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>ret=np.where(a&gt;<span class="number">3</span>,x,y) <span class="comment">#这里发生了广播</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>ret</span><br><span class="line">array([[-<span class="number">1</span>, <span class="number">12</span>, -<span class="number">1</span>, <span class="number">14</span>],</span><br><span class="line">       [-<span class="number">1</span>, <span class="number">16</span>, -<span class="number">1</span>, <span class="number">18</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a = np.arange(<span class="number">9.</span>).reshape(<span class="number">3</span>, <span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.where(a &lt; <span class="number">5</span>, a, -<span class="number">1</span>) <span class="comment">#大于等于5的元素被置为-1，不过最简单的做法还是：a[a&gt;=5]=-1</span></span><br><span class="line">array([[ <span class="number">0.</span>,  <span class="number">1.</span>,  <span class="number">2.</span>],</span><br><span class="line">       [ <span class="number">3.</span>,  <span class="number">4.</span>, -<span class="number">1.</span>],</span><br><span class="line">       [-<span class="number">1.</span>, -<span class="number">1.</span>, -<span class="number">1.</span>]])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szzsgc-12"><div class="note blue simple"><p><code>np.extract(condition, arr)</code><br>函数说明：<br>用于从数组<code>a</code>中提取满足条件的元素。这不就是<code>a[condition]</code>么</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>arr = np.arange(<span class="number">12</span>).reshape((<span class="number">3</span>, <span class="number">4</span>))</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>arr</span><br><span class="line">array([[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">       [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">       [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>condition = np.mod(arr, <span class="number">3</span>)==<span class="number">0</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>condition</span><br><span class="line">array([[ <span class="literal">True</span>, <span class="literal">False</span>, <span class="literal">False</span>,  <span class="literal">True</span>],</span><br><span class="line">       [<span class="literal">False</span>, <span class="literal">False</span>,  <span class="literal">True</span>, <span class="literal">False</span>],</span><br><span class="line">       [<span class="literal">False</span>,  <span class="literal">True</span>, <span class="literal">False</span>, <span class="literal">False</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.extract(condition, arr)</span><br><span class="line">array([<span class="number">0</span>, <span class="number">3</span>, <span class="number">6</span>, <span class="number">9</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>arr[condition]</span><br><span class="line">array([<span class="number">0</span>, <span class="number">3</span>, <span class="number">6</span>, <span class="number">9</span>])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szzsgc-13"><div class="note blue simple"><p><code>np.place(arr, mask, vals)</code><br>函数说明：<br>将数组<code>arr</code>中满足条件<code>mask</code>（掩码数组）的元素用数据<code>vals</code>进行替换（原址操作）。这不就是<code>arr[mask]=vals</code>么。注意<code>vals</code>参数是一个一维数组或一维序列，指定用于替换的元素，设其长度为<code>N</code>，而符合条件的元素个数记为<code>M</code>，若<code>N&gt;M</code>，则将只使用<code>vals</code>序列的前<code>M</code>个元素用于替换，若<code>N&lt;=M</code>，则将循环重复使用这个序列的元素，譬如<code>vals=[1,2,3]</code>，且符合条件的元素有5个，则用于替换的元素为：[<code>1,2,3,1,2</code>]</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>arr = np.arange(<span class="number">12</span>).reshape(<span class="number">3</span>, <span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>arr</span><br><span class="line">array([[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">       [ <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>],</span><br><span class="line">       [ <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">11</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.place(arr, arr&gt;<span class="number">2</span>, [<span class="number">66</span>, <span class="number">88</span>]) <span class="comment">#相当于arr[arr&gt;2]=[66,88]，不过此句实际会报错，因为等号两边替换的元素和符合条件的元素数量不一致</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>arr</span><br><span class="line">array([[ <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>, <span class="number">66</span>],</span><br><span class="line">       [<span class="number">88</span>, <span class="number">66</span>, <span class="number">88</span>, <span class="number">66</span>],</span><br><span class="line">       [<span class="number">88</span>, <span class="number">66</span>, <span class="number">88</span>, <span class="number">66</span>]])</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="szzsgc-14"><div class="note blue simple"><p><code>np.partition(a, kth, axis=-1, kind='introselect', order=None)</code><br>函数说明：<br>指定一个或多个数，对数组进行分区。这玩意儿常用来求序列的第<code>k</code>项最大（小）值，特别是前几项最大（小）值，效率较高，因为它不对分区元素排序<br>参数说明：</p><ul><li><code>kth</code>：可以是单个整数，也可以是多个整数的序列，单个整数值时，<code>kth</code>表示第<code>k</code>个元素，<code>k</code>是指按升序排序后的数组（记作<code>s</code>，参数<code>axis</code>决定了具体沿哪个轴进行排序）的下标索引，<code>axis</code>所在轴长也就是<code>kth</code>参数的合法取值（实际取值区间为<code>[-len(arr),len(arr)-1]</code>，负数索引譬如-1表示的是最后一个元素的索引，这里姑且假设<code>axis</code>取0，于是0轴长度就是<code>len(arr)</code>），函数的功能是将原数组中小于<code>s[k]</code>的元素放到（<code>s[k]</code>的）左边区域，将大于或等于<code>s[k]</code>的元素放到（<code>s[k]</code>的）右边区域，但分区区域中元素并无顺序。显而易见的是，由于第<code>k</code>个元素指的是排序后的数组（<code>s</code>）的第<code>k</code>个元素，因此<code>s</code>本身就是一个符合条件的函数返回值，因为<code>s[k]</code>左边的元素的确都比<code>s[k]</code>小，<code>s[k]</code>右边的元素的确都比<code>s[k]</code>大或等啊。当<code>kth</code>参数是多值序列时（设为<code>[k0,k1,,k2,...]</code>），序列中的每一个整数都要在“合法取值”内，只需记住：作为函数返回值的数组的第<code>k0</code>、<code>k1</code>、<code>k2</code>、…个元素就是按升序排列后的数组的第<code>k0</code>、<code>k1</code>、<code>k2</code>、…个元素，将这些元素视为一个一个的分界点，左边的数总是小于它，右边的数总是大于等于它</li><li><code>axis</code>：指定要排序的轴，缺省为-1，表示沿最后一根轴排序，若指定为<code>None</code>，则首先将数组“展平”为一维，然后再排序，同<code>np.sort()</code></li><li><code>order</code>：非内存布局，而是用于自定义结构化数据类型时，指定字段排序优先级，仍同<code>np.sort()</code></li></ul></div><code>kth</code>为整数时：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=[<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">2</span>,<span class="number">1</span>] <span class="comment">#这里有五个数，使用np.sort()按升序排序得到：[1,2,3,4,5]，记作s</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,<span class="number">0</span>) <span class="comment">#以s的第0个元素为分界点，比它小的在前面，比它大的或相等的在后面，前后区域中的元素未排序</span></span><br><span class="line">array([<span class="number">1</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,-<span class="number">5</span>)</span><br><span class="line">array([<span class="number">1</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,<span class="number">1</span>) <span class="comment">#以s的第1个元素为分界点，比它小的在前面，比它大的或相等的在后面，前后区域中的元素未排序</span></span><br><span class="line">array([<span class="number">1</span>, <span class="number">2</span>, <span class="number">5</span>, <span class="number">4</span>, <span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,-<span class="number">4</span>)</span><br><span class="line">array([<span class="number">1</span>, <span class="number">2</span>, <span class="number">5</span>, <span class="number">4</span>, <span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,<span class="number">2</span>) <span class="comment">#以s的第2个元素为分界点，比它小的在前面，比它大的或相等的在后面，前后区域中的元素未排序</span></span><br><span class="line">array([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,-<span class="number">3</span>)</span><br><span class="line">array([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,<span class="number">3</span>) <span class="comment">#以s的第3个元素为分界点，比它小的在前面，比它大的或相等的在后面，前后区域中的元素未排序</span></span><br><span class="line">array([<span class="number">2</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,-<span class="number">2</span>)</span><br><span class="line">array([<span class="number">2</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,<span class="number">4</span>) <span class="comment">#以s的第4个元素为分界点，比它小的在前面，比它大的或相等的在后面，前后区域中的元素未排序</span></span><br><span class="line">array([<span class="number">2</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,-<span class="number">1</span>)</span><br><span class="line">array([<span class="number">2</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>])</span><br></pre></td></tr></table></figure><code>kth</code>为多个整数序列时：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">a=[<span class="number">2</span>,<span class="number">6</span>,<span class="number">10</span>,<span class="number">1</span>,<span class="number">5</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">8</span>,<span class="number">1</span>,<span class="number">9</span>,<span class="number">7</span>,<span class="number">7</span>,<span class="number">13</span>]</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;kth参数是多值序列时：如[3,5,8]，函数返回的数组的第3个元素（从0开始计数，第0个元素...）、第5个元素、第8个元素分别是原数组按升序排列后的第3、5、8个元素：&#x27;</span>)</span><br><span class="line">b=np.frombuffer(<span class="string">b&#x27; &#x27;</span>*<span class="built_in">len</span>(a),dtype=<span class="string">&#x27;S1&#x27;</span>)</span><br><span class="line">b=b.copy() <span class="comment"># 通过frombuffer()得到的将是一个只允许“读”模式的数组对象，op_flags参数无法开启“写”模式，只好拷贝一份副本而丢弃原数组对象</span></span><br><span class="line">it=np.nditer(b,op_flags=[<span class="string">&#x27;readwrite&#x27;</span>])</span><br><span class="line"><span class="keyword">while</span> <span class="keyword">not</span> it.finished:</span><br><span class="line">    <span class="keyword">if</span> it.iterindex <span class="keyword">in</span> [<span class="number">3</span>,<span class="number">5</span>,<span class="number">8</span>]:</span><br><span class="line">        it[<span class="number">0</span>]=<span class="string">b&#x27;|&#x27;</span></span><br><span class="line">    <span class="comment">#print(it[0])</span></span><br><span class="line">    it.iternext()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;   分区  界点 分区 界点 分区 界点 分区&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;  &#x27;</span>,end=<span class="string">&#x27;&#x27;</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> np.nditer(b):</span><br><span class="line">    <span class="built_in">print</span>(<span class="built_in">str</span>(i, encoding=<span class="string">&#x27;utf-8&#x27;</span>),end=<span class="string">&#x27;  &#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"><span class="built_in">print</span>(np.sort(a),end=<span class="string">&#x27; -- sort(a)\n&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(np.partition(a,(<span class="number">3</span>,<span class="number">5</span>,<span class="number">8</span>)),end=<span class="string">&#x27; -- partition(a,[3,5,8])\n&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;OUTPUT</span></span><br><span class="line"><span class="string">kth参数是多值序列时：如[3,5,8]，函数返回的数组的第3个元素（从0开始计数，第0个元素...）、第5个元素、第8个元素分别是原数组按升序排列后的第3、5、8个元素：</span></span><br><span class="line"><span class="string">   分区  界点 分区 界点 分区 界点 分区</span></span><br><span class="line"><span class="string">           |     |        |</span></span><br><span class="line"><span class="string">[ 1  1  2  2  4  5  6  7  7  8  9 10 13] -- sort(a)</span></span><br><span class="line"><span class="string">[ 1  1  2  2  4  5  6  7  7  9  8 10 13] -- partition(a,[3,5,8])</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure>该函数常用于求数组的前几个最大或最小值：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=[<span class="number">2</span>,<span class="number">6</span>,<span class="number">10</span>,<span class="number">1</span>,<span class="number">5</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">8</span>,<span class="number">1</span>,<span class="number">9</span>,<span class="number">7</span>,<span class="number">7</span>,<span class="number">13</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,[-<span class="number">1</span>,-<span class="number">2</span>,-<span class="number">3</span>]) <span class="comment">#求数组的前三大元素（由于默认是升序，因此是取最后三项，使用负数索引），另外当kth为多值序列时，其中的索引无需计较先后顺序</span></span><br><span class="line">array([ <span class="number">2</span>,  <span class="number">2</span>,  <span class="number">1</span>,  <span class="number">1</span>,  <span class="number">4</span>,  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">5</span>,  <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">13</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,[-<span class="number">2</span>,-<span class="number">3</span>,-<span class="number">1</span>])</span><br><span class="line">array([ <span class="number">2</span>,  <span class="number">2</span>,  <span class="number">1</span>,  <span class="number">1</span>,  <span class="number">4</span>,  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">5</span>,  <span class="number">7</span>,  <span class="number">8</span>,  <span class="number">9</span>, <span class="number">10</span>, <span class="number">13</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,[-<span class="number">1</span>,-<span class="number">2</span>,-<span class="number">3</span>])[[-<span class="number">1</span>,-<span class="number">2</span>,-<span class="number">3</span>]] <span class="comment">#花式索引</span></span><br><span class="line">array([<span class="number">13</span>, <span class="number">10</span>,  <span class="number">9</span>])</span><br></pre></td></tr></table></figure>再看一个自定义结构化类型和多维情况下的例子：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>dtype = [(<span class="string">&#x27;name&#x27;</span>, <span class="string">&#x27;S10&#x27;</span>), (<span class="string">&#x27;height&#x27;</span>, <span class="built_in">float</span>), (<span class="string">&#x27;age&#x27;</span>, <span class="built_in">int</span>)]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>values = [(<span class="string">&#x27;Lancelot&#x27;</span>, <span class="number">1.9</span>, <span class="number">38</span>), (<span class="string">&#x27;Arthur&#x27;</span>, <span class="number">1.8</span>, <span class="number">41</span>), (<span class="string">&#x27;muggledy&#x27;</span>, <span class="number">1.8</span>, <span class="number">22</span>), (<span class="string">&#x27;Galahad&#x27;</span>, <span class="number">1.7</span>, <span class="number">38</span>)] <span class="comment">#尝试将&#x27;Arthur&#x27;改成&#x27;rthur&#x27;，看看结果会有什么不同（该实验将说明“未在order参数中出现的字段仍将影响排序结果”，对于order=&#x27;height&#x27;来说，&#x27;height&#x27;字段出于最高优先级，其次是在dtype中先定义的&#x27;name&#x27;字段，最后是&#x27;age&#x27;字段）</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a = np.array(values, dtype=dtype)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(a, order=<span class="string">&#x27;height&#x27;</span>)</span><br><span class="line">array([(<span class="string">b&#x27;Galahad&#x27;</span>, <span class="number">1.7</span>, <span class="number">38</span>), (<span class="string">b&#x27;Arthur&#x27;</span>, <span class="number">1.8</span>, <span class="number">41</span>),</span><br><span class="line">       (<span class="string">b&#x27;muggledy&#x27;</span>, <span class="number">1.8</span>, <span class="number">22</span>), (<span class="string">b&#x27;Lancelot&#x27;</span>, <span class="number">1.9</span>, <span class="number">38</span>)],</span><br><span class="line">      dtype=[(<span class="string">&#x27;name&#x27;</span>, <span class="string">&#x27;S10&#x27;</span>), (<span class="string">&#x27;height&#x27;</span>, <span class="string">&#x27;&lt;f8&#x27;</span>), (<span class="string">&#x27;age&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a, kth=<span class="number">2</span>, order=<span class="string">&#x27;height&#x27;</span>)</span><br><span class="line">array([(<span class="string">b&#x27;Galahad&#x27;</span>, <span class="number">1.7</span>, <span class="number">38</span>), (<span class="string">b&#x27;Arthur&#x27;</span>, <span class="number">1.8</span>, <span class="number">41</span>),</span><br><span class="line">       (<span class="string">b&#x27;muggledy&#x27;</span>, <span class="number">1.8</span>, <span class="number">22</span>), (<span class="string">b&#x27;Lancelot&#x27;</span>, <span class="number">1.9</span>, <span class="number">38</span>)],</span><br><span class="line">      dtype=[(<span class="string">&#x27;name&#x27;</span>, <span class="string">&#x27;S10&#x27;</span>), (<span class="string">&#x27;height&#x27;</span>, <span class="string">&#x27;&lt;f8&#x27;</span>), (<span class="string">&#x27;age&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sort(a, order=[<span class="string">&#x27;age&#x27;</span>, <span class="string">&#x27;height&#x27;</span>])</span><br><span class="line">array([(<span class="string">b&#x27;muggledy&#x27;</span>, <span class="number">1.8</span>, <span class="number">22</span>), (<span class="string">b&#x27;Galahad&#x27;</span>, <span class="number">1.7</span>, <span class="number">38</span>),</span><br><span class="line">       (<span class="string">b&#x27;Lancelot&#x27;</span>, <span class="number">1.9</span>, <span class="number">38</span>), (<span class="string">b&#x27;Arthur&#x27;</span>, <span class="number">1.8</span>, <span class="number">41</span>)],</span><br><span class="line">      dtype=[(<span class="string">&#x27;name&#x27;</span>, <span class="string">&#x27;S10&#x27;</span>), (<span class="string">&#x27;height&#x27;</span>, <span class="string">&#x27;&lt;f8&#x27;</span>), (<span class="string">&#x27;age&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a, kth=<span class="number">2</span>, order=[<span class="string">&#x27;age&#x27;</span>, <span class="string">&#x27;height&#x27;</span>])</span><br><span class="line">array([(<span class="string">b&#x27;muggledy&#x27;</span>, <span class="number">1.8</span>, <span class="number">22</span>), (<span class="string">b&#x27;Galahad&#x27;</span>, <span class="number">1.7</span>, <span class="number">38</span>),</span><br><span class="line">       (<span class="string">b&#x27;Lancelot&#x27;</span>, <span class="number">1.9</span>, <span class="number">38</span>), (<span class="string">b&#x27;Arthur&#x27;</span>, <span class="number">1.8</span>, <span class="number">41</span>)],</span><br><span class="line">      dtype=[(<span class="string">&#x27;name&#x27;</span>, <span class="string">&#x27;S10&#x27;</span>), (<span class="string">&#x27;height&#x27;</span>, <span class="string">&#x27;&lt;f8&#x27;</span>), (<span class="string">&#x27;age&#x27;</span>, <span class="string">&#x27;&lt;i4&#x27;</span>)])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.array([[<span class="number">3</span>,<span class="number">7</span>,<span class="number">1</span>],[<span class="number">4</span>,<span class="number">2</span>,<span class="number">5</span>],[<span class="number">2</span>,<span class="number">3</span>,<span class="number">2</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">3</span>, <span class="number">7</span>, <span class="number">1</span>],</span><br><span class="line">       [<span class="number">4</span>, <span class="number">2</span>, <span class="number">5</span>],</span><br><span class="line">       [<span class="number">2</span>, <span class="number">3</span>, <span class="number">2</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,kth=<span class="number">1</span>,axis=<span class="number">0</span>)</span><br><span class="line">array([[<span class="number">2</span>, <span class="number">2</span>, <span class="number">1</span>],</span><br><span class="line">       [<span class="number">3</span>, <span class="number">3</span>, <span class="number">2</span>],</span><br><span class="line">       [<span class="number">4</span>, <span class="number">7</span>, <span class="number">5</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.array([[[<span class="number">3</span>,<span class="number">1</span>],[<span class="number">6</span>,<span class="number">5</span>]],[[<span class="number">4</span>,<span class="number">7</span>],[<span class="number">2</span>,<span class="number">3</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[[<span class="number">3</span>, <span class="number">1</span>],</span><br><span class="line">        [<span class="number">6</span>, <span class="number">5</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">4</span>, <span class="number">7</span>],</span><br><span class="line">        [<span class="number">2</span>, <span class="number">3</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.partition(a,kth=<span class="number">1</span>,axis=<span class="number">1</span>)</span><br><span class="line">array([[[<span class="number">3</span>, <span class="number">1</span>],</span><br><span class="line">        [<span class="number">6</span>, <span class="number">5</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line">        [<span class="number">4</span>, <span class="number">7</span>]]])</span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.argpartition()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.argpartition(a, kth, axis=-1, kind='introselect', order=None)</code><br>函数说明：<br>功能同<code>np.partition()</code>，只不过返回的是<code>np.partition()</code>结果数组中的元素在原数组<code>a</code>中的下标索引</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=[<span class="number">2</span>,<span class="number">6</span>,<span class="number">10</span>,<span class="number">1</span>,<span class="number">5</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">8</span>,<span class="number">1</span>,<span class="number">9</span>,<span class="number">7</span>,<span class="number">7</span>,<span class="number">13</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1=np.argpartition(a,<span class="number">5</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s2=np.partition(a,<span class="number">5</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s1</span><br><span class="line">array([ <span class="number">5</span>,  <span class="number">0</span>,  <span class="number">8</span>,  <span class="number">3</span>,  <span class="number">6</span>,  <span class="number">4</span>,  <span class="number">1</span>, <span class="number">10</span>, <span class="number">11</span>,  <span class="number">9</span>,  <span class="number">7</span>,  <span class="number">2</span>, <span class="number">12</span>], dtype=int64)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>s2</span><br><span class="line">array([ <span class="number">2</span>,  <span class="number">2</span>,  <span class="number">1</span>,  <span class="number">1</span>,  <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">7</span>,  <span class="number">9</span>,  <span class="number">8</span>, <span class="number">10</span>, <span class="number">13</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.array(a)[s1]</span><br><span class="line">array([ <span class="number">2</span>,  <span class="number">2</span>,  <span class="number">1</span>,  <span class="number">1</span>,  <span class="number">4</span>,  <span class="number">5</span>,  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">7</span>,  <span class="number">9</span>,  <span class="number">8</span>, <span class="number">10</span>, <span class="number">13</span>])</span><br></pre></td></tr></table></figure></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><h2 id="数学运算">数学运算</h2><div class="tabs" id="sxys"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#sxys-1"><code>np.dot()</code></button></li><li class="tab"><button type="button" data-href="#sxys-2"><code>np.log()</code></button></li><li class="tab"><button type="button" data-href="#sxys-3"><code>np.sqrt()</code></button></li><li class="tab"><button type="button" data-href="#sxys-4"><code>np.mod()</code></button></li><li class="tab"><button type="button" data-href="#sxys-5">多项式</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="sxys-1"><div class="note blue simple"><p><code>np.dot(a, b, out=None)</code><br>函数说明：<br>矩阵乘法（可以在<code>ndarray</code>对象上直接调用该方法），等同于<code>np.matmul(a,b)</code>或使用<code>@</code>运算符：<code>a @ b</code>，注意区别于<code>np.multiply()</code>方法，这是用于两个数组之间的逐元素乘法操作，对应运算符<code>*</code>，即<code>a * b</code></p><ul><li><code>a</code>和<code>b</code>都是标量，表示数值间的普通乘法</li><li><code>a</code>和<code>b</code>都是一维时，表示计算这两个向量的内积</li><li><code>a</code>和<code>b</code>都是二维或其中一个允许是一维，表示矩阵乘法</li><li><code>a</code>是<code>N</code>维（<code>N&gt;2</code>）而<code>b</code>是一维，则结果是<code>a</code>和<code>b</code>的最后一个轴上元素的和积，因此需满足条件：<code>a</code>和<code>b</code>最后一个轴的长度相同，等同于：<code>reduce(lambda last,now:last+now[0]*now[1],zip(np.rollaxis(a,a.ndim-1),b),0)</code>，结果数组形状为<code>a.shape[:-1]</code></li><li><code>a</code>是<code>N</code>维（<code>N&gt;2</code>）而<code>b</code>是<code>M</code>维（<code>M&gt;=2</code>），则结果是<code>a</code>的最后一个轴和<code>b</code>的倒数第二个轴上元素的和积，需满足条件：<code>a</code>的最后一个轴长等于b的倒数第二个轴长，且有：<code>dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])</code>，这条没看懂</li></ul></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.random.randint(<span class="number">0</span>,<span class="number">10</span>,<span class="number">3</span>).reshape(<span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.random.randint(<span class="number">0</span>,<span class="number">10</span>,<span class="number">3</span>).reshape(<span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([<span class="number">3</span>, <span class="number">4</span>, <span class="number">0</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">array([<span class="number">8</span>, <span class="number">9</span>, <span class="number">4</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.dot(b)</span><br><span class="line"><span class="number">60</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>c=np.arange(<span class="number">6</span>).reshape(<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>c.dot(a) <span class="comment">#c形状为(2,3)，a形状为(3,)，允许这样，而并不一定要求a形状为(3,1)</span></span><br><span class="line">array([ <span class="number">4</span>, <span class="number">25</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>c.dot(a[:,<span class="literal">None</span>])</span><br><span class="line">array([[ <span class="number">4</span>],</span><br><span class="line">       [<span class="number">25</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">24</span>).reshape(<span class="number">3</span>,<span class="number">4</span>,<span class="number">2</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[[ <span class="number">0</span>,  <span class="number">1</span>],</span><br><span class="line">        [ <span class="number">2</span>,  <span class="number">3</span>],</span><br><span class="line">        [ <span class="number">4</span>,  <span class="number">5</span>],</span><br><span class="line">        [ <span class="number">6</span>,  <span class="number">7</span>]],</span><br><span class="line"></span><br><span class="line">       [[ <span class="number">8</span>,  <span class="number">9</span>],</span><br><span class="line">        [<span class="number">10</span>, <span class="number">11</span>],</span><br><span class="line">        [<span class="number">12</span>, <span class="number">13</span>],</span><br><span class="line">        [<span class="number">14</span>, <span class="number">15</span>]],</span><br><span class="line"></span><br><span class="line">       [[<span class="number">16</span>, <span class="number">17</span>],</span><br><span class="line">        [<span class="number">18</span>, <span class="number">19</span>],</span><br><span class="line">        [<span class="number">20</span>, <span class="number">21</span>],</span><br><span class="line">        [<span class="number">22</span>, <span class="number">23</span>]]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.array([<span class="number">1</span>,<span class="number">2</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a.dot(b)</span><br><span class="line">array([[ <span class="number">2</span>,  <span class="number">8</span>, <span class="number">14</span>, <span class="number">20</span>],</span><br><span class="line">       [<span class="number">26</span>, <span class="number">32</span>, <span class="number">38</span>, <span class="number">44</span>],</span><br><span class="line">       [<span class="number">50</span>, <span class="number">56</span>, <span class="number">62</span>, <span class="number">68</span>]])</span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.out()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.outer(a, b, out=None)</code><br>函数说明：<br>用于计算两个一维向量的外积，其尺寸各自随意，等同于<code>a[:,None]@b[None,:]</code></p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.random.randint(<span class="number">0</span>,<span class="number">10</span>,<span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([<span class="number">4</span>, <span class="number">9</span>, <span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b=np.random.randint(<span class="number">0</span>,<span class="number">10</span>,<span class="number">5</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>b</span><br><span class="line">array([<span class="number">9</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">8</span>, <span class="number">4</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.outer(a,b)</span><br><span class="line">array([[<span class="number">36</span>,  <span class="number">8</span>,  <span class="number">4</span>, <span class="number">32</span>, <span class="number">16</span>],</span><br><span class="line">       [<span class="number">81</span>, <span class="number">18</span>,  <span class="number">9</span>, <span class="number">72</span>, <span class="number">36</span>],</span><br><span class="line">       [<span class="number">27</span>,  <span class="number">6</span>,  <span class="number">3</span>, <span class="number">24</span>, <span class="number">12</span>]])</span><br></pre></td></tr></table></figure></div></div><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span><code>np.inner()</code></span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.inner(a, b)</code><br>函数说明：<br>用于计算两个一维向量的内积，其尺寸必须一致，等同于<code>a[None,:]@b[:,None]</code></p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.random.randint(<span class="number">0</span>,<span class="number">10</span>,<span class="number">3</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([<span class="number">9</span>, <span class="number">6</span>, <span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.inner(a,a)</span><br><span class="line"><span class="number">126</span></span><br></pre></td></tr></table></figure></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="sxys-2"><div class="note blue simple"><p><code>np.log(a)</code><br>函数说明：<br>逐元素的以<code>e</code>为底的对数计算，满足<code>log(exp(x)) = x</code>（以<code>e</code>为底<code>exp(x)</code>的对数就是<code>x</code>），还有<code>np.log2()</code>、<code>np.log10()</code>，而基于其他底数的对数计算，通常可以采用换底公式转换为以10为底的对数（也就是<code>ln</code>）计算：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mo><mi>log</mi><mo>⁡</mo></mo><mi>a</mi></msub><mi>b</mi><mo>=</mo><mfrac><mrow><msub><mo><mi>log</mi><mo>⁡</mo></mo><mn>10</mn></msub><mi>b</mi></mrow><mrow><msub><mo><mi>log</mi><mo>⁡</mo></mo><mn>10</mn></msub><mi>a</mi></mrow></mfrac><mo>=</mo><mfrac><mrow><mi>ln</mi><mo>⁡</mo><mi>b</mi></mrow><mrow><mi>ln</mi><mo>⁡</mo><mi>a</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">\log_a b=\frac{\log_{10}b}{\log_{10}a}=\frac{\ln b}{\ln a}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.93858em;vertical-align:-0.24414em;"></span><span class="mop"><span class="mop">lo<span style="margin-right:0.01389em;">g</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.057252em;"><span style="top:-2.4558600000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">a</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.24414em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.513324em;vertical-align:-0.5311079999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.982216em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop mtight"><span class="mop mtight"><span class="mtight">l</span><span class="mtight">o</span><span class="mtight" style="margin-right:0.01389em;">g</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.19444571428571428em;"><span style="top:-2.2341314285714287em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.26586857142857145em;"><span></span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mathnormal mtight">a</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.496108em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop mtight"><span class="mop mtight"><span class="mtight">l</span><span class="mtight">o</span><span class="mtight" style="margin-right:0.01389em;">g</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.19444571428571428em;"><span style="top:-2.2341314285714287em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.26586857142857145em;"><span></span></span></span></span></span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5311079999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.2251079999999999em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop mtight"><span class="mtight">l</span><span class="mtight">n</span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mathnormal mtight">a</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mop mtight"><span class="mtight">l</span><span class="mtight">n</span></span><span class="mspace mtight" style="margin-right:0.19516666666666668em;"></span><span class="mord mathnormal mtight">b</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.log(np.exp(<span class="number">12</span>))</span><br><span class="line"><span class="number">12.0</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.log2(<span class="number">12</span>)</span><br><span class="line"><span class="number">3.584962500721156</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.log10(<span class="number">12</span>)/np.log10(<span class="number">2</span>)</span><br><span class="line"><span class="number">3.5849625007211565</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="sxys-3"><div class="note blue simple"><p><code>np.sqrt(a)</code><br>函数说明：<br>逐元素计算平方根。要计算任意次方根，可以使用<code>**</code>运算符，如<code>a**(1/2)</code>、<code>a**(1/3)</code>，其等同于调用<code>np.power()</code>函数（或<code>math</code>库中的<code>pow()</code>），如<code>np.power(a,1/2)</code>、<code>np.power(a,1/3)</code></p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.sqrt([<span class="number">1</span>,<span class="number">4</span>,<span class="number">9</span>])</span><br><span class="line">array([<span class="number">1.</span>, <span class="number">2.</span>, <span class="number">3.</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.array([<span class="number">1</span>,<span class="number">4</span>,<span class="number">9</span>])**(<span class="number">1</span>/<span class="number">2</span>)</span><br><span class="line">array([<span class="number">1.</span>, <span class="number">2.</span>, <span class="number">3.</span>])</span><br></pre></td></tr></table></figure><div class="hide-toggle" ><div class="hide-button toggle-title " style=""><i class="fas fa-caret-right fa-fw"></i><span>立方根</span></div>    <div class="hide-content"><div class="note blue simple"><p><code>np.cbrt(a)</code><br>函数说明：<br>逐元素计算立方根。不建议使用<code>a**(1/3)</code>方式，譬如当<code>a</code>是负数时将返回复数类型，<code>a**(1/5)</code>等也是如此</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.array([-<span class="number">1</span>,-<span class="number">8</span>,-<span class="number">27</span>])**(<span class="number">1</span>/<span class="number">3</span>) <span class="comment">#之所以返回nan，是因为np.array([-1,-8,-27])是int64整型，无法支持复数运算</span></span><br><span class="line">array([nan, nan, nan])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.array([-<span class="number">1</span>,-<span class="number">8</span>,-<span class="number">27</span>],dtype=<span class="string">&#x27;complex&#x27;</span>)**(<span class="number">1</span>/<span class="number">3</span>)</span><br><span class="line">array([<span class="number">0.5</span>+<span class="number">0.8660254j</span> , <span class="number">1.</span> +<span class="number">1.73205081j</span>, <span class="number">1.5</span>+<span class="number">2.59807621j</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.power(np.array([-<span class="number">1</span>,-<span class="number">8</span>,-<span class="number">27</span>],dtype=<span class="string">&quot;complex&quot;</span>),<span class="number">1</span>/<span class="number">3</span>)</span><br><span class="line">array([<span class="number">0.5</span>+<span class="number">0.8660254j</span> , <span class="number">1.</span> +<span class="number">1.73205081j</span>, <span class="number">1.5</span>+<span class="number">2.59807621j</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>(-<span class="number">27</span>)**(<span class="number">1</span>/<span class="number">3</span>)</span><br><span class="line">(<span class="number">1.5000000000000004</span>+<span class="number">2.598076211353316j</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>-<span class="number">27</span>**(<span class="number">1</span>/<span class="number">3</span>) <span class="comment">#由于**运算符的优先级大于-，所以相当于-(27**(1/3))，因为有-(-a)^&#123;1/3&#125;=a^&#123;1/3&#125;,a&gt;0成立</span></span><br><span class="line">-<span class="number">3.0</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.cbrt(-<span class="number">27</span>) <span class="comment">#立方根（cube root）</span></span><br><span class="line">-<span class="number">3.0</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">import</span> math</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>x=-<span class="number">27</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>math.<span class="built_in">pow</span>(<span class="built_in">abs</span>(x),<span class="built_in">float</span>(<span class="number">1</span>)/<span class="number">3</span>) * (<span class="number">1</span>,-<span class="number">1</span>)[x&lt;<span class="number">0</span>] <span class="comment">#参见https://stackoverflow.com/questions/1361740/cubic-root-of-the-negative-number-on-python</span></span><br><span class="line">-<span class="number">3.0</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>math.<span class="built_in">pow</span>(-<span class="number">27</span>,<span class="number">1</span>/<span class="number">3</span>) <span class="comment">#参见https://vevurka.github.io/cs/python/cubic_root/</span></span><br><span class="line">Traceback (most recent call last):</span><br><span class="line">  File <span class="string">&quot;&lt;stdin&gt;&quot;</span>, line <span class="number">1</span>, <span class="keyword">in</span> &lt;module&gt;</span><br><span class="line">ValueError: math domain error</span><br></pre></td></tr></table></figure></div></div><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="sxys-4"><div class="note blue simple"><p><code>np.mod(a,b)</code><br>函数说明：<br>逐元素的取模运算</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>a=np.arange(<span class="number">8</span>).reshape(<span class="number">2</span>,<span class="number">4</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>a</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line">       [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>]])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>np.mod(a,<span class="number">2</span>)</span><br><span class="line">array([[<span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="number">1</span>],</span><br><span class="line">       [<span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="number">1</span>]], dtype=int32)</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="sxys-5"><div class="note blue simple"><p><code>np.poly1d(c_or_r, r=False, variable='x')</code><br>函数说明：<br>用于创建一个一元多项式函数，有两种模式，一是<code>r</code>为<code>False</code>（默认），此时<code>c_or_r</code>指定多项式的系数，譬如<code>c_or_r=[1,2,3]</code>，创建的多项式函数为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mn>2</mn><msup><mi>x</mi><mn>1</mn></msup><mo>+</mo><mn>3</mn><msup><mi>x</mi><mn>0</mn></msup></mrow><annotation encoding="application/x-tex">f(x)=1x^2+2x^1+3x^0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord">3</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span></span></span></span></span></span></span></span>，二是<code>r</code>为<code>True</code>，此时<code>c_or_r</code>指定多项式的根，仍以<code>c_or_r=[1,2,3]</code>为例，创建的多项式函数为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><mi>x</mi><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo><mo stretchy="false">(</mo><mi>x</mi><mo>−</mo><mn>2</mn><mo stretchy="false">)</mo><mo stretchy="false">(</mo><mi>x</mi><mo>−</mo><mn>3</mn><mo stretchy="false">)</mo><mo>=</mo><msup><mi>x</mi><mn>3</mn></msup><mo>−</mo><mn>6</mn><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mn>11</mn><mi>x</mi><mo>−</mo><mn>6</mn></mrow><annotation encoding="application/x-tex">f(x)=(x-1)(x-2)(x-3)= x^3 - 6x^2 + 11x -6</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">2</span><span class="mclose">)</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">3</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord">6</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mord">1</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">6</span></span></span></span>，实际<code>poly1d</code>是一个类，若返回的类实例记作<code>f=np.poly1d([1,2,3])</code>，可以直接用<code>()</code>调用之（<code>f()</code>），返回多项式的具体值，<code>variable</code>参数指定未知变量字母，控制多项式函数的打印结果，默认为<code>'x'</code>，<code>f</code>有一些属性，<code>r</code>属性返回多项式的根，<code>c</code>属性返回多项式的系数数组，<code>order</code>属性返回多项式的最高次方，<code>f</code>可以用<code>[i]</code>进行索引，获取<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>x</mi><mi>i</mi></msup></mrow><annotation encoding="application/x-tex">x^i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.824664em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.824664em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span></span></span></span></span></span></span></span>的系数，<code>f</code>还有两个方法，<code>deriv([m])</code>表示求导，可选的参数<code>m</code>表示求几次导，默认求一次导，返回的仍是一个多项式函数，<code>integ([m,k])</code>表示求积分，可选的参数<code>m</code>表示积几次分，<code>k</code>表示积分后的常数项的值</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>f=np.poly1d([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">print</span>(f)</span><br><span class="line">   <span class="number">2</span></span><br><span class="line"><span class="number">1</span> x + <span class="number">2</span> x + <span class="number">3</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>f.r</span><br><span class="line">array([-<span class="number">1.</span>+<span class="number">1.41421356j</span>, -<span class="number">1.</span>-<span class="number">1.41421356j</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>f(_)</span><br><span class="line">array([<span class="number">4.4408921e-16</span>+<span class="number">0.j</span>, <span class="number">4.4408921e-16</span>+<span class="number">0.j</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>f.c</span><br><span class="line">array([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>f[<span class="number">2</span>]</span><br><span class="line"><span class="number">1</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>f.deriv()</span><br><span class="line">poly1d([<span class="number">2</span>, <span class="number">2</span>])</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">print</span>(_)</span><br><span class="line"><span class="number">2</span> x + <span class="number">2</span></span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div><style>.tip{width:80%;}@media only screen and (max-width: 600px){    .tip{width:100%}}</style><div class="tip fas fa-quote-left"><p>[1] <a href="https://numpy.org/doc/stable/user/quickstart.html" target="_blank">Numpy官方英文文档·用户手册</a><br>[2] <a href="https://www.numpy.org.cn/user/quickstart.html#基础知识" target="_blank">Numpy中文网入门教程</a><br>[3] <a href="https://www.runoob.com/numpy/numpy-tutorial.html" target="_blank">RUNOOB菜鸟教程 Numpy入门教程</a></p></div><script>var dyrefreshexists = false;var dyencyptdingshiqi = setInterval(function(){    if(typeof(refreshFn_forEncrypt)!="undefined"){        dyrefreshexists = true;        refreshFn_forEncrypt();    }    if (dyrefreshexists){        clearInterval(dyencyptdingshiqi);    }},300);</script>]]></content>
      
      
      <categories>
          
          <category> 计算机基础 </category>
          
          <category> 编程语言 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> Python </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>Butterfly魔改部分记录</title>
      <link href="posts/65257/"/>
      <url>posts/65257/</url>
      
        <content type="html"><![CDATA[<style>#article-container figure.highlight {    margin: 0.5rem 0 0.5rem !important;}</style><ul><li>按照<a href="https://butterfly.lete114.top/article/Butterfly-config.html">Lete乐特</a>的教程添加了哔哩哔哩banner，用以替换原始顶图（Top image）<br>这导致banner图不适应暗黑模式，问题就是如何将banner所在div调暗，现有两种解决方案（我采取第二种）：<ol><li>通过亮度滤镜实现<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-id">#page-header</span> &#123;</span><br><span class="line">    <span class="attribute">filter</span>: <span class="built_in">brightness</span>(<span class="number">60%</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>实测发现，每当从暗黑模式进入新的页面，顶图变暗都有一个很大的延迟，我没有找出具体的原因，因此想了另一个解决方案，通过伪元素实现（黑色透明蒙板）遮罩层：</li><li>通过伪元素实现<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-id">#page-header</span><span class="selector-pseudo">::before</span> &#123;</span><br><span class="line">    <span class="attribute">content</span>:<span class="string">&#x27;&#x27;</span>;</span><br><span class="line">    <span class="attribute">display</span>:block;</span><br><span class="line">    <span class="attribute">position</span>:relative;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100%</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">100%</span>;</span><br><span class="line">    <span class="attribute">z-index</span>:<span class="number">7</span>;</span><br><span class="line">    <span class="attribute">background-color</span>:<span class="number">#121212</span>;</span><br><span class="line">    <span class="attribute">opacity</span>:<span class="number">0.7</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ol></li><li>之前看到<a href="https://www.heson10.com/">黑石博客</a>首页文章卡片有模糊背景，很漂亮，我也来实现一下吧<br>首先看一个实现该效果的简单示例：<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">style</span> <span class="attr">type</span>=<span class="string">&quot;text/css&quot;</span>&gt;</span><span class="language-css"></span></span><br><span class="line"><span class="language-css">  <span class="selector-class">.wrapper</span>&#123;</span></span><br><span class="line"><span class="language-css">      <span class="attribute">position</span>: relative;</span></span><br><span class="line"><span class="language-css">      <span class="attribute">width</span>:<span class="number">500px</span>;</span></span><br><span class="line"><span class="language-css">      <span class="attribute">height</span>:<span class="number">400px</span>;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css">  <span class="selector-class">.blur_layer</span>&#123;</span></span><br><span class="line"><span class="language-css">      <span class="attribute">position</span>: absolute;</span></span><br><span class="line"><span class="language-css">      <span class="attribute">width</span>:<span class="number">100%</span>;</span></span><br><span class="line"><span class="language-css">      <span class="attribute">height</span>:<span class="number">100%</span>;</span></span><br><span class="line"><span class="language-css">      <span class="attribute">filter</span>: <span class="built_in">blur</span>(<span class="number">8px</span>);</span></span><br><span class="line"><span class="language-css">      <span class="attribute">background</span>:<span class="built_in">url</span>(<span class="string">https://cdn.statically.io/gh/celestezj/ImageHosting/master/img/20210217120300.jpg</span>);</span></span><br><span class="line"><span class="language-css">      <span class="attribute">background-size</span>: cover;</span></span><br><span class="line"><span class="language-css">      <span class="attribute">opacity</span>: <span class="number">0.5</span>;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css">  <span class="selector-class">.content</span>&#123;</span></span><br><span class="line"><span class="language-css">      <span class="attribute">position</span>:absolute;</span></span><br><span class="line"><span class="language-css">      <span class="attribute">left</span>: <span class="number">50%</span>;</span></span><br><span class="line"><span class="language-css">      <span class="attribute">top</span>: <span class="number">50%</span>;</span></span><br><span class="line"><span class="language-css">      <span class="attribute">transform</span>: <span class="built_in">translate</span>(-<span class="number">50%</span>);</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;wrapper&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;blur_layer&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;content&quot;</span>&gt;</span></span><br><span class="line">        Hello, World!<span class="comment">&lt;!-- 这里放置你的内容 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>简单来说就是将父div设为relative，然后额外添加一个子div充当blur层并设为absolute，在blur层上设置背景并进行高斯模糊，最后将你要显示在blur层之上的东西都放在blur层后面即可<br>好了，思路有了，现在改源码，打开目标文件<em>butterfly/layout/includes/mixins/post-ui.pug</em>，在<code>if post_cover &amp;&amp; theme.cover.index_enable</code>一行下面添加如下内容：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">.dyblurbg</span><br><span class="line">  if theme.lazyload.enable</span><br><span class="line">    img(data-lazy-src=url_for(post_cover) onerror=`this.onerror=null;this.src=&#x27;`+ url_for(theme.error_img.post_page) + `&#x27;` alt=title)</span><br><span class="line">  else</span><br><span class="line">    img(src=url_for(post_cover))</span><br></pre></td></tr></table></figure>这个<code>.dyblurbg</code>就是充当blur层的div，类名叫做<code>dyblurbg</code>，为了适配主题源码，还需要增加是否图片懒加载的判断，具体参见<a href="https://www.npmjs.com/package/vanilla-lazyload">vanilla-lazyload</a><br>新建<em>butterfly/source/css/mystyle.css</em>文件：<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.dyblurbg</span> &#123;</span><br><span class="line">    <span class="attribute">position</span>: absolute;</span><br><span class="line">    <span class="attribute">width</span>: <span class="number">100%</span>;</span><br><span class="line">    <span class="attribute">height</span>: <span class="number">100%</span>;</span><br><span class="line">    <span class="attribute">filter</span>: <span class="built_in">blur</span>(<span class="number">15px</span>);</span><br><span class="line">    <span class="attribute">opacity</span>: <span class="number">0.5</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.dyblurbg</span> <span class="selector-tag">img</span> &#123;</span><br><span class="line">    <span class="attribute">width</span>: <span class="number">100%</span>;</span><br><span class="line">    <span class="attribute">height</span>: <span class="number">100%</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.recent-post-item</span>&#123;</span><br><span class="line">    <span class="attribute">position</span>: relative;</span><br><span class="line">    <span class="attribute">overflow</span>: hidden;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>其中<code>recent-post-item</code>就是<code>dyblurbg</code>的父div，最后在主题配置的<code>inject</code>项中引入该css文件即可：<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">inject:</span></span><br><span class="line">  <span class="attr">head:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;/css/mystyle.css&quot;&gt;</span></span><br></pre></td></tr></table></figure><div class="note danger flat"><p>经过测试，在PC端、手机端各浏览器都工作正常，唯独在iPad设备中背景模糊特效图片会时不时发生闪烁且残缺不全的状况，暂时无力解决，慎用</p></div>解决不了问题那就消除问题好了，在移动端，我直接将blur层给置为<code>none</code>了😅<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">@media</span> <span class="keyword">only</span> screen <span class="keyword">and</span> (<span class="attribute">max-width</span>: <span class="number">1500px</span>)&#123;</span><br><span class="line">    <span class="selector-class">.dyblurbg</span> &#123;</span><br><span class="line">        <span class="attribute">display</span>: none;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li>之前在Volantis主题中根据<a href="https://cloud.tencent.com/developer/article/1597223">参考文章</a>增加了文章日历图，稍稍改一点应用到Butterfly主题下<div class="btns rounded center dy">            <a class="button" href='https://cdn.statically.io/gh/celestezj/ImageHosting/master/download/post-calendar.pug' title='下载资源'><i class='fas fa-download'></i>下载资源</a>          </div><ol><li>将下载下来的源码文件（<em>post-calendar.pug</em>）粘贴到<i>themes/butterfly/layout/includes/</i>目录下</li><li>在<em>themes/butterfly/source/css/mystyle.css</em>中添加样式：<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"> <span class="selector-id">#post-calendar</span> &#123;</span><br><span class="line">     <span class="attribute">height</span>: <span class="number">225px</span>;</span><br><span class="line">     <span class="attribute">width</span>: <span class="number">100%</span>;</span><br><span class="line">     <span class="attribute">margin-top</span>: <span class="number">20px</span>;</span><br><span class="line">     <span class="attribute">border-radius</span>: <span class="number">12px</span>;</span><br><span class="line">     <span class="attribute">background</span>:<span class="built_in">rgba</span>(<span class="number">255</span>,<span class="number">255</span>,<span class="number">255</span>,<span class="number">0</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li>在<em>themes/butterfly/layout/archive.pug</em>中引入<em>post-calendar.pug</em>，在<code>#archive</code>位置下插入一行：<code>include includes/post-calendar</code>，注意空格，如下：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">...</span><br><span class="line">#archive</span><br><span class="line">  include includes/post-calendar</span><br><span class="line">  .article-sort-title= _p(&#x27;page.articles&#x27;) + &#x27; - &#x27; + site.posts.length</span><br><span class="line">...</span><br></pre></td></tr></table></figure></li><li>在主题配置文件（<em>_config.butterfly.yml</em>）中<code>inject</code>项中引入依赖文件：<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">inject:</span></span><br><span class="line">  <span class="attr">head:</span></span><br><span class="line">    <span class="string">...</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;/css/mystyle.css&quot;&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">src=&quot;http://cdn.staticfile.org/moment.js/2.24.0/moment.min.js&quot;&gt;&lt;/script&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">src=&quot;https://cdn.statically.io/gh/InfiniteYinux/cloud/2.44/Hexo/themeConfig/echarts.min.js&quot;&gt;&lt;/script&gt;</span></span><br><span class="line">    <span class="string">...</span></span><br></pre></td></tr></table></figure></li></ol>注：目前本博客已去除文章日历，示例可参见：<s><a href="https://celestezj.github.io/archives/">https://celestezj.github.io/archives/</a></s></li><li>对相关文章的样式进行了修改（似乎比原来美观了那么一点点，或者还是丑陋~），目前只在电脑端体验<br>注：不需要修改主题源文件，只需要在<em>butterfly/source/css/mystyle.css</em>中添加即可<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">@media</span> <span class="keyword">only</span> screen <span class="keyword">and</span> (<span class="attribute">min-width</span>: <span class="number">1500px</span>)&#123;</span><br><span class="line">  </span><br><span class="line">  <span class="selector-class">.relatedPosts</span> &gt; <span class="selector-class">.relatedPosts-list</span> <span class="selector-tag">div</span> &#123;</span><br><span class="line">      <span class="attribute">background</span>: <span class="number">#f6f6f6</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-class">.relatedPosts</span>&#123;</span><br><span class="line">      <span class="attribute">background</span>: <span class="number">#121212</span> <span class="meta">!important</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-class">.relatedPosts</span> &gt; <span class="selector-class">.relatedPosts-list</span> <span class="selector-tag">div</span>&#123;</span><br><span class="line">      <span class="attribute">background</span>: <span class="number">#121212</span> <span class="meta">!important</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="selector-class">.relatedPosts</span> &gt; <span class="selector-class">.relatedPosts-list</span> <span class="selector-class">.cover</span> &#123;</span><br><span class="line">      <span class="attribute">height</span>: <span class="number">66%</span>;</span><br><span class="line">      <span class="attribute">opacity</span>: <span class="number">0.8</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="selector-class">.relatedPosts</span> &gt; <span class="selector-class">.relatedPosts-list</span> <span class="selector-class">.content</span> &#123;</span><br><span class="line">      <span class="attribute">top</span>: <span class="number">85%</span> <span class="meta">!important</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="selector-class">.relatedPosts</span> &gt; <span class="selector-class">.relatedPosts-list</span> <span class="selector-class">.content</span> <span class="selector-class">.title</span>, <span class="selector-class">.date</span> &#123;</span><br><span class="line">      <span class="attribute">color</span>: <span class="number">#888888</span> <span class="meta">!important</span>;</span><br><span class="line">      <span class="attribute">font-size</span>: <span class="number">0.82rem</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="selector-class">.relatedPosts</span> &gt; <span class="selector-class">.relatedPosts-list</span> <span class="selector-class">.content</span> <span class="selector-class">.title</span> &#123;</span><br><span class="line">      <span class="attribute">color</span>: <span class="number">#656261</span> <span class="meta">!important</span>;</span><br><span class="line">      <span class="attribute">height</span>: <span class="number">50px</span>;</span><br><span class="line">      <span class="attribute">display</span>: block;</span><br><span class="line">      <span class="attribute">overflow</span>:hidden;</span><br><span class="line">      <span class="attribute">white-space</span>: nowrap;</span><br><span class="line">      <span class="attribute">text-overflow</span>:ellipsis;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="selector-class">.relatedPosts</span> &gt; <span class="selector-class">.relatedPosts-list</span> <span class="selector-class">.content</span> <span class="selector-class">.title</span><span class="selector-pseudo">:hover</span> &#123;</span><br><span class="line">      <span class="attribute">color</span>: red <span class="meta">!important</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="selector-class">.relatedPosts</span> &#123;</span><br><span class="line">      <span class="attribute">background</span>: <span class="number">#f6f6f6</span> <span class="meta">!important</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="selector-class">.relatedPosts</span> &gt; <span class="selector-class">.relatedPosts-list</span> &#123;</span><br><span class="line">      <span class="attribute">width</span>: <span class="number">94%</span> <span class="meta">!important</span>;</span><br><span class="line">      <span class="attribute">margin</span>: <span class="number">0</span> auto;</span><br><span class="line">      <span class="attribute">height</span>: <span class="number">215px</span>;</span><br><span class="line">      <span class="attribute">overflow</span>: scroll;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="selector-class">.relatedPosts</span> &gt; <span class="selector-class">.headline</span> &#123;</span><br><span class="line">      <span class="attribute">font-size</span>: <span class="number">1.1em</span>;</span><br><span class="line">      <span class="attribute">margin-left</span>: <span class="number">3%</span>;</span><br><span class="line">      <span class="attribute">padding-top</span>: <span class="number">14.5px</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-class">.relatedPosts</span> &gt; <span class="selector-class">.headline</span> &#123;</span><br><span class="line">      <span class="attribute">color</span>: <span class="number">#b8b8b8</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  ::-webkit-scrollbar &#123;</span><br><span class="line">      <span class="attribute">width</span>: <span class="number">5px</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  ::-webkit-scrollbar-corner &#123;</span><br><span class="line">      <span class="attribute">background-color</span>: <span class="number">#f6f6f6</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> ::-webkit-scrollbar-corner &#123;</span><br><span class="line">      <span class="attribute">background-color</span>: <span class="number">#121212</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li>为存档、分类、标签页面的文章列表中的头图添加大图预览<ol><li>新建<i>themes/butterfly/source/js/article_img_preview.js</i>文件：<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">this</span>.<span class="property">imagePreview</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  xOffset = <span class="number">10</span>;</span><br><span class="line">  yOffset = <span class="number">30</span>;</span><br><span class="line">  $(<span class="string">&quot;a.article-sort-item-img&quot;</span>).<span class="title function_">hover</span>(<span class="keyword">function</span>(<span class="params">e</span>)&#123;</span><br><span class="line">     <span class="variable language_">this</span>.<span class="property">t</span> = <span class="variable language_">this</span>.<span class="property">title</span>;</span><br><span class="line">     <span class="keyword">var</span> c = (<span class="variable language_">this</span>.<span class="property">t</span> != <span class="string">&quot;&quot;</span>) ? <span class="string">&quot;&lt;br/&gt;&quot;</span> + <span class="variable language_">this</span>.<span class="property">t</span> : <span class="string">&quot;&quot;</span>;</span><br><span class="line">     $(<span class="string">&quot;body&quot;</span>).<span class="title function_">append</span>(<span class="string">&quot;&lt;div id=&#x27;article-img-preview&#x27;&gt;&lt;img src=&#x27;&quot;</span>+ $(<span class="variable language_">this</span>).<span class="title function_">find</span>(<span class="string">&#x27;img&#x27;</span>).<span class="title function_">attr</span>(<span class="string">&#x27;src&#x27;</span>) +<span class="string">&quot;&#x27; alt=&#x27;Article Image Preview&#x27; style=&#x27;width:300px;&#x27; /&gt;&quot;</span>+ c +<span class="string">&quot;&lt;/div&gt;&quot;</span>);</span><br><span class="line">     $(<span class="string">&quot;#article-img-preview&quot;</span>)</span><br><span class="line">         .<span class="title function_">css</span>(<span class="string">&quot;top&quot;</span>,(e.<span class="property">pageY</span> - xOffset) + <span class="string">&quot;px&quot;</span>)</span><br><span class="line">         .<span class="title function_">css</span>(<span class="string">&quot;left&quot;</span>,(e.<span class="property">pageX</span> + yOffset) + <span class="string">&quot;px&quot;</span>)</span><br><span class="line">         .<span class="title function_">fadeIn</span>(<span class="string">&quot;fast&quot;</span>);</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">     $(<span class="string">&quot;#article-img-preview&quot;</span>).<span class="title function_">remove</span>();</span><br><span class="line">  &#125;);</span><br><span class="line">  $(<span class="string">&quot;a.article-sort-item-img&quot;</span>).<span class="title function_">mousemove</span>(<span class="keyword">function</span>(<span class="params">e</span>)&#123;</span><br><span class="line">     $(<span class="string">&quot;#article-img-preview&quot;</span>)</span><br><span class="line">         .<span class="title function_">css</span>(<span class="string">&quot;top&quot;</span>,(e.<span class="property">pageY</span> - xOffset) + <span class="string">&quot;px&quot;</span>)</span><br><span class="line">         .<span class="title function_">css</span>(<span class="string">&quot;left&quot;</span>,(e.<span class="property">pageX</span> + yOffset) + <span class="string">&quot;px&quot;</span>);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// starting the script on page load</span></span><br><span class="line">$(<span class="variable language_">document</span>).<span class="title function_">ready</span>(<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="title function_">imagePreview</span>();</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></li><li>在<i>themes/butterfly/source/css/mystyle.css</i>中添加预览图所在div样式：<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-id">#article-img-preview</span>&#123;</span><br><span class="line">  <span class="attribute">position</span>:absolute;</span><br><span class="line">  <span class="attribute">background</span>:<span class="number">#333</span>;</span><br><span class="line">  <span class="attribute">padding</span>:<span class="number">5px</span>;</span><br><span class="line">  <span class="attribute">display</span>:none;</span><br><span class="line">  <span class="attribute">color</span>:<span class="number">#fff</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li>在主题配置文件的<code>inject</code>项中引入上述脚本以及jQuery库：<figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">inject:</span><br><span class="line">  head:</span><br><span class="line"><span class="code">    ...</span></span><br><span class="line"><span class="code">    - &lt;script src=&quot;https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js&quot;&gt;&lt;/script&gt;</span></span><br><span class="line"><span class="code">    - &lt;script src=&quot;/js/article_img_preview.js&quot;&gt;&lt;/script&gt;</span></span><br><span class="line"><span class="code">    ...</span></span><br></pre></td></tr></table></figure></li></ol>好了，这就OK了，无需修改任何其他主题源码<br>考虑到大部分人都会在主题配置中启用pjax，下面给出（在上述基础上）适配pjax的修改版本<blockquote><p>使用pjax后，一些用户自定义的js脚本在页面跳转时可能需要重新调用，参见主题<a href="https://butterfly.js.org/posts/ceeb73f/#Pjax">文档</a><br>将待执行的jquery代码用一个函数包裹起来，然后通过<code>btf.isJqueryLoad(包裹函数)</code>调用以避免多次加载jquery，参见主题<a href="https://butterfly.js.org/posts/4073eda/#jQuery-%E5%8A%A0%E8%BC%89">文档</a></p></blockquote><ol><li>删除主题配置<code>inject</code>项中<code>jquery.min.js</code>的引用</li><li>替换<i>themes/butterfly/source/js/article_img_preview.js</i>文件：<a class="btn-beautify button--animated purple" href="https://cdn.statically.io/gh/celestezj/ImageHosting/v0.9/data/img_preview/article_img_preview.js"   title="下载"><i class="far fa-hand-point-right faa-horizontal animated fa-fw"></i><span>下载</span></a></li><li>修改<i>themes/butterfly/layout/includes/layout.pug</i>文件，在最后一行添加（注意空格，script打头空两格）：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">script(data-pjax).</span><br><span class="line">  btf.isJqueryLoad(image_preview_wrapper);</span><br></pre></td></tr></table></figure></li></ol></li><li>发现一款有意思的“<a href="https://cndrew.cn/2019/10/19/plugin/">随机文章</a>”插件，不过正如作者所说，插件目前存在一个<i>bug</i>，当用于其他主题（非<i>Sakura</i>主题）时可能将无关页面载入随机文章列表。为了正确引入该功能，我给出两种方案<ul><li>按照原插件的思路，生成一个<i>random.html</i>页面，页面脚本存储着可供随机选择的全部文章列表，当访问该页面时候，浏览器自动跳转到某一随机文章页面，具体代码效仿<i>404.html</i>页面的生成：<ol><li>新建<i>themes/butterfly/layout/random.pug</i>文件：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">doctype html</span><br><span class="line">html(lang=config.language data-theme=theme.display_mode)</span><br><span class="line">  head</span><br><span class="line">  body(onload=&quot;javascript:dogo();&quot;)</span><br><span class="line">    - let random_articles = []</span><br><span class="line">    - site.posts.each(function (article) &#123;</span><br><span class="line">      - let if_random = article.random == true || article.random == false ? article.random : theme.random_article</span><br><span class="line">      - if (if_random) random_articles.push(url_for(article.path))</span><br><span class="line">  - &#125;)</span><br><span class="line">  script.</span><br><span class="line">  function dogo()&#123;</span><br><span class="line">    var urls=&quot;#&#123;random_articles&#125;&quot;;</span><br><span class="line">    urls=urls.split(&quot;,&quot;);</span><br><span class="line">    n = Math.floor(Math.random()*urls.length);</span><br><span class="line">    location.href= urls[n];</span><br><span class="line">  &#125;;</span><br></pre></td></tr></table></figure></li><li>新建<i>themes/butterfly/scripts/events/random.js</i>文件：<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* Butterfly</span></span><br><span class="line"><span class="comment">* random article page</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="meta"></span></span><br><span class="line"><span class="meta">&#x27;use strict&#x27;</span></span><br><span class="line"></span><br><span class="line">hexo.<span class="property">extend</span>.<span class="property">generator</span>.<span class="title function_">register</span>(<span class="string">&#x27;random&#x27;</span>, <span class="keyword">function</span> (<span class="params">locals</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="attr">path</span>: <span class="string">&#x27;random/index.html&#x27;</span>,</span><br><span class="line">    <span class="attr">data</span>: locals.<span class="property">posts</span>,</span><br><span class="line">    <span class="attr">layout</span>: [<span class="string">&#x27;random&#x27;</span>]</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure></li><li>在导航栏添加随机文章超链接，地址指向<i>/random/</i>，编辑主题配置文件：<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">menu:</span></span><br><span class="line">  <span class="string">.</span> <span class="string">.</span> <span class="string">.</span></span><br><span class="line">  <span class="string">随便看看:</span> <span class="string">/random/</span> <span class="string">||</span> <span class="string">fas</span> <span class="string">fa-layer-group</span> <span class="string">faa-tada</span></span><br><span class="line">  <span class="string">.</span> <span class="string">.</span> <span class="string">.</span></span><br></pre></td></tr></table></figure></li><li>最后在主题配置文件中新增配置：<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">random_article:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>表示默认将所有<i>post</i>文章都添加到随机列表，你可以在<i>post</i>的<i>front-matter</i>中覆盖此配置，譬如：<figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">. . .</span><br><span class="line">random: false</span><br><span class="line"><span class="section">. . .</span></span><br><span class="line"><span class="section">---</span></span><br></pre></td></tr></table></figure>这意味着当前<i>post</i>文章不会被添加到随机列表中</li></ol></li><li>不借助<i>random.html</i>页面，直接将随机跳转脚本写在<i>layout.pug</i>模板中（如果你启用了<i>pjax</i>，建议使用此方法）：<ol><li>新建<i>themes/butterfly/layout/includes/random-js.pug</i>文件：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">- let random_articles = []</span><br><span class="line">- site.posts.each(function (article) &#123;</span><br><span class="line">  - let if_random = article.random == true || article.random == false ? article.random : theme.random_article</span><br><span class="line">  - if (if_random) random_articles.push(url_for(article.path))</span><br><span class="line">- &#125;)</span><br><span class="line">script.</span><br><span class="line">  function dogo()&#123;</span><br><span class="line">    var urls=&quot;#&#123;random_articles&#125;&quot;;</span><br><span class="line">    urls=urls.split(&quot;,&quot;);</span><br><span class="line">    n = Math.floor(Math.random()*urls.length);</span><br><span class="line">    pjax.loadUrl(urls[n]);</span><br><span class="line">  &#125;;</span><br></pre></td></tr></table></figure></li><li>编辑<i>themes/butterfly/layout/includes/layout.pug</i>文件，在<code>include ./additional-js.pug</code>下一行添加即可：<figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">include ./additional-js.pug</span><br><span class="line"><span class="addition">+ include ./random-js.pug</span></span><br></pre></td></tr></table></figure></li><li>编辑主题配置文件，在导航栏添加随机文章超链接：<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">menu:</span></span><br><span class="line">  <span class="string">.</span> <span class="string">.</span> <span class="string">.</span></span><br><span class="line">  <span class="string">友链:</span> <span class="string">/link/</span> <span class="string">||</span> <span class="string">fas</span> <span class="string">fa-link</span> <span class="string">||</span></span><br><span class="line">  <span class="string">随便看看:</span> <span class="string">javascript:void(0);</span> <span class="string">||</span> <span class="string">fas</span> <span class="string">fa-layer-group</span> <span class="string">faa-tada</span> <span class="string">||</span> <span class="string">dogo()</span></span><br><span class="line">  <span class="string">.</span> <span class="string">.</span> <span class="string">.</span></span><br></pre></td></tr></table></figure>原本只有一个<code>||</code>间隔，左边表示链接地址，右边为图标标识，修改后，有两个<code>||</code>间隔，左边为链接，中间为标识，右边为<code>onclick</code>属性值，为此修改<i>themes/butterfly/layout/includes/header/menu_item.pug</i>文件：<figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">. . .</span><br><span class="line"><span class="deletion">- a.site-page(href=url_for(trim(value.split(&#x27;||&#x27;)[0])))</span></span><br><span class="line"><span class="addition">+ a.site-page(href=url_for(trim(value.split(&#x27;||&#x27;)[0])),onclick=trim(value.split(&#x27;||&#x27;)[2]))</span></span><br><span class="line">. . .</span><br></pre></td></tr></table></figure>还有一处：<figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">. . .</span><br><span class="line"><span class="deletion">- a.site-page.child.faa-parent.animated-hover(href=url_for(trim(val.split(&#x27;||&#x27;)[0])))</span></span><br><span class="line"><span class="addition">+ a.site-page.child.faa-parent.animated-hover(href=url_for(trim(val.split(&#x27;||&#x27;)[0])),onclick=trim(val.split(&#x27;||&#x27;)[2]))</span></span><br><span class="line">. . .</span><br></pre></td></tr></table></figure></li><li>最后仍需在主题配置文件中新增配置（同样可以在<i>front-matter</i>中覆盖）：<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">random_article:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure></li></ol></li></ul></li><li>添加春节灯笼，灯笼样式来自博主<a href="https://nekodeng.gitee.io/posts/hexo-spring-christmas.html" target="_blank">itsNeko</a>，步骤如下：<ol><li>编辑主题配置文件，引入样式文件：<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">inject:</span></span><br><span class="line">  <span class="attr">head:</span></span><br><span class="line">    <span class="string">.</span> <span class="string">.</span> <span class="string">.</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;https://cdn.statically.io/gh/celestezj/Mirror1ImageHosting/master/data/denglong/denglong.css&quot;&gt;</span></span><br><span class="line">    <span class="string">.</span> <span class="string">.</span> <span class="string">.</span></span><br></pre></td></tr></table></figure></li><li>编辑<i>themes/butterfly/layout/includes/layout.pug</i>，在页面中添加灯笼<code>&lt;div&gt;</code>标签：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">body</span><br><span class="line">  . . .</span><br><span class="line">  if theme.denglong</span><br><span class="line">    .denglong</span><br><span class="line">      .deng-box</span><br><span class="line">      .deng</span><br><span class="line">          .xian</span><br><span class="line">          .deng-a</span><br><span class="line">            .deng-b</span><br><span class="line">              .deng-t 喜迎</span><br><span class="line">          .shui.shui-a</span><br><span class="line">            .shui-c</span><br><span class="line">            .shui-b</span><br><span class="line">      .deng-box1</span><br><span class="line">        .deng</span><br><span class="line">          .xian</span><br><span class="line">          .deng-a</span><br><span class="line">            .deng-b</span><br><span class="line">              .deng-t 春节</span><br><span class="line">          .shui.shui-a</span><br><span class="line">            .shui-c</span><br><span class="line">            .shui-b</span><br><span class="line">  . . .</span><br></pre></td></tr></table></figure></li><li>再次编辑主题配置文件，引入开关：<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">denglong:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>执行<code>hexo g</code>、<code>hexo s</code>就可以看到位于网站左上角的灯笼了</li></ol></li><li>参考糖果屋<a href="https://akilar.vercel.app/posts/ecff41cf/" target="_blank">Akilar</a>和<a href="https://hassanwong.top/posts/7a869374/" target="_blank">Hassan</a>，修改顶栏菜单样式<ol><li>在<i>themes/butterfly/source/css/mystyle.css</i>中新增样式：<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*顶部菜单栏居中*/</span></span><br><span class="line"><span class="selector-id">#nav</span> <span class="selector-class">.menus_items</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: flex;</span><br><span class="line">  <span class="attribute">justify-content</span>: center;</span><br><span class="line">  <span class="attribute">position</span>: absolute;</span><br><span class="line">  <span class="attribute">width</span>: <span class="number">500px</span>;</span><br><span class="line">  <span class="attribute">left</span>: <span class="number">0</span>;</span><br><span class="line">  <span class="attribute">right</span>: <span class="number">0</span>;</span><br><span class="line">  <span class="attribute">top</span>: <span class="number">10px</span>;</span><br><span class="line">  <span class="attribute">margin</span>: auto;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/* 横向排布子菜单 */</span></span><br><span class="line"><span class="selector-id">#nav</span> <span class="selector-class">.menus_items</span> <span class="selector-class">.menus_item</span> <span class="selector-class">.menus_item_child</span> <span class="selector-tag">li</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: inline-block;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/* 圆角隐藏 */</span></span><br><span class="line"><span class="selector-id">#nav</span> <span class="selector-tag">ul</span><span class="selector-class">.menus_item_child</span> &#123;</span><br><span class="line">  <span class="attribute">overflow</span>: hidden;</span><br><span class="line">  <span class="attribute">border-radius</span>: <span class="number">5px</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/* 调整空隙，确保不会天下武功唯快不破 */</span></span><br><span class="line"><span class="selector-id">#nav</span> <span class="selector-class">.menus_items</span> <span class="selector-class">.menus_item</span> <span class="selector-class">.menus_item_child</span> &#123;</span><br><span class="line">  <span class="attribute">margin-top</span>: <span class="number">0px</span> <span class="meta">!important</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li>修改<i>themes/butterfly/layout/includes/header/menu_item.pug</i>：<figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="deletion">- ul.menus_item_child</span></span><br><span class="line"><span class="addition">+ ul.menus_item_child(style=`left:`+ (-5.6 * Object.keys(value).join(&quot;&quot;).length - 40.3) + `px;`)</span></span><br></pre></td></tr></table></figure><div class="hide-block"><button type="button" class="hide-button button--animated" style="">图释    </button><div class="hide-content"><img src="https://i.loli.net/2021/09/02/oHDuIsYpaGSU2k8.png"><div onclick="reshowhidetag(this)" class="button button-tiny">重新隐藏</div></div></div>注意，稍稍不同于Akilar的计算方式<code>x * Object.keys(value).length + y</code>，譬如我有两个二级菜单，每个都有三项，这种方式计算的left偏移值应该是相同的，但是我这两个二级菜单宽度并不一样啊，所以替换为<code>x * Object.keys(value).join(&quot;&quot;).length + y</code>更合理</li></ol></li><li><a href="https://plotly.com/javascript/">Plotly</a>是一个基于<a href="https://d3js.org/">d3.js</a>与<a href="https://github.com/stackgl">stack.gl</a>的图形库，它可以用来绘制各种类型的图表，比如散点图、折线图、饼图、柱状图甚至3D图形等，与butterfly主题的集成可以参考这篇<a href="https://mertbakir.gitlab.io/hugo/plotly-with-hugo/">Plotly &amp; Hugo</a><!--参考：https://www.bmpi.dev/self/my-drawing-toolbox/--><ol><li>绘制三维散点图的python示例代码如下：<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> plotly.graph_objects <span class="keyword">as</span> go</span><br><span class="line"><span class="keyword">from</span> plotly.graph_objs <span class="keyword">import</span> Layout</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="comment"># Generate sample data</span></span><br><span class="line">np.random.seed(<span class="number">42</span>)</span><br><span class="line">x = np.random.rand(<span class="number">100</span>)</span><br><span class="line">y = np.random.rand(<span class="number">100</span>)</span><br><span class="line">z = np.random.rand(<span class="number">100</span>)</span><br><span class="line"><span class="comment"># Create a 3D scatter plot</span></span><br><span class="line">layout = Layout(</span><br><span class="line">    paper_bgcolor=<span class="string">&#x27;black&#x27;</span>, <span class="comment">#设置黑色背景</span></span><br><span class="line">    plot_bgcolor=<span class="string">&#x27;rgba(0,0,0,0)&#x27;</span></span><br><span class="line">)</span><br><span class="line">fig = go.Figure(data=[go.Scatter3d(x=x, y=y, z=z, mode=<span class="string">&#x27;markers&#x27;</span>, marker=<span class="built_in">dict</span>(size=<span class="number">8</span>, color=z, colorscale=<span class="string">&#x27;Viridis&#x27;</span>))], layout=layout)</span><br><span class="line"><span class="comment"># Add title and labels</span></span><br><span class="line">fig.update_layout(scene=<span class="built_in">dict</span>(xaxis_title=<span class="string">&#x27;X-axis&#x27;</span>, yaxis_title=<span class="string">&#x27;Y-axis&#x27;</span>, zaxis_title=<span class="string">&#x27;Z-axis&#x27;</span>, </span><br><span class="line">                  xaxis=<span class="built_in">dict</span>(backgroundcolor=<span class="string">&#x27;rgba(0,0,0,0)&#x27;</span>,gridcolor=<span class="string">&#x27;rgba(173, 216, 230, 0.8)&#x27;</span>,color=<span class="string">&#x27;white&#x27;</span>),</span><br><span class="line">                  yaxis=<span class="built_in">dict</span>(backgroundcolor=<span class="string">&#x27;rgba(0,0,0,0)&#x27;</span>,gridcolor=<span class="string">&#x27;rgba(173, 216, 230, 0.8)&#x27;</span>,color=<span class="string">&#x27;white&#x27;</span>),</span><br><span class="line">                  zaxis=<span class="built_in">dict</span>(backgroundcolor=<span class="string">&#x27;rgba(0,0,0,0)&#x27;</span>,gridcolor=<span class="string">&#x27;rgba(173, 216, 230, 0.8)&#x27;</span>,color=<span class="string">&#x27;white&#x27;</span>))) <span class="comment">#设置坐标轴背景颜色为透明</span></span><br><span class="line"><span class="comment"># 取消图像和边框之间的 margin</span></span><br><span class="line">fig.update_layout(margin=<span class="built_in">dict</span>(l=<span class="number">0</span>, r=<span class="number">0</span>, t=<span class="number">0</span>, b=<span class="number">0</span>))</span><br><span class="line"><span class="comment"># Show the plot</span></span><br><span class="line">fig.show()</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> plotly.io <span class="keyword">import</span> write_image</span><br><span class="line"><span class="comment">#... Generate the fig here.</span></span><br><span class="line">fig.write_json(<span class="string">&quot;plotly_demo.json&quot;</span>)</span><br></pre></td></tr></table></figure></li><li>通过HTML+JS读取步骤一保存的json图像数据文件并显示：<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://cdn.plot.ly/plotly-latest.min.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;demo1&quot;</span> <span class="attr">class</span>=<span class="string">&quot;plotly&quot;</span> <span class="attr">style</span>=<span class="string">&quot;height:600px&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="title class_">Plotly</span>.<span class="property">d3</span>.<span class="title function_">json</span>(<span class="string">&#x27;http://192.168.0.103:8080/plotly_demo.json&#x27;</span>, <span class="keyword">function</span>(<span class="params">err, fig</span>) &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="title class_">Plotly</span>.<span class="title function_">plot</span>(<span class="string">&#x27;demo1&#x27;</span>, fig.<span class="property">data</span>, fig.<span class="property">layout</span>, &#123;<span class="attr">responsive</span>: <span class="literal">true</span>&#125;);</span></span><br><span class="line"><span class="language-javascript">  &#125;);</span></span><br><span class="line"><span class="language-javascript">  </span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>这里涉及到跨域问题，浏览器不允许使用file协议访问plotly_demo.json，会报错：“Access to XMLHttpRequest at ‘file:///C:/Users/muggledy/Downloads/plotly_demo.json’ from origin ‘null’ has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome, https”，于是使用<a href="https://www.npmjs.com/package/anywhere">anywhere</a>将本地目录变成一个静态文件服务器的根目录：<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">C:\Users\muggledy\Downloads&gt; npm install anywhere -g</span><br><span class="line">C:\Users\muggledy\Downloads&gt; anywhere -p 8080</span><br></pre></td></tr></table></figure></li><li>现在让我们将其集成到butterfly主题中，首先将plotly.js cdn链接放在<i>_config.butterfly.yml</i>配置文件中：<figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">CDN:</span></span><br><span class="line">  <span class="comment"># plotly.js</span></span><br><span class="line">  <span class="attr">plotly_js:</span> <span class="string">https://cdn.plot.ly/plotly-latest.min.js</span></span><br></pre></td></tr></table></figure>要启用plotly绘图，需要在文章front-matter头部添加<code>plotly:enable</code>来引入上述plotly.js，我们在<i>butterfly/layout/includes/head.pug</i>中加以控制：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">if page.plotly</span><br><span class="line">  script(src=url_for(theme.CDN.plotly_js))</span><br></pre></td></tr></table></figure>最后编写标签插件简化书写：<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&#x27;use strict&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">plotly</span>(<span class="params">args</span>) &#123;</span><br><span class="line">  args = args.<span class="title function_">join</span>(<span class="string">&#x27; &#x27;</span>).<span class="title function_">split</span>(<span class="string">&#x27;, &#x27;</span>)</span><br><span class="line">  <span class="keyword">let</span> id = args[<span class="number">0</span>].<span class="title function_">trim</span>();</span><br><span class="line">  <span class="keyword">let</span> json_url = args[<span class="number">1</span>].<span class="title function_">trim</span>();</span><br><span class="line">  <span class="keyword">let</span> style = <span class="string">&#x27;&#x27;</span>;</span><br><span class="line">  <span class="keyword">if</span> (args.<span class="property">length</span> &gt; <span class="number">2</span>) &#123;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">2</span>; i &lt; args.<span class="property">length</span>; i++) &#123;</span><br><span class="line">      <span class="keyword">let</span> tmp = args[i].<span class="title function_">trim</span>();</span><br><span class="line">      <span class="keyword">if</span> (tmp.<span class="title function_">includes</span>(<span class="string">&#x27;height=&#x27;</span>)) &#123;</span><br><span class="line">        style += <span class="string">&#x27;height:&#x27;</span> + tmp.<span class="title function_">substring</span>(<span class="number">7</span>, tmp.<span class="property">length</span>) + <span class="string">&#x27;;&#x27;</span>;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span> (!style.<span class="title function_">includes</span>(<span class="string">&#x27;height:&#x27;</span>)) &#123;</span><br><span class="line">    style += <span class="string">&#x27;height:400px;&#x27;</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> <span class="string">`&lt;div id=&quot;<span class="subst">$&#123;id&#125;</span>&quot; class=&quot;plotly&quot; style=&quot;<span class="subst">$&#123;style&#125;</span>&quot;&gt;&lt;/div&gt;</span></span><br><span class="line"><span class="string">&lt;script&gt;</span></span><br><span class="line"><span class="string">Plotly.d3.json(&quot;<span class="subst">$&#123;json_url&#125;</span>&quot;, function(err, fig) &#123;</span></span><br><span class="line"><span class="string">    Plotly.plot(&quot;<span class="subst">$&#123;id&#125;</span>&quot;, fig.data, fig.layout, &#123;responsive: true&#125;);</span></span><br><span class="line"><span class="string">&#125;);</span></span><br><span class="line"><span class="string">&lt;/script&gt;`</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// &#123;% plotly id, json_url[, height=400px] %&#125;</span></span><br><span class="line">hexo.<span class="property">extend</span>.<span class="property">tag</span>.<span class="title function_">register</span>(<span class="string">&#x27;plotly&#x27;</span>, plotly);</span><br></pre></td></tr></table></figure></li><li>示例，<code>&#123;% plotly plotly_demo1, http://192.168.0.103:8080/plotly_demo.json[, height=400px] %&#125;</code>：<!--最新实现：不需要在front-matter中添加plotly:true来引入plotlyjs了，因为无法适配pjax（pjax不支持script的局部刷新），现在我们在哪个文章页面需要plotly绘图就手动引入一下plotlyjs就好了，当前实现已非常nice！单页面绘制多图、或者页面pjax切换时不会产生任何重复引入--><div id="plotly_demo1" class="plotly dyplotlydiv" style="height:400px;"></div><script>(function loadPlotlyScript(url, callback) {    if ((typeof window.plotly_js_imported === 'undefined') || (!window.plotly_js_imported) || (typeof Plotly === 'undefined')) {        var script = document.createElement('script');        script.src = url;        script.async = true; // 异步加载        script.onload = function() {            window.plotly_js_imported = true;            // 脚本加载完成后执行回调函数            if (callback && typeof callback === 'function') {                callback();            }        };        document.head.appendChild(script);    } else {        if (callback && typeof callback === 'function') {            callback();        }    }})("https://cdn.plot.ly/plotly-latest.min.js", function() {    var plotlyTitleElement = null;    var plotlyDiv = null;    Plotly.d3.json("https://muggledy.github.io/appendix/plotly_demo.json", function(err, fig) {        Plotly.plot("plotly_demo1", fig.data, fig.layout, {responsive: true});        setTimeout(() => {            plotlyDiv = document.getElementById('plotly_demo1');            if (plotlyDiv) {                //找到<title>元素并删除，否则会导致pjax页面切换失败，报错：pjax.min.js:1 Pjax switch fail:  DOM doesn’t look the same on new loaded page: ’title’ - new 1, old 2。关于pjax，可以参见：https://akilar.top/posts/3b78b69a/、https://www.bytezonex.com/archives/aEycaFEG.html                plotlyTitleElement = plotlyDiv.querySelector('title');                if (plotlyTitleElement) {                    plotlyTitleElement.remove();                }            }        }, 50);    });});</script></li></ol></li></ul><script>function reshowhidetag(ele){    ele.parentNode.previousElementSibling.classList.remove("open");}</script>]]></content>
      
      
      
        <tags>
            
            <tag> Butterfly </tag>
            
        </tags>
      
    </entry>
    
    
  
  
</search>
