3

我经历了这些线程:

他们都讨论了几种计算具有唯一行和列的矩阵的方法。

然而,这些解决方案看起来有点令人费解,至少在未经训练的人看来是这样。例如,这是第一个线程的最佳解决方案,(如果我错了,请纠正我)我相信这是最安全和最快的:

np.unique(a.view(np.dtype((np.void, a.dtype.itemsize*a.shape[1])))).view(a.dtype).reshape(-1, 
a.shape[1])

无论哪种方式,上述解决方案只返回唯一行的矩阵。我正在寻找的是沿着原始功能的东西np.unique

u, indices = np.unique(a, return_inverse=True)

它不仅返回唯一条目列表,还返回每个项目对找到的每个唯一条目的成员资格,但我该如何为列执行此操作?

这是我正在寻找的示例:

array([[0, 2, 0, 2, 2, 0, 2, 1, 1, 2],
       [0, 1, 0, 1, 1, 1, 2, 2, 2, 2]])

我们会有:

u       = array([0,1,2,3,4])
indices = array([0,1,0,1,1,3,4,4,3])

其中不同的值u表示原始数组中唯一列的集合:

0 -> [0,0]
1 -> [2,1]
2 -> [0,1]
3 -> [2,2]
4 -> [1,2]
4

3 回答 3

3

首先让我们获取唯一索引,为此我们需要从转置数组开始:

>>> a=a.T

使用上述的修改版本来获取唯一索引。

>>> ua, uind = np.unique(np.ascontiguousarray(a).view(np.dtype((np.void,a.dtype.itemsize * a.shape[1]))),return_inverse=True)

>>> uind
array([0, 3, 0, 3, 3, 1, 4, 2, 2, 4])

#Thanks to @Jamie
>>> ua = ua.view(a.dtype).reshape(ua.shape + (-1,))
>>> ua
array([[0, 0],
       [0, 1],
       [1, 2],
       [2, 1],
       [2, 2]])

为了理智:

>>> np.all(a==ua[uind])
True

要重现您的图表:

>>> for x in range(ua.shape[0]):
...     print x,'->',ua[x]
...
0 -> [0 0]
1 -> [0 1]
2 -> [1 2]
3 -> [2 1]
4 -> [2 2]

完全按照您的要求做,但如果必须转换数组会慢一点:

>>> b=np.asfortranarray(a).view(np.dtype((np.void,a.dtype.itemsize * a.shape[0])))
>>> ua,uind=np.unique(b,return_inverse=True)
>>> uind
array([0, 3, 0, 3, 3, 1, 4, 2, 2, 4])
>>> ua.view(a.dtype).reshape(ua.shape+(-1,),order='F')
array([[0, 0, 1, 2, 2],
       [0, 1, 2, 1, 2]])

#To return this in the previous order.
>>> ua.view(a.dtype).reshape(ua.shape + (-1,))
于 2013-08-12T22:35:47.370 回答
2

本质上,您希望 np.unique 返回唯一列的索引以及使用它们的位置的索引?这很容易通过转置矩阵然后使用另一个问题中的代码来完成,并添加return_inverse=True.

at = a.T
b = np.ascontiguousarray(at).view(np.dtype((np.void, at.dtype.itemsize * at.shape[1])))
_, u, indices = np.unique(b, return_index=True, return_inverse=True)

使用您的a,这给出:

In [35]: u
Out[35]: array([0, 5, 7, 1, 6])

In [36]: indices
Out[36]: array([0, 3, 0, 3, 3, 1, 4, 2, 2, 4])

然而,我并不完全清楚你想u成为什么。如果您希望它是唯一的列,那么您可以使用以下内容:

at = a.T
b = np.ascontiguousarray(at).view(np.dtype((np.void, at.dtype.itemsize * at.shape[1])))
_, idx, indices = np.unique(b, return_index=True, return_inverse=True)
u = a[:,idx]

这会给

In [41]: u
Out[41]:
array([[0, 0, 1, 2, 2],
       [0, 1, 2, 1, 2]])

In [42]: indices
Out[42]: array([0, 3, 0, 3, 3, 1, 4, 2, 2, 4])
于 2013-08-12T22:35:59.320 回答
1

不完全确定你在追求什么,但看看numpy_indexed包(免责声明:我是它的作者);肯定会使此类问题变得更容易:

import numpy_indexed as npi
unique_columns = npi.unique(A, axis=1)
# or perhaps this is what you want?
unique_columns, indices = npi.group_by(A.T, np.arange(A.shape[1])))
于 2016-04-02T14:40:24.290 回答