访问包含列表或数组数组的1D数组

时间:2015-02-21 14:57:48

标签: python arrays numpy

我有一维标签数组。索引i的对象具有标签标签[i]。我还有一个数组或列表数组,其中我有我想要访问的标签索引。 例如:

labels = np.array([2, 0, 3, 3, 0, 0, 0, 0, 0, 0])
duplicates = np.array(np.array([0,3]), np.array([3,0]), np.array([6,7,8]))

我想访问标签元素,因此输出看起来像这样:

labels_duplicates = np.array(np.array([2,3]), np.array([3,2]), np.array([0,0,0]))

实现这一目标的最佳方法是什么(最好没有for循环)?

我想要实现的目标:我有一系列中心索引(重复)。我必须检查这些中心的标签是否匹配。如果他们这样做,中心将合并为一个中心。如果有比上面更好的解决方案,我很高兴听到它。

1 个答案:

答案 0 :(得分:1)

首先让我们专注于做(不要担心'循环'):

In [82]: duplicates = [np.array([0,3]), np.array([3,0]), np.array([6,7,8])]

In [83]: [labels[x] for x in duplicates]
Out[83]: [array([2, 3]), array([3, 2]), array([0, 0, 0])]

我将duplicates列为一个列表,而不是数组。 dtype对象的1d数组仅仅是一个列表。 (但要么在这里工作)

np.concatenate(duplicates)解决方案移至结束)

只要您的duplicates元素的长度不同,就没有一种方法(我能想到)可以避免“循环”,迭代这些元素。这只是numpy索引的本质。 2d操作本质上是“矩形”。如果有一个直接执行它的函数,它可能隐藏了一个循环。


如果只有少数duplicates更长,并且您不介意失去额外的'值,你可以剪辑它们:

labels[np.array([x[:2] for x in duplicates])]

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

同样,您可以将每个duplicate扩展为相同的长度。这是一个通用np.pad功能,但它可能提供比您需要的更多选项。

对于填充,目标长度需要理解,作为填充本​​身。 np.pad可用于复制最后一个值。另一种选择是默认或虚拟索引(例如0)。

mlen = max([len(x) for x in duplicates])
padded_dups = [np.pad(x,(0,mlen-len(x)),'edge') for x in duplicates]
labels[np.array(padded_dup)]

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

duplicates应该是列表还是对象数组?可能并不重要。

[labels[x] for x in np.array(duplicates)]

的工作原理。如您所知,np.array(duplicates)-1有效,而列表需要[x-1 for x in duplicates]

在初步时间中,两次减法大约需要相同的时间,这意味着对象数组减法执行相当于列表理解。

像这样的数组有时像列表一样,在其他情况下就像2d数组。这是一个发展领域,所以你必须逐个尝试。

array([array([0, 3]), array([3, 0]), array([6, 7, 8])], dtype=object)

之前我展示过您可以轻松获得标签的平面列表:

flat_labels = labels[np.concatenate(duplicates)]
# array([2, 3, 3, 2, 0, 0, 0])

我刚刚意识到np.split很容易将这样的数组拆分成你想要的子数组:

split_indices = np.cumsum([len(x) for x in duplicates])[:-1]
np.split(flat_labels,split_indices)

# [array([2, 3]), array([3, 2]), array([0, 0, 0])]