<p>让我们试试堆叠和拆散魔法。这也会保留空列表。你知道吗</p>
<pre><code>(df.set_index(['P_ID', 'N_ID'])
.stack()
.str.join(',')
.str.split(',', expand=True)
.stack()
.unstack(-2)
.reset_index(level=[0, 1])
.reset_index(drop=True))
P_ID N_ID Result Gene
0 1 A1 pos kras
1 1 A1 + kras
2 1 A1 pos kras
3 1 A1 positive egfr
4 2 A2 neg brca
5 2 A2 neg brca
6 3 A3
7 4 A4 pos cd133
</code></pre>
<hr/>
<p><strong>细节</strong></p>
<p>首先,将不被触摸的列设置为索引。你知道吗</p>
<pre><code>df.set_index(['P_ID', 'N_ID'])
Result Gene
P_ID N_ID
1 A1 [pos, +, pos, positive] [kras, kras, kras, egfr]
2 A2 [neg, neg] [brca, brca]
3 A3 [] []
4 A4 [pos] [cd133]
</code></pre>
<p>接下来,<code>stack</code>行。你知道吗</p>
<pre><code>_.stack()
P_ID N_ID
1 A1 Result [pos, +, pos, positive]
Gene [kras, kras, kras, egfr]
2 A2 Result [neg, neg]
Gene [brca, brca]
3 A3 Result []
Gene []
4 A4 Result [pos]
Gene [cd133]
dtype: object
</code></pre>
<p>我们现在有一个系列。我们需要把这些元素分解成不同的列。所以,先加入列表,然后再拆分。<strong>假设列表元素本身不包含逗号(如果不包含逗号,请找到另一个分隔符进行连接和拆分)。你知道吗</p>
<pre><code>_.str.join(',').str.split(',', expand=True)
0 1 2 3
P_ID N_ID
1 A1 Result pos + pos positive
Gene kras kras kras egfr
2 A2 Result neg neg None None
Gene brca brca None None
3 A3 Result None None None
Gene None None None
4 A4 Result pos None None None
Gene cd133 None None None
</code></pre>
<p>我们需要去掉空值,所以再次调用<code>stack</code>。你知道吗</p>
<pre><code>_.stack()
P_ID N_ID
1 A1 Result 0 pos
1 +
2 pos
3 positive
Gene 0 kras
1 kras
2 kras
3 egfr
2 A2 Result 0 neg
1 neg
Gene 0 brca
1 brca
3 A3 Result 0
Gene 0
4 A4 Result 0 pos
Gene 0 cd133
dtype: object
</code></pre>
<p>我们快到了。现在我们希望索引的第二个最后一级成为我们的列,因此使用<code>unstack(-2)</code>(<code>unstack</code>在第二个最后一级上取消堆栈)</p>
<pre><code>_.unstack(-2)
Result Gene
P_ID N_ID
1 A1 0 pos kras
1 + kras
2 pos kras
3 positive egfr
2 A2 0 neg brca
1 neg brca
3 A3 0
4 A4 0 pos cd133
</code></pre>
<p>最后,一些管家,以获得我们原来的专栏。你知道吗</p>
<pre><code>_.reset_index(-1, drop=True).reset_index()
P_ID N_ID Result Gene
0 1 A1 pos kras
1 1 A1 + kras
2 1 A1 pos kras
3 1 A1 positive egfr
4 2 A2 neg brca
5 2 A2 neg brca
6 3 A3
7 4 A4 pos cd133
</code></pre>
<p>如果希望空格实际上是列表,请使用<code>applymap</code>:</p>
<pre><code>_.applymap(lambda x: x if x != '' else []))
P_ID N_ID Result Gene
0 1 A1 pos kras
1 1 A1 + kras
2 1 A1 pos kras
3 1 A1 positive egfr
4 2 A2 neg brca
5 2 A2 neg brca
6 3 A3 [] []
7 4 A4 pos cd133
</code></pre>