<p>下面是一个使用查找表的方法:</p>
<pre><code>>>> alphabet = np.array(list('ACGT'))
>>> alphabet
array(['A', 'C', 'G', 'T'], dtype='<U1')
</code></pre>
<p>要使用查找表,我们需要将字母重新解释为索引,这是通过视图转换完成的:</p>
^{pr2}$
<p>我们现在可以构建它需要的<code>85</code>槽,实际上我们只使用4个插槽,即<code>65</code>,<code>67</code>,<code>71</code>和{<cd5>}。至于输出格式,我们可以自由选择最符合我们要求的格式:</p>
<p>示例一-输出为bytestring:</p>
<pre><code>>>> lookup_1 = np.zeros((alph_as_num.max()+1), dtype='S4')
>>> lookup_1[alph_as_num] = [b'0001000'[i:i+4] for i in range(4)]
</code></pre>
<p>示例二-输出为<code>uint8</code>:</p>
<pre><code>>>> lookup_2 = np.zeros((alph_as_num.max()+1), dtype=np.uint8)
>>> lookup_2[alph_as_num] = 1 << np.arange(4)
</code></pre>
<p>示例三-输出为每个字母四<code>uint8</code>:</p>
<pre><code>>>> lookup_3 = np.zeros((alph_as_num.max()+1, 4), dtype=np.uint8)
>>> lookup_3[alph_as_num[::-1]] = np.identity(4)
</code></pre>
<p>现在让我们将其应用于<code>100</code>字母序列:</p>
<pre><code>>>> seq
array(['CATTTCTCCACCATTTTGGTTTTTCATTGATCCGTTAGGTGGAGCCGGACTATGTCTACCGAAAGATGCACCTGCGCCGGGTCTGGTCTATCTCTTAATG'],
dtype='<U100')
</code></pre>
<p>因为它只依赖于</p>
<ul>
<li><p><strong>numpy内置的高级索引</strong>它使我们可以非常快速地查找(例如,比Python字典快得多)</p></li>
<li><p><strong>视图转换</strong>这基本上是免费的,因为它所做的只是重新解释数据缓冲区(没有任何复制或转换)</p></li>
</ul>
<p>示例一-bytestrings:</p>
<pre><code>>>> lookup_1[seq.view(np.int32)]
array([b'0010', b'0001', b'1000', b'1000', b'1000', b'0010', b'1000',
b'0010', b'0010', b'0001', b'0010', b'0010', b'0001', b'1000',
b'1000', b'1000', b'1000', b'0100', b'0100', b'1000', b'1000',
b'1000', b'1000', b'1000', b'0010', b'0001', b'1000', b'1000',
b'0100', b'0001', b'1000', b'0010', b'0010', b'0100', b'1000',
b'1000', b'0001', b'0100', b'0100', b'1000', b'0100', b'0100',
b'0001', b'0100', b'0010', b'0010', b'0100', b'0100', b'0001',
b'0010', b'1000', b'0001', b'1000', b'0100', b'1000', b'0010',
b'1000', b'0001', b'0010', b'0010', b'0100', b'0001', b'0001',
b'0001', b'0100', b'0001', b'1000', b'0100', b'0010', b'0001',
b'0010', b'0010', b'1000', b'0100', b'0010', b'0100', b'0010',
b'0010', b'0100', b'0100', b'0100', b'1000', b'0010', b'1000',
b'0100', b'0100', b'1000', b'0010', b'1000', b'0001', b'1000',
b'0010', b'1000', b'0010', b'1000', b'1000', b'0001', b'0001',
b'1000', b'0100'], dtype='|S4')
</code></pre>
<p>作为偏好,这些也可以被视为一个长序列:</p>
<pre><code>>>> lookup_1[seq.view(np.int32)].view('S400')
array([b'0010000110001000100000101000001000100001001000100001100010001000100001000100100010001000100010000010000110001000010000011000001000100100100010000001010001001000010001000001010000100010010001000001001010000001100001001000001010000001001000100100000100010001010000011000010000100001001000101000010000100100001000100100010001001000001010000100010010000010100000011000001010000010100010000001000110000100'],
dtype='|S400')
</code></pre>
<p>例二-<code>uint8</code>:</p>
<pre><code>>>> lookup_2[seq.view(np.int32)]
array([2, 1, 8, 8, 8, 2, 8, 2, 2, 1, 2, 2, 1, 8, 8, 8, 8, 4, 4, 8, 8, 8,
8, 8, 2, 1, 8, 8, 4, 1, 8, 2, 2, 4, 8, 8, 1, 4, 4, 8, 4, 4, 1, 4,
2, 2, 4, 4, 1, 2, 8, 1, 8, 4, 8, 2, 8, 1, 2, 2, 4, 1, 1, 1, 4, 1,
8, 4, 2, 1, 2, 2, 8, 4, 2, 4, 2, 2, 4, 4, 4, 8, 2, 8, 4, 4, 8, 2,
8, 1, 8, 2, 8, 2, 8, 8, 1, 1, 8, 4], dtype=uint8)
</code></pre>
<p>示例3-每个字母有四个<code>uint8</code>;但是让我们使用一个不同的<code>seq</code>来处理多行:</p>
<pre><code>>>> seq
array([['CCCT'],
['GCGA']], dtype='<U4')
>>> lookup_3[seq.view(np.int32)].reshape(len(seq), -1)
array([[0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1]], dtype=uint8)
</code></pre>