Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/294.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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 计算nd数组中相同子数组的最快方法? 让我们考虑二维数组a/p>_Python_Arrays_Numpy - Fatal编程技术网

Python 计算nd数组中相同子数组的最快方法? 让我们考虑二维数组a/p>

Python 计算nd数组中相同子数组的最快方法? 让我们考虑二维数组a/p>,python,arrays,numpy,Python,Arrays,Numpy,第一行、第二行和最后一行是相同的。我正在寻找的算法应该返回每个不同行的相同行数(=每个元素的重复数)。如果脚本可以很容易地修改,也可以计算相同列的数量,那就太好了 我使用了一种低效的朴素算法: import numpy A=numpy.array([[2, 3, 5, 7],[2, 3, 5, 7],[1, 7, 1, 4],[5, 8, 6, 0],[2, 3, 5, 7]]) i=0 end = len(A) while i<end: print

第一行、第二行和最后一行是相同的。我正在寻找的算法应该返回每个不同行的相同行数(=每个元素的重复数)。如果脚本可以很容易地修改,也可以计算相同列的数量,那就太好了

我使用了一种低效的朴素算法:

import numpy
A=numpy.array([[2,  3,  5,  7],[2,  3,  5,  7],[1,  7,  1,  4],[5,  8,  6,  0],[2,  3,  5,  7]])
i=0
end = len(A)
while i<end:
    print i,
    j=i+1
    numberID = 1
    while j<end:
        print j
        if numpy.array_equal(A[i,:] ,A[j,:]):
            numberID+=1
        j+=1
    i+=1
print A, len(A)

我的算法看起来像是在numpy中使用本机python,因此效率低下。谢谢您的帮助。

您可以使用
集合
模块中的
计数器
类来完成此操作

它的工作原理如下:

x = [2, 2, 1, 5, 2]
from collections import Counter
c=Counter(x)
print c
输出:计数器({2:3,1:1,5:1})

您将面临的唯一问题是您的情况,因为x的每个值本身就是一个列表,它是一个不可散列的数据结构。 如果您可以转换元组中x的每个值,则它应作为:

x = [(2,  3,  5,  7),(2,  3,  5,  7),(1,  7,  1,  4),(5,  8,  6,  0),(2,  3,  5,  7)]
from collections import Counter
c=Counter(x)
print c

输出:计数器({(2,3,5,7):3,(5,8,6,0):1,(1,7,1,4):1})

您可以对行条目进行lexsort,这将为您提供按排序顺序遍历行的索引,使搜索成为O(n)而不是O(n^2)。请注意,默认情况下,最后一列中的元素最后排序,即行是从右到左而不是从左到右“按字母顺序排列”的

In [9]: a
Out[9]: 
array([[2, 3, 5, 7],
       [2, 3, 5, 7],
       [1, 7, 1, 4],
       [5, 8, 6, 0],
       [2, 3, 5, 7]])

In [10]: lexsort(a.T)
Out[10]: array([3, 2, 0, 1, 4])

In [11]: a[lexsort(a.T)]
Out[11]: 
array([[5, 8, 6, 0],
       [1, 7, 1, 4],
       [2, 3, 5, 7],
       [2, 3, 5, 7],
       [2, 3, 5, 7]])

在unumpy>=1.9.0中,
np.unique
有一个
return\u counts
关键字参数,您可以与解决方案组合以获得计数:

b = np.ascontiguousarray(A).view(np.dtype((np.void, A.dtype.itemsize * A.shape[1])))
unq_a, unq_cnt = np.unique(b, return_counts=True)
unq_a = unq_a.view(A.dtype).reshape(-1, A.shape[1])

>>> unq_a
array([[1, 7, 1, 4],
       [2, 3, 5, 7],
       [5, 8, 6, 0]])

>>> unq_cnt
array([1, 3, 1])
在较旧的numpy中,您可以复制
np.unique
,它看起来像:

a_view = np.array(A, copy=True)
a_view = a_view.view(np.dtype((np.void,
                               a_view.dtype.itemsize*a_view.shape[1]))).ravel()
a_view.sort()
a_flag = np.concatenate(([True], a_view[1:] != a_view[:-1]))
a_unq = A[a_flag]
a_idx = np.concatenate(np.nonzero(a_flag) + ([a_view.size],))
a_cnt = np.diff(a_idx)

>>> a_unq
array([[1, 7, 1, 4],
       [2, 3, 5, 7],
       [5, 8, 6, 0]])

>>> a_cnt
array([1, 3, 1])

谢谢,考虑到一行形式化,真的很难理解算法和逻辑,但我会一直努力理解;-)在应用numpy.unique()之前,你能解释一下你做了什么以及为什么要得到b吗?链接问题的评论中对此进行了解释。基本上,它创建类型为
np.void
的数据视图,并调整整行中的字节数。因此,每一行看起来都是一个单独的项目。好的,一些测试和处理帮助我理解。又是泰,詹姆!计数器对numpy对象不起作用(很遗憾),所以我们需要转换为列表。在我看来,将numpy-nd数组转换为nd-list将非常耗时,但感谢pythonic而非numpic方法。您的建议对子数组进行排序,但不计算它们;-)考虑到Jime不是那么容易回答(如果有人有时间来做更详细的解释),那么像我这样的新手就不应该把这个问题看成是重复的;
b = np.ascontiguousarray(A).view(np.dtype((np.void, A.dtype.itemsize * A.shape[1])))
unq_a, unq_cnt = np.unique(b, return_counts=True)
unq_a = unq_a.view(A.dtype).reshape(-1, A.shape[1])

>>> unq_a
array([[1, 7, 1, 4],
       [2, 3, 5, 7],
       [5, 8, 6, 0]])

>>> unq_cnt
array([1, 3, 1])
a_view = np.array(A, copy=True)
a_view = a_view.view(np.dtype((np.void,
                               a_view.dtype.itemsize*a_view.shape[1]))).ravel()
a_view.sort()
a_flag = np.concatenate(([True], a_view[1:] != a_view[:-1]))
a_unq = A[a_flag]
a_idx = np.concatenate(np.nonzero(a_flag) + ([a_view.size],))
a_cnt = np.diff(a_idx)

>>> a_unq
array([[1, 7, 1, 4],
       [2, 3, 5, 7],
       [5, 8, 6, 0]])

>>> a_cnt
array([1, 3, 1])