<p>一种可能的方法是<em>在索引中隐藏</em>PersonID,在删除第二部分中的空行并重命名其列后,水平拆分数据帧并垂直将其合并回来。在语法中,它可以是:</p>
<pre><code>tmp = df.set_index('PersonID')
tmp1 = tmp[tmp.columns[:5].to_list()]
tmp2 = tmp[tmp.columns[5:].to_list()]
tmp2 = tmp2[tmp2.count(axis=1) > 0]
tmp2.columns = tmp1.columns
result = pd.concat([tmp1, tmp2]).sort_index().reset_index()
</code></pre>
<p>正如预期的那样:</p>
<pre><code> PersonID Code1 Code2 Code3 Code4 Code5
0 1 a12163 q934581 t7198 q3213 q21357
1 1 h026 q3213 q934581 h026 a12163
2 2 a12453 f54548 k654798 z98798 l1957
3 2 g498 z98798 f54548 g498 a12453
4 3 a19538 g193545 q98798 n2132 s6555
5 4 b98787 q8575 l87987 k576 l4555
6 4 j5757 k576 NaN NaN NaN
7 5 c424533 h734535 m5798 u9513 e8203
8 5 o99995 u9513 h734535 o99995 NaN
</code></pre>
<hr/>
<p>如果需要列数可能不同的通用版本,则只需添加一个循环:</p>
<pre><code>#split after every fith column, whatever the total number of columns
split_at = 5
tmp = df.set_index('PersonID')
tmps = [tmp[tmp.columns[i:i+ split_at].to_list()]
for i in range(0, len(tmp.columns), split_at)]
for i, tmp in enumerate(tmps[1:], 1):
tmp.columns = tmps[0].columns
tmps[i] = tmp[tmp.count(axis=1) > 0]
result = pd.concat(tmps).sort_index().reset_index()
</code></pre>