Numpy.unique - 获得具有一致深度的输出

时间:2013-10-04 11:51:45

标签: python numpy

假设我有两个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)

1 个答案:

答案 0 :(得分: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)

这两个数组qq2看起来相似,但行为却不同。

q是一个形状(2,3)的数组,其中包含6个整数值。

q2是一个shape(2,)数组,其中包含两个值,即Python列表。

当您将np.unique应用于q时,它会在6个整数中找到唯一值。

当您将np.unique应用于q2时,它会在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 object的2元素数组。用

初始化它
q = np.empty(2, dtype='object')

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


如果你发现自己正在处理dtype object的NumPy数组,那么问问自己,使用纯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