Numpy:删除2x2阵列中相邻的重复子阵列?

时间:2014-01-02 21:23:14

标签: python numpy multidimensional-array unique

好吧,我是Numpy的新手,但是我不能把这个拿出来,所以把它交给专家。我有一个像下面那样的2x2表格数组,我想“按顺序统一”数组。序列很重要,如果有多个相同的行数组彼此相邻,那么它们是还原剂并且应该被排除(行数组的序列也很重要,因此[111,222]被认为是不同的[222,111])。以另一种方式构图,我只想保留左或右邻居(或者如下所示的顶部/底部)与自身不同的行阵列(在下面的示例中用*标记)。

[[[492 105]
  [492 105]
  [492 105]*
  [492 106]*
  [492 106]
  [492 106]
  [491 106]*
  [491 106]
  [491 105]*
  [491 105]
  [491 105]
  [492 105]*
  [492 105]
  [492 105]]]

我尝试了numpy.uniquify函数,但是并不关心我有一个2x2数组,而是在平面列表中返回每个子数组中的每个唯一数字,这是我不想要的,它排序并更改了顺序我也不想要的原始阵列。

使用简单的for循环,我可以很容易地写出这个逻辑,但我需要在Numpy速度下进行优化。我最接近的是返回一个trutharray,标记左邻居不同的地方,这似乎有效:

MYARRAY = numpy.matrix(  my2x2array  )
indexes = numpy.arange(len(MYARRAY))
trutharray = numpy.any(MYARRAY[indexes]!=MYARRAY[indexes-1], 1)

然而,我不知道如何继续以及如何处理trutharray。尝试将trutharray提供给numpy.extract函数,但这只返回每个子数组的平面列表,甚至不返回它应该的所有元素;在我的例子中,它返回“[105 492 492 106]”。

有任何帮助吗?如何继续我的示例并最终得到独特的顺序子阵列?或者有没有更快的解决方案来解决这个问题?在这个阶段,Numpy对我来说非常困惑:p

2 个答案:

答案 0 :(得分:1)

我猜是这样的:

>>> a=array( [[492, 105],
...   [492, 105],
...   [492, 105],
...   [492, 106],
...   [492, 106],
...   [492, 106],
...   [491, 106],
...   [491, 106],
...   [491, 105],
...   [491, 105],
...   [491, 105],
...   [492, 105],
...   [492, 105],
...   [492, 105]]
... )
>>> g_idx=any(a[1:]!=a[:-1], axis=1)
>>> vstack((a[:-1][g_idx][0], a[1:][g_idx]))
array([[492, 105],
       [492, 106],
       [491, 106],
       [491, 105],
       [492, 105]])

a[:-1][g_idx][0]是必要的,否则第一个元素就会丢失。

答案 1 :(得分:0)

这可能比上面公布的解决方案略快;它通过预分配来消除不必要的数组创建,并且它在最后一个轴上处理循环,以更快的方式检查所有元素是否与一些voidview voodoo不同。但除非我遗漏了某些东西,否则发布的解决方案应该接近最优,而且相当微不足道;我很难相信这确实是你代码中的瓶颈。

import numpy as np

a = np.array([[492, 105],
  [492, 105],
  [492, 105],
  [492, 106],
  [492, 106],
  [492, 106],
  [491, 106],
  [491, 106],
  [491, 105],
  [491, 105],
  [491, 105],
  [492, 105],
  [492, 105],
  [492, 105]])


def voidview(arr):
    """view the last axis as a void object."""
    return np.ascontiguousarray(arr).view(np.dtype((np.void, arr.dtype.itemsize * arr.shape[-1]))).reshape(arr.shape[:-1])

q = voidview(a)
I = np.empty(len(q), np.bool)
I[:-1] = q[1:]!=q[:-1]
I[-1] = True
print a[I]