如果子阵列中的元素在其他子阵列中按位置重复,则过滤numpy数组

时间:2017-08-23 16:17:24

标签: python arrays numpy

不幸的是,它非常类似于:Filter a numpy array if any list within it contains at least one value of a previous row这是我几分钟前提出的一个问题。

在这种情况下,我有一个列表

let volumeView = MPVolumeView(frame: CGRect.init(x: self.view.frame.maxX, y: self.view.frame.maxY, width: 0, height: 0))
volumeView.clipsToBounds = true
volumeView.showsRouteButton = false
self.view.addSubview(volumeView)

我现在要做的是略有不同。

我想从列表的开头和每个b = np.array([[1,2], [1,8], [2,3], [4,2], [5,6], [7,8], [3,3], [10,1]]) 开始。我想检查位置i中的元素(相对于subarray)是否在其他subarray中遇到位置i 。因此,删除所有这些元素。

例如:

  • 查看subarrays:消除[1,2]因为1位于位置0,消除[1,8]因为2位于位置1.但是不要消除[4,2]或{{1因为1和2处于不同的位置。
  • 查看[10,1],消除[2,3],因为3位于第1位。
  • 看看[2,3]什么都不能消除。
  • 查看[3,3]无需消除

结果将是[5,6],

我的尝试 正如你在我之前的帖子中看到的,我尝试了不同的东西。现在,我注意到[7,8],提供了一个有用的数组,可用于过滤,但我不能完全决定如何将它们放在一起。

2 个答案:

答案 0 :(得分:2)

编辑:

我的初始解决方案并不能始终如一地产生您正在寻找的结果,例如在底部。

所以这是一个替代解决方案,它实际上在必要时迭代行:

ar = b.copy()
new_rows = []
while ar.shape[0]:
    new_rows.append(ar[0])
    ar = ar[(ar != ar[0]).all(axis=1)]
np.stack(new_rows)
Out[463]:
array([[ 1,  2],
       [ 2,  3],
       [ 5,  6],
       [ 7,  8],
       [10,  1]])

原始答案:

您可以将np.unique与参数return_index=True一起使用,以标识第一个包含给定列中值的行。然后,您可以按顺序选择这些行,并对下一列执行相同的操作。

ar = b.copy()
num_cols = ar.shape[1]
for col in range(num_cols):
    ar = ar[np.sort(np.unique(ar[:, col], return_index=True)[1])]
ar
Out[30]: 
array([[ 1,  2],
       [ 2,  3],
       [ 5,  6],
       [ 7,  8],
       [10,  1]])

原始失败的情况:

考虑ar = b[:, ::-1],列的顺序相反。

然后,

num_cols = ar.shape[1]
    for col in range(num_cols):
        ar = ar[np.sort(np.unique(ar[:, col], return_index=True)[1])]

给予

ar
Out[426]: 
array([[ 2,  1],
       [ 3,  2],
       [ 6,  5],
       [1,  10]])

错过了所需的[8, 7]行。

答案 1 :(得分:1)

您的问题和示例需要一些澄清(为什么[10, 1]不是最终答案的一部分?如果一个子阵列被淘汰,这是否意味着它无助于消除任何进一步的子阵列?),但这里是一个第一枪。它不是非常pythonic(或pythonic),但它需要的只是一个通过较大阵列的循环,一个地图跟踪你看到的数字,每个数字的集合,以跟踪它出现的指数。

final_arr = []
found_nums = {}
for subarray in array:
    found = False
    for i in xrange(len(subarray)):
        num = subarray[i]
        if num in found_nums:
            if i in found_nums[num]:
                found = True
                break
            else:
                found_nums[num].add(i)
        else:
            found_nums[num] = set([i])
    if not found:
        final_arr.append(subarray)