1

假设我有一个值列表

l = [1, 1, 2, 5, 2, 3, 4, 2]

我想用它们的索引提取重复的对/集群,例如,[(0, 1), (2, 4, 7)]. 有没有快速的方法呢?列表的长度可能大于 100000。

更新:我试图构建一个n^2布尔矩阵,但这占用了太多内存。

4

6 回答 6

3

使用defaulldict

from collections import defaultdict

l = [1, 1, 2, 5, 2, 3, 4]
d = defaultdict(list)  # key - number, value - list of indexes

for i, n in enumerate(l):
    d[n].append(i)  # add index to list for this number n

print(d)

输出:

{1: [0, 1], 2: [2, 4], 3: [5], 4: [6], 5: [3]}

这里的复杂度是 O(n)

要仅过滤重复的项目,请使用:

[v for v in d.values() if len(v) > 1]

输出:

[[0, 1], [2, 4]]

于 2019-08-25T20:22:33.560 回答
1

既然你标记pandas

s=pd.DataFrame(enumerate(l))
s[s[1].duplicated(keep=False)].groupby(1)[0].apply(list)
1
1       [0, 1]
2    [2, 4, 7]
Name: 0, dtype: object
于 2019-08-25T20:27:56.493 回答
1

您可以使用numpy.unique后跟列表推导来获取所需的索引集合:

In [29]: l = [1, 1, 2, 5, 2, 3, 4, 2]                                           

In [30]: u, inv, counts = np.unique(l, return_inverse=True, return_counts=True)                  

In [31]: [np.nonzero(inv == k)[0] for k in np.where(counts > 1)[0]]                              
Out[31]: [array([0, 1]), array([2, 4, 7])]

如果 中的值l都是相对较小的整数,这是另一种有效的方法:

In [40]: l = [1, 1, 2, 5, 2, 3, 4, 2]                                                            

In [41]: al = np.array(l)                                                                        

In [42]: [np.nonzero(al == k)[0] for k in np.where(np.bincount(l) > 1)[0]]                       
Out[42]: [array([0, 1]), array([2, 4, 7])]
于 2019-08-25T20:44:00.483 回答
0

我们希望将索引与该列表的序列进行匹配。找到每个匹配项后,将此参数重置为找到的匹配项之后的位置。

代码

list =[1,1,1,3,4,5,5,6,7]

def Duplicate(func,data):
    start = -1
    y = []
    while True:
        try:
            x = func.index(data,start+1)
        except ValueError:
            break
        else:
            y.append(x)
            start = x
    return y

from functools import partial
New= partial(Duplicate, list)

for a in list:
    print(a, New(a))

因此,如果我们想针对同一源对该列表中的各种键进行重复测试,我们可以使用 functools.partial 创建一个新的函数变量,使用“部分完整”的参数列表。

输出:

1 [0, 1, 2]
1 [0, 1, 2]
1 [0, 1, 2]
3 [3]
4 [4]
5 [5, 6]
5 [5, 6]
6 [7]
7 [8]
于 2019-08-25T20:42:34.190 回答
0

您可以使用np.unique,np.flatnonzero并按如下方式列出理解

u_val, dupcount = np.unique(l, return_counts=True)
dups = u_val[dupcount > 1]
out = [tuple(np.flatnonzero(l==item)) for item in dups]

In [98]: out
Out[98]: [(0, 1), (2, 4, 7)]
于 2019-08-25T21:01:50.087 回答
0

您可以使用 groupby:

from itertools import  groupby
from operator import itemgetter

[gr for gr in (tuple(e for e, _ in v) for _, v in groupby(sorted(enumerate(l),key=itemgetter(1)), key=itemgetter(1))) if len(gr) > 1]

输出:

[(0, 1), (2, 4, 7)]
于 2019-08-25T21:07:13.863 回答