一个简单的 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])
有没有更简单的方法?
对于这个简单的一维案例,我实际上会使用一个布尔掩码:
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)。
你可以用布尔掩码很好地做到这一点:
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])
它更像是:
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]
我会用布尔掩码来做这件事,但有点不同。这具有在 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]
此外,如果它们是连续的,请使用 [N:] 语法来选择其余部分。例如, arr[5:] 将选择数组中倒数第 5 个元素。
这是另一种方式,使用 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_id
和False
其他。由于我们想要获取不在其中的索引,因此sel_id
我们使用按位 NOT 运算符~
来反转布尔掩码。
numpy.setdiff1d(a, a[sel_id])
应该做的伎俩。不知道有没有比这更简洁的东西。
假设这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]
这个想法是在你不想要的索引集的互补上使用花哨的索引。