【问题标题】:How to compare lists of indices如何比较索引列表
【发布时间】:2016-12-28 05:52:58
【问题描述】:

我有一个 1x1000 的超级数组。

su = np.ones(1000)

还有 3 个列表,索引介于 (1,1000) 之间。

l1=random.sample(range(1, 1000), 320)
l2=random.sample(range(1, 1000), 340)
l3=random.sample(range(1, 1000), 412)

基本上,这些列表表示它们的值为 1 的超数组的索引。

我怎样才能比较这三个列表,甚至不膨胀它们或在超级数组上插值它们。

一个小例子--->

考虑这两个数组a1=[0,1,1,0,0];a2= [1,1,0,0,0],它们都可以表示为a1_=[1,2]; a2_=[0,1],因为它们的值=1。现在很容易将 a1,a1 的表示形式比较为

In [593]:cosine_distances(a1,a2)
Out[594]: array([[ 0.5]])

但是如果以 a1_, a2_ 的形式给出,你会如何比较。这正是我要问的

【问题讨论】:

  • 你想进行什么样的比较?
  • 余弦距离from sklearn.metrics.pairwise import cosine_similarity
  • 在问题中提及这一点
  • 比较列表是什么意思?您能否通过提供示例列表及其比较结果将一些示例纳入您的问题?
  • @vinita 添加了一个特定于cosine_similarity的答案

标签: python arrays numpy compare


【解决方案1】:

我想您正在寻找 l1、l2、l3 中的共同元素?您可以为此使用集合:

s1 = set(l1)
s2 = set(l2)
s3 = set(l3)

然后分别使用s1.intersection(s2)s1.difference(s2) 找到共同/不同的索引。一个简单的长度检查:

assert len(s1) == len(s1.intersection(s2)) + len(s1.difference(s2))

没有输出,因此长度按预期正确相加。

【讨论】:

  • 考虑这两个数组a1=[0,1,1,0,0];a2= [1,1,0,0,0] 它们都可以表示为a1_=[1,2]; a2_=[0,1],因为它们的值=1。现在很容易比较 a1,a1 的表示,但是如果以 a1_, a2_ 的形式给出,你将如何比较。这正是我要问的
【解决方案2】:

应该很容易比较这两个向量之间的余弦相似度。对于余弦相似度,您需要每个向量的模以及两个向量的点积。

由于向量仅由 1 和 0 组成,因此取模很简单,向量中 1 的数量,平方根。

l1_mod = math.sqrt(len(l1))
l2_mod = math.sqrt(len(l2))

现在点积比较棘手,您需要找出两个向量之间共有元素的数量。您应该使用np.intersect1d,因为您正在处理一维数组。

dot = len(np.intersect1d(l1, l2))
simililarity = dot / (l1_mod*l2_mod)

不用说,把它封装成一个函数!

【讨论】:

    【解决方案3】:

    密集阵列解决方案

    a_ 形式转换为a 形式很容易,其功能如下:

    def foo(a_, n):
        a = np.zeros(n,int)
        a[a_] = 1
        return a
    
    In [1565]: foo([1,2],5)
    Out[1565]: array([0, 1, 1, 0, 0])
    In [1566]: foo([0,1],5)
    Out[1566]: array([1, 1, 0, 0, 0])
    

    使用简单列表,该函数给出所需的值,但带有警告。

    In [1572]: a1=[0,1,1,0,0];a2= [1,1,0,0,0]
    In [1573]: pairwise.cosine_distances(a1,a2)
    /usr/lib/python3/dist-packages/sklearn/utils/validation.py:386: DeprecationWarning: Passing 1d arrays as data is deprecated in 0.17 and willraise ValueError in 0.19. Reshape your data either using X.reshape(-1, 1) if your data has a single feature or X.reshape(1, -1) if it contains a single sample.
    Out[1573]: array([[ 0.5]])
    

    所以我需要修改我的foo,所以它也创建了 (1,5) 数组:

    def foo(a_, n):
       a = np.zeros((1,n),int)
       a[:,a_] = 1
       return a
    
    In [1575]: pairwise.cosine_distances(foo([1,2],5),foo([0,1],5))
    Out[1575]: array([[ 0.5]])
    

    稀疏矩阵解

    cosine_distance 接受稀疏矩阵输入。

    制作稀疏矩阵的最简单方法是只使用密集数组,甚至是a1 列表

    In [1580]: from scipy import sparse
    In [1592]: sparse.csr_matrix(a1)
    Out[1592]: 
    <1x5 sparse matrix of type '<class 'numpy.int32'>'
        with 2 stored elements in Compressed Sparse Row format>
    
    In [1593]: sparse.csr_matrix(a1).A    # view it as a dense array
    Out[1593]: array([[0, 1, 1, 0, 0]], dtype=int32)
    
    In [1594]: pairwise.cosine_distances( sparse.csr_matrix(a1), sparse.csr_matrix(a2))
    Out[1594]: array([[ 0.5]])
    

    所以作为一个中间步骤我可以做:

    In [1581]: sparse.csr_matrix(foo([1,2],5))
    Out[1581]: 
    <1x5 sparse matrix of type '<class 'numpy.int32'>'
        with 2 stored elements in Compressed Sparse Row format>
    

    下一步是直接从a_ 格式制作稀疏矩阵。这需要更多关于稀疏矩阵的知识。

    使用稀疏的coo 输入样式:

    In [1601]: sparse.csr_matrix(([1,1],([0,0],[1,2])), shape=(1,5)).A
    Out[1601]: array([[0, 1, 1, 0, 0]], dtype=int32)
    
    def mkcsr(a_, n):
        col = np.array(a_)
        row = np.zeros_like(col)
        data = np.ones_like(col)
        return sparse.csr_matrix((data, (row, col)), shape=(1,n))
    
    In [1611]: mkcsr([1,2],5).A
    Out[1611]: array([[0, 1, 1, 0, 0]], dtype=int32)
    
    In [1614]: pairwise.cosine_distances(mkcsr([1,2],5), mkcsr([0,1],5))
    Out[1614]: array([[ 0.5]])
    

    【讨论】:

    • OP 不想将数组转换成它们的真实形式
    • 我添加了一个稀疏矩阵解决方案。
    猜你喜欢
    • 2022-01-03
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 2012-07-10
    • 1970-01-01
    相关资源
    最近更新 更多