3

假设我有两个 numpy 列表数组:

r = np.array([[1,2,3],[1,2,3],[4,5]])
q= np.array([[1,2,3],[1,2,3]])

numpy.unique习惯将它们修剪成唯一的列表

np.unique(r)
array([[1, 2, 3], [4, 5]], dtype=object)
np.unique(q)
array([1, 2, 3])

您可以看到来自的输出np.unique(q)具有不同的深度。

我的问题是;如何为上述两个示例保持一致的“深度”?

即这样np.unique(q)给出:

array([[1, 2, 3]], dtype=object)
4

1 回答 1

1

这与q构建的方式有关。当你说

q = np.array([[1,2,3],[1,2,3]])

您正在创建一个包含 6 个项目的数组:

In [77]: q.size
Out[77]: 6

当您应用np.unique到这个数组时,这 6 个项目中的每一个都被认为是一个单独的值,并返回唯一的值。

相反,如果您创建一个q只有 2 个项目的 Python 列表:

In [78]: q = np.empty(2, dtype='object')

In [79]: q[:] = [[1,2,3],[1,2,3]]

In [80]: q.size
Out[80]: 2

然后np.unique返回想要的结果:

In [81]: np.unique(q)
Out[81]: array([[1, 2, 3]], dtype=object)

如果您从不同的开始,差异可能会更明显q

In [20]: q = np.array([[1,2,3],[1,2,4]])

In [21]: q2 = np.empty(2, dtype='object')

In [22]: q2[:] = [[1,2,3],[1,2,4]]

In [23]: q
Out[23]: 
array([[1, 2, 3],
       [1, 2, 4]])

In [24]: q2
Out[24]: array([[1, 2, 3], [1, 2, 4]], dtype=object)

这两个数组,q看起来q2很相似,但它们的行为不同。

q是一个形状 (2,3) 的数组,具有 6 个整数值。

q2是一个形状为 (2,) 的数组,其中有 2 个值是 Python 列表。

当您申请np.uniqueq,它会在 6 个整数中找到唯一值。

当您申请np.uniqueq2,它会在 2 个列表中查找唯一值。

In [25]: np.unique(q)
Out[25]: array([1, 2, 3, 4])

In [26]: np.unique(q2)
Out[26]: array([[1, 2, 3], [1, 2, 4]], dtype=object)

您的替代方案实际上只是制作np.unique(q)二维。

In [27]: np.array([np.unique(q).tolist()],dtype='object')
Out[27]: array([[1, 2, 3, 4]], dtype=object)

如果这是您想要做的,那么您可以改用np.atleast_2d

In [28]: np.atleast_2d(np.unique(q))
Out[28]: array([[1, 2, 3, 4]])

如果你希望结果是

array([[1, 2, 3], [1, 2, 4]], dtype=object)

那么您必须构造q为 dtype 的 2 元素数组object。初始化它

q = np.empty(2, dtype='object')

是我知道如何实现这一目标的最简单方法。


如果你发现自己在处理 dtype 的 NumPy 数组object,问问你自己,使用普通的 Python 对象可能不会更好:

In [32]: set(map(tuple, ([[1, 2, 3], [1, 2, 4]])))
Out[32]: {(1, 2, 3), (1, 2, 4)}

In [33]: %timeit set(map(tuple, ([[1, 2, 3], [1, 2, 4]])))
1000000 loops, best of 3: 1.07 µs per loop

In [34]: %timeit np.unique(q2)
100000 loops, best of 3: 13.1 µs per loop
于 2013-10-04T12:07:29.373 回答