<p>与示例dataframe构造函数相比,所需的输出使用不同的值和列名。我使用您想要的输出数据帧进行测试</p>
<p><strong>逻辑:</strong><br/>
对于<code>links</code>的每个子列表,我们需要找到第一个重叠子列表的行索引(我指的是数据帧的索引,而不是列<code>index</code>)。我们将使用这些行索引在<code>counts95</code>上按<code>.loc</code>切片,以获得列<code>index</code>的相应值。为了实现这一目标,我们需要采取以下几个步骤:</p>
<ul>
<li>将每个子列表与<code>link</code>中的所有子列表进行比较。列表理解是
快速有效地完成这项任务。我们需要编写一份清单
理解如何创建布尔二维掩码数组,其中每个子数组
包含重叠行的<code>True</code>值和非重叠行的<code>False</code>值(请参阅本指南的分步说明)
2D遮罩并检查列<code>links</code>您将看到更清晰的内容)</li>
<li>我们希望从顶部到当前子列表进行比较。即站立
从当前行开始,我们只想向后比较顶部。
因此,我们需要设置与<code>False</code>相比的任何前向。这是
{<cd11>}的功能</li>
<li>在这个2D掩模的每个子阵列中,<code>True</code>的位置/索引是
当前子列表重叠的行的行索引。我们需要找到
这些位置是<code>True</code>。它是<code>np.argmax</code>的功能。
<code>np.argmax</code>返回数组的第一个max元素的位置/索引<code>True</code>被认为是{<cd17>},而{<cd8>}被认为是{<cd19>}。因此
在具有<code>True</code>的任何子数组上,它正确返回第一个重叠行索引。但是,在所有<code>False</code>子数组上,它返回<code>0</code>。稍后我们将使用<code>where</code>处理所有<code>False</code>子阵列</li>
<li>在<code>np.argmax</code>之后,2D掩码被缩减为1D掩码。每个元素
此1D掩码是重叠子列表的行索引数。
将其传递给<code>.loc</code>以获取列<code>index</code>的相应值。
然而,结果也错误地包括了
二维掩码包含所有<code>False</code>。我们希望这些行变成<code>NaN</code>。它是
{<cd30>}的功能</li>
</ul>
<p><strong>方法1</strong>:<br/>
使用列表理解在<code>links</code>的每个列表和<code>links</code>中的所有列表之间构建布尔二维掩码<code>m</code>。我们只需要向后比较,所以使用<code>np.tril</code>将掩码的右上角三角形压碎为表示向前比较的所有<code>False</code>。最后,调用<code>np.argmax</code>以获取<code>m</code>的每一行中第一个<code>True</code>的位置,并链接<code>where</code>以将<code>m</code>的所有<code>False</code>行转换为<code>NaN</code></p>
<pre><code>c95_list = counts95.links.tolist()
m = np.tril([[any(x in l2 for x in l1) for l2 in c95_list] for l1 in c95_list],-1)
counts95['linkoflist'] = (counts95.loc[np.argmax(m, axis=1), 'index']
.where(m.any(1)).to_numpy())
Out[351]:
index level0 links linkoflist
0 616351 25 [1, 2, 3, 4, 5] NaN
1 616352 30 [23, 45, 2] 616351.0
2 616353 35 [1, 19, 67] 616351.0
3 6457754 100 [14, 15, 16] NaN
4 6566666 200 [1, 14] 616351.0
5 6457754 556 [14, 1] 616351.0
</code></pre>
<hr/>
<p><strong>方法2</strong>:<br/>
如果dataframe很大,则将每个子列表仅与<code>links</code>的顶部进行比较会更快。在大数据帧上,它可能比方法1快2倍</p>
<pre><code>c95_list = counts95.links.tolist()
m = [[any(x in l2 for x in l1) for l2 in c95_list[:i]] for i,l1 in enumerate(c95_list)]
counts95['linkoflist'] = counts95.reindex([np.argmax(y) if any(y) else np.nan
for y in m])['index'].to_numpy()
</code></pre>
<hr/>
<p><strong>逐步(方法1)</strong></p>
<pre><code>m = np.tril([[any(x in l2 for x in l1) for l2 in c95_list] for l1 in c95_list],-1)
Out[353]:
array([[False, False, False, False, False, False],
[ True, False, False, False, False, False],
[ True, False, False, False, False, False],
[False, False, False, False, False, False],
[ True, False, True, True, False, False],
[ True, False, True, True, True, False]])
</code></pre>
<p><code>argmax</code>返回所有<code>False</code>行的第一个<code>True</code>和第一个<code>False</code>位置</p>
<pre><code>In [354]: np.argmax(m, axis=1)
Out[354]: array([0, 0, 0, 0, 0, 0], dtype=int64)
</code></pre>
<p>使用<code>argmax</code>的结果进行切片</p>
<pre><code>counts95.loc[np.argmax(m, axis=1), 'index']
Out[355]:
0 616351
0 616351
0 616351
0 616351
0 616351
0 616351
Name: index, dtype: int64
</code></pre>
<p>链<code>where</code>以将所有<code>False</code>对应的行从<code>m</code>转到<code>NaN</code></p>
<pre><code>counts95.loc[np.argmax(m, axis=1), 'index'].where(m.any(1))
Out[356]:
0 NaN
0 616351.0
0 616351.0
0 NaN
0 616351.0
0 616351.0
Name: index, dtype: float64
</code></pre>
<p>最后,输出的索引不同于<code>counts95</code>的索引,因此只需调用<code>to_numpy</code>即可获得要分配给<code>counts95</code>的<code>linkoflist</code>列的数据数组</p>