好吧,我是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
答案 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]