<p>如果数据不太大,可以使用<code>get_dummies</code>对值进行编码并执行矩阵乘法:</p>
<pre><code>s = pd.get_dummies(df.list_of_value.explode()).sum(level=0)
s.dot(s.T).div(s.sum(1))
</code></pre>
<p>输出:</p>
<pre><code> 0 1 2 3
0 1.000000 0.666667 1.000000 1.000000
1 0.666667 1.000000 0.666667 0.666667
2 1.000000 0.666667 1.000000 1.000000
3 1.000000 0.666667 1.000000 1.000000
</code></pre>
<hr/>
<p><strong>更新</strong>:下面是对代码的简短解释。其主要思想是将给定列表转换为一个热编码列表:</p>
<pre><code> a b c d
0 1 1 1 0
1 0 1 1 1
2 1 1 1 0
3 1 1 1 0
</code></pre>
<p>一旦我们有了它,两行的交集的大小,比如说,<code>0</code>和<code>1</code>就是它们的点积,因为一个字符属于这两行,当且仅当它在这两行中都由<code>1</code>表示</p>
<p>记住这一点,首先使用</p>
<pre><code>df.list_of_value.explode()
</code></pre>
<p>将每个单元格转换为一个系列并连接所有这些系列。输出:</p>
<pre><code>0 a
0 b
0 c
1 d
1 b
1 c
2 a
2 b
2 c
3 a
3 b
3 c
Name: list_of_value, dtype: object
</code></pre>
<p>现在,我们在该系列上使用<code>pd.get_dummies</code>将其转换为一个热编码数据帧:</p>
<pre><code> a b c d
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
1 0 0 0 1
1 0 1 0 0
1 0 0 1 0
2 1 0 0 0
2 0 1 0 0
2 0 0 1 0
3 1 0 0 0
3 0 1 0 0
3 0 0 1 0
</code></pre>
<p>如您所见,每个值都有自己的行。由于我们希望将属于同一原始行的数据合并到一行中,因此我们可以通过原始索引对它们求和。因此</p>
<pre><code>s = pd.get_dummies(df.list_of_value.explode()).sum(level=0)
</code></pre>
<p>给出所需的二进制编码数据帧。下一行</p>
<pre><code>s.dot(s.T).div(s.sum(1))
</code></pre>
<p>正如您的逻辑:<code>s.dot(s.T)</code>按行计算点积,然后<code>.div(s.sum(1))</code>按行除以计数</p>