Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python NumPy:计算两个数组之间行交叉的大小_Python_Arrays_Numpy_Vectorization - Fatal编程技术网

Python NumPy:计算两个数组之间行交叉的大小

Python NumPy:计算两个数组之间行交叉的大小,python,arrays,numpy,vectorization,Python,Arrays,Numpy,Vectorization,我有两个数组,由小于100的整数填充。一个数字不能连续出现两次 阵列1:nrow=100000;ncol=5 阵列2:nrow=50000;ncol=5 我想创建一个第三个数组(交集),在数组1的每一行和数组2的每一行之间具有相似元素的数量 def Intersection(array1, array2): Intersection = np.empty([ array1.shape[0] , array2.shape[0] ], dtype=int8) for i in

我有两个数组,由小于100的整数填充。一个数字不能连续出现两次

  • 阵列1:nrow=100000;ncol=5
  • 阵列2:nrow=50000;ncol=5
我想创建一个第三个数组(交集),在数组1的每一行和数组2的每一行之间具有相似元素的数量

def Intersection(array1, array2):
    Intersection = np.empty([ array1.shape[0]  , array2.shape[0] ], dtype=int8)
    for i in range(0, array1.shape[0]):
        for j in range(0, array2.shape[0]):
            Intersection[i,j] = len( set(array1[i,]).intersection(array2[j,]) )
    return Intersection
以下是一个例子:

array1 = np.array([[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [7,8,9,10,11] ])
array2 = np.array([[1, 3, 7, 20, 21], [1, 43, 104, 115, 116], [6,30,91,110,121] ])
#Expected result:
array([[2, 1, 0],
       [1, 0, 1],
       [1, 0, 0]], dtype=int8)

这种带有嵌套循环的简单解决方案非常缓慢如何将其矢量化?

对于大小为100000和50000的输入,这里有一种方法需要一秒钟的时间:

import numpy as np
import scipy.sparse

def intersection_counts(x,y):
    # find the size of the input arrays
    n_x, n_d = x.shape
    n_y, n_d = y.shape

    # get a list of the unique values appearing in x and y, as well
    # as a list of inverse indices (see docs for np.unique)
    values, ix = np.unique(np.vstack((x,y)), return_inverse=True)
    n_unique = len(values)

    # reshape the inverse array. ix_x_hat will be an array the same size
    # as x, where ix_x_hat[i,j] gives the index of x[i,j] in values. That
    # is to say, values[ix_x_hat[i,j]] == x[i,j]
    ix_hat = ix.reshape(-1, n_d)
    ix_x_hat = ix_hat[:n_x]
    ix_y_hat = ix_hat[n_x:]

    # create a sparse matrix where entry [i,j] is 1 if and only if
    # row i of x contains values[j]
    x_hat = scipy.sparse.lil_matrix((n_x, n_unique), dtype=int)
    x_hat[np.arange(n_x)[:,None], ix_x_hat] = 1

    # create a sparse matrix where entry [i,j] is 1 if and only if
    # row i of y contains values[j]
    y_hat = scipy.sparse.lil_matrix((len(y), len(values)), dtype=int)
    y_hat[np.arange(n_y)[:,None], ix_y_hat] = 1

    # the dot product gives the solution
    return x_hat.dot(y_hat.T)
这里的想法是:假设
x
y
的每个条目在某个小集合中取一个值,例如,
values=[1,3,6,9,11,15,28,40]
。考虑一行<代码> x<代码>:

x[0] = [11, 6, 40, 1, 3]
#          [1, 3, 6, 9,11,15,28,40]
x_hat[0] = [1, 1, 1, 0, 1, 0, 0, 1]
y_hat[0] = [0, 1, 1, 1, 1, 1, 0, 0]
和一行
y

y[0] = [3, 11, 6, 9, 15]
我们可以将
x[0]
表示为与
值长度相同的稀疏向量。如果
i
th值出现在
x
中,则
i
th条目将为一:

x[0] = [11, 6, 40, 1, 3]
#          [1, 3, 6, 9,11,15,28,40]
x_hat[0] = [1, 1, 1, 0, 1, 0, 0, 1]
y_hat[0] = [0, 1, 1, 1, 1, 1, 0, 0]
x_-hat
y_-hat
的交点处有多少个元素?这只是点积:3。上面的代码就是这样做的,但是是成批的

该函数使用稀疏矩阵,结果是稀疏矩阵,以节省内存。请注意,一个密集的100000 x 50000 INT32阵列已经是20GB,这可能会也可能不会超过您的RAM。有关使用稀疏阵列的帮助,请参见

我通过生成数组
x
y
来测试上述代码:

x = np.random.randint(0,1000,(100000,5))
y = np.random.randint(0,1000,(50000,5))

它在我5岁的机器上用24GB的主内存在2秒钟内完成。这里,
1000
作为
x
y
可以采用的可能值范围。使其更小意味着所涉及的矩阵将更少稀疏,代码将花费更长的时间。

请您发布一个小示例,显示两个更小的数组(例如10x5)以及这种情况下的预期输出?这确实有助于澄清您的要求。通过谷歌搜索“numpy.vectorize”:“提供矢量化功能主要是为了方便,而不是为了性能。实现本质上是一个for循环。”@DSM我不是说这段代码有效,但它是我的。我是python初学者,我只是想把一个想法翻译成python代码。Array1和Array2的条目是什么样子的?它们有界吗?它们是在一组唯一的整数值上吗?@ajcr我编辑了描述,它应该能回答你的问题。是的,就是这样,可能的值是小于100的正整数。这看起来很复杂,但我不理解代码。你能描述一下函数的主要步骤吗?我们能用普通矩阵代替解析矩阵吗?因为我需要知道该值何时等于0。要获得密集矩阵,可以对结果使用
todense()
方法。也就是说,
交叉点计数(x,y).todense()
。但是,请注意,这将导致大量内存使用——很可能大多数值都为零。如果值的范围很小,则行
x[i]
和行
y[j]
具有空交点的可能性很小。然后,所涉及的矩阵不是稀疏的,并且将它们相乘需要更多的时间。事实上,我们希望可能性的范围很大,这样得到的矩阵非常稀疏。我们在这里使用稀疏点积,因为它是矢量化的,而numpy的求交函数只对一维数组进行矢量化。