26

一个简单的 numpy 索引示例:

In: a = numpy.arange(10)
In: sel_id = numpy.arange(5)
In: a[sel_id]
Out: array([0,1,2,3,4])

如何返回未由 sel_id 索引的数组的其余部分?我能想到的是:

In: numpy.array([x for x in a if x not in a[id]])
out: array([5,6,7,8,9])

有没有更简单的方法?

4

8 回答 8

18

对于这个简单的一维案例,我实际上会使用一个布尔掩码:

a = numpy.arange(10)
include_index = numpy.arange(4)
include_idx = set(include_index)  #Set is more efficient, but doesn't reorder your elements if that is desireable
mask = numpy.array([(i in include_idx) for i in xrange(len(a))])

现在你可以得到你的价值观:

included = a[mask]  # array([0, 1, 2, 3])
excluded = a[~mask] # array([4, 5, 6, 7, 8, 9])

请注意,a[mask]这不一定会产生与该场景中输出a[include_index]的事项顺序相同include_index的结果(它应该大致相当于a[sorted(include_index)])。但是,由于您的排除项目的顺序没有明确定义,这应该可以正常工作。


编辑

创建蒙版的更好方法是:

mask = np.zeros(a.shape,dtype=bool)
mask[include_idx] = True

(感谢seberg)

于 2012-09-20T18:17:28.363 回答
5

你可以用布尔掩码很好地做到这一点:

a = numpy.arange(10)

mask = np.ones(len(a), dtype=bool) # all elements included/True.
mask[[7,2,8]] = False              # Set unwanted elements to False

print a[mask]
# Gives (removing entries 7, 2 and 8):
[0 1 3 4 5 6 9]

加法(取自@mgilson)。创建的二进制掩码可以很好地用于取回原始切片,但是只有在对原始索引进行排序a[~mask]时才相同。


编辑:向下移动,因为我必须意识到np.delete此时我会考虑越野车(2012 年 9 月)。

您也可以使用np.delete,尽管掩码功能更强大(将来我认为这应该是一个不错的选择)。然而,目前它比上面的要慢,并且会产生带有负索引的意外结果(或给定切片时的步骤)。

print np.delete(a, [7,2,8])
于 2012-09-20T20:33:19.837 回答
4

它更像是:

a = numpy.array([1, 2, 3, 4, 5, 6, 7, 4])
exclude_index = numpy.arange(5)
include_index = numpy.setdiff1d(numpy.arange(len(a)), exclude_index)
a[include_index]
# array([6, 7, 4])

# Notice this is a little different from
numpy.setdiff1d(a, a[exclude_index])
# array([6, 7]
于 2012-09-20T18:07:12.900 回答
1

我会用布尔掩码来做这件事,但有点不同。这具有在 N 维中工作的好处,具有连续或非索引。内存使用情况取决于是否为掩码数组创建了视图或副本,我不确定。

import numpy
a = numpy.arange(10)
sel_id = numpy.arange(5)
mask = numpy.ma.make_mask_none(a.shape)
mask[sel_id] = True
answer = numpy.ma.masked_array(a, mask).compressed()
print answer
# [5 6 7 8 9]
于 2012-09-20T22:24:32.187 回答
0

此外,如果它们是连续的,请使用 [N:] 语法来选择其余部分。例如, arr[5:] 将选择数组中倒数第 5 个元素。

于 2012-09-20T18:17:15.287 回答
0

这是另一种方式,使用 numpy 的isin()函数:

import numpy as np

a = np.arange(10)
sel_id = np.arange(5)

a[~np.isin(np.arange(a.size), sel_id)]

解释:

np.arange(a.size)给出 的所有索引a,即[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

np.isin(np.arange(a.size), sel_id)返回一个布尔掩码[ True, True, True, True, True, False, False, False, False, False],其True索引为 insel_idFalse其他。由于我们想要获取不在其中的索引,因此sel_id我们使用按位 NOT 运算符~来反转布尔掩码。

于 2020-01-06T08:02:52.417 回答
-1

numpy.setdiff1d(a, a[sel_id])应该做的伎俩。不知道有没有比这更简洁的东西。

于 2012-09-20T17:55:30.503 回答
-1

假设这a是一个一维数组,您可以从索引列表中弹出您不想要的项目:

accept = [i for i in range(a.size) if i not in avoid_list]
a[accept]

你也可以尝试使用类似的东西

accept = sorted(set(range(a.size)) - set(indices_to_discard))
a[accept]

这个想法是在你不想要的索引集的互补上使用花哨的索引。

于 2012-09-20T21:21:32.383 回答