带有’rows’和index的ismember的Python版本
发布时间:2020-12-20 13:41:30 所属栏目:Python 来源:网络整理
导读:类似的问题已被提出,但没有一个答案完全符合我的需要 – 一些允许多维搜索(在matlab中也称为’rows’选项)但不返回索引.有些返回索引但不允许行.我的阵列非常大(1M x 2)并且我已经成功地制作了一个可行的循环,但显然这非常慢.在matlab中,内置的ismember函数
类似的问题已被提出,但没有一个答案完全符合我的需要 – 一些允许多维搜索(在matlab中也称为’rows’选项)但不返回索引.有些返回索引但不允许行.我的阵列非常大(1M x 2)并且我已经成功地制作了一个可行的循环,但显然这非常慢.在matlab中,内置的ismember函数大约需要10秒.
这是我正在寻找的: a=np.array([[4,6],[2,[5,2]]) b=np.array([[1,7],[1,8],1],4],[4,9],2],1]]) 完成这个技巧的确切matlab函数是: [~,index] = ismember(a,b,'rows') 哪里 index = [6,3,9] 解决方法import numpy as np def asvoid(arr): """ View the array as dtype np.void (bytes) This views the last axis of ND-arrays as bytes so you can perform comparisons on the entire row. https://stackoverflow.com/a/16840350/190597 (Jaime,2013-05) Warning: When using asvoid for comparison,note that float zeros may compare UNEQUALLY >>> asvoid([-0.]) == asvoid([0.]) array([False],dtype=bool) """ arr = np.ascontiguousarray(arr) return arr.view(np.dtype((np.void,arr.dtype.itemsize * arr.shape[-1]))) def in1d_index(a,b): voida,voidb = map(asvoid,(a,b)) return np.where(np.in1d(voidb,voida))[0] a = np.array([[4,2]]) b = np.array([[1,1]]) print(in1d_index(a,b)) 版画 [2 5 8] 这相当于Matlab的[3,6,因为Python使用基于0的索引. 一些警告: >指数按递增顺序返回.他们不对应 尽管存在警告,但为了速度,人们可能会选择使用in1d_index: def ismember_rows(a,b): # https://stackoverflow.com/a/22705773/190597 (ashg) return np.nonzero(np.all(b == a[:,np.newaxis],axis=2))[1] In [41]: a2 = np.tile(a,(2000,1)) In [42]: b2 = np.tile(b,1)) In [46]: %timeit in1d_index(a2,b2) 100 loops,best of 3: 8.49 ms per loop In [47]: %timeit ismember_rows(a2,b2) 1 loops,best of 3: 5.55 s per loop 因此in1d_index快?650倍(对于数千的长数组),但再次注意比较并不完全是苹果对苹果,因为in1d_index按递增顺序返回索引,而ismember_rows返回a的顺序行中的索引.出现在b. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |