假设我有一个值列表
l = [1, 1, 2, 5, 2, 3, 4, 2]
我想提取重复的对/簇及其索引,例如[(0, 1), (2, 4, 7)]
。有快速的方法吗?列表的长度可以是> 100000。
更新:我试图构造一个n^2
布尔矩阵,但是占用了太多内存。
答案 0 :(得分:3)
使用192.168.0.50
conf=/path/to/company/app/server001
-----
192.168.0.50
conf=/path/to/company/app/server005
-----
192.168.0.100
conf=/path/to/company/app/cluster
-----
192.168.0.150
conf=/path/to/company/app/server006
-----
:
defaulldict
输出:
{1:[0,1],2:[2,4],3:[5],4:[6],5:[3]}
这里的复杂度为O(n)
要仅过滤重复项,请使用:
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)
输出:
[[0,1],[2,4]]
答案 1 :(得分: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
答案 2 :(得分: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])]
答案 3 :(得分: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]
答案 4 :(得分: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)]
答案 5 :(得分: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)]