采取三套共同元素

时间:2015-04-30 02:01:56

标签: python numpy pandas

我有三个numpy数组。

[40  9  0 12 49  1  3  4 18 13 34 47]

[40  0 28 39 29 27 50  9 42 41]

[40  0  9 48 46  1 38 45 15 27 31 36  3 12 16 41 30 33 22 37 28  4  2  6 50
 29 32 49 35  7 11 23 44 42 14 13]

现在我想获得两个或所有集合共有的所有元素。如上所述,前三个对所有三个元素都是通用的,因此将保留这些元素。然后你看,12对于1和第3集是共同的,所以即使它不存在于2集中也应保留。 50对于2组和第3组是共同的,所以即使它在第一组中不存在也应该保留。

所以基本上要么保留任何一对共同的或所有共同的。

我做了类似的事情,但很明显,这将保持与三套不同。

set(list(shortlistvar_rf)) & set(list(shortlistvar_f)) & set(list(shortlistvar_rl))

3 个答案:

答案 0 :(得分:4)

Numpy为您可以使用的1D阵列提供了多个set operations。在编写任何代码之前,请注意您所使用的通用公式:

(a & b) | (b & c) | (c & a)

可以使用boolean algebra缩减为:

(b & (a | c)) | (a & c)

需要4次而不是5次操作。

考虑到这一点,你可以做到:

>>> np.union1d(np.intersect1d(b, np.union1d(a, c)), np.intersect1d(a, c))
array([ 0,  1,  3,  4,  9, 12, 13, 27, 28, 29, 40, 41, 42, 49, 50])

答案 1 :(得分:3)

>>> a = [40,  9,  0, 12 ,49  ,1  ,3  ,4 ,18 ,13 ,34 ,47]
>>> b = [40  ,0 ,28 ,39 ,29 ,27 ,50  ,9 ,42 ,41]
>>> c = [40  ,0  ,9 ,48 ,46  ,1 ,38 ,45 ,15 ,27 ,31 ,36  ,3 ,12 ,16 ,41 ,30 ,33 ,22 ,37 ,28  ,4  ,2  ,6 ,50,29 ,32 ,49 ,35  ,7 ,11 ,23 ,44 ,42 ,14 ,13]
>>> (set(a) & set(b)) | (set(a) & set(c)) | (set(b) & set(c))
{0, 1, 3, 4, 40, 9, 42, 41, 12, 13, 49, 50, 27, 28, 29}

答案 2 :(得分:1)

您可以将这三个输入数组的唯一元素版本连接到一个单独的数组中。然后,排序并找出相同元素的游程长度。对应于大于1的游程长度的元素将是至少在这两个原始输入数组中的元素。

这是实施 -

import numpy as np

# Get unique elements versions of input arrays
unqA = np.unique(A)
unqB = np.unique(B)
unqC = np.unique(C)

# Combine them into one single array and then sort it
comb_sorted = np.sort(np.hstack((unqA,unqB,unqC)))

# Find indices where group changes, where a group means a run of idential elements.
# These identical elements basically represent those common elements between inputs.
idx  = np.where(np.diff(comb_sorted))[0]
grp_change = np.hstack([ [-1],idx,[comb_sorted.size-1] ])+1

# Finally, get the runlengths of each group, detect those runlength > 1 and,
# get the corresponding elements from the combined array
common_ele = comb_sorted[grp_change[np.diff(grp_change)>1]]

基准

本节列出了一些运行时测试,将{3}}中使用unionintersect的numpy数组的方法与其他方法进行了比较。

案例#1:对于已经包含uniqiue元素的输入数组 -

设置输入数组:

A = np.random.randint(0,1000,[1,1000000])
B = np.random.randint(0,1000,[1,1000000])
C = np.random.randint(0,1000,[1,1000000])

A = A.ravel()
B = B.ravel()
C = C.ravel()

_, idx1 = np.unique(A, return_index=True)
A = A[np.sort(idx1)]

_, idx2 = np.unique(B, return_index=True)
B = B[np.sort(idx2)]

_, idx3 = np.unique(C, return_index=True)
C = C[np.sort(idx3)]

运行时:

In [6]: %timeit concat(A,B,C)
10000 loops, best of 3: 136 µs per loop

In [7]: %timeit union_intersect(A,B,C)
1000 loops, best of 3: 315 µs per loop

案例#2:对于可能有重复项的通用输入数组 -

设置输入数组:

A = np.random.randint(0,1000,[1,1000000])
B = np.random.randint(0,1000,[1,1000000])
C = np.random.randint(0,1000,[1,1000000])

A = A.ravel()
B = B.ravel()
C = C.ravel()

运行时:

In [24]: %timeit concat(A,B,C)
10 loops, best of 3: 102 ms per loop

In [25]: %timeit union_intersect(A,B,C)
10 loops, best of 3: 172 ms per loop