假设我有一个值列表
l = [1, 1, 2, 5, 2, 3, 4, 2]
我想用它们的索引提取重复的对/集群,例如,[(0, 1), (2, 4, 7)]. 有没有快速的方法呢?列表的长度可能大于 100000。
更新:我试图构建一个n^2布尔矩阵,但这占用了太多内存。
使用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]]
既然你标记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
您可以使用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])]
我们希望将索引与该列表的序列进行匹配。找到每个匹配项后,将此参数重置为找到的匹配项之后的位置。
代码
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]
您可以使用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)]
您可以使用 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)]