给出一个值数组和一个有效的索引数组,我想获取所有其他索引。
正在寻找一种可实现此目标的pythonic方式,但这是解决方案的示例,还阐明了我要完成的工作:
A = np.array(['a', 'b', 'c', 'd', 'e', 'f', 'g']) # Array of values. Shape: (7,)
B = np.array([0,3,5]) # Array of indices.
# Looking for a more elegant way to do this following line
C = np.array([i for i in range(len(A)) if i not in B]) # Array indices not in B
# Expected Output: C = [1, 2, 4, 6]
编辑:对解决方案进行基准测试
A = np.ones(10000)
B = np.random.random_integers(low=0, high=len(A) - 1, size=8000)
t1 = time()
mask = np.ones(len(A), dtype=bool)
mask[B] = False
C = np.arange(len(A))[mask]
t1 = time() - t1
t2 = time()
C = np.delete(np.arange(A.size), B)
t2 = time() - t2
t3 = time()
C = np.array([i for i in range(len(A)) if i not in B])
t3 = time() - t3
t4 = time()
C = set(np.arange(len(A))).difference(B)
t4 = time() - t4
print("T1: %.5f" % np.round(t1, 5))
print("T2: %.5f" % np.round(t2, 5))
print("T3: %.5f" % np.round(t3, 5))
print("T4: %.5f" % np.round(t4, 5))
结果(当B
中的索引数更改时,值会有所不同,但最快的始终是T1
:
T1: 0.00011
<<<多次运行以上脚本,这始终是最快的。第二种方法总是落后一点。
T2: 0.00017
T3: 0.05746
<<列表理解花费的时间最多。即使删除了np.array。
T4: 0.00158
T2
)只是因为它是一个班轮,并且(与)最快的方法花费的时间几乎相同。答案 0 :(得分:2)
您可以使用np.delete
从可以使用B
创建的其他索引列表中删除np.arange
的项目:
inds = np.delete(np.arange(A.size), B)
演示:
In [53]: A = np.array(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
...: B = np.array([0,3,5])
In [54]: inds = np.delete(np.arange(A.size), B)
In [55]: inds
Out[55]: array([1, 2, 4, 6])
答案 1 :(得分:2)
我不确定这是Pythonic,但更多的是Numpythonic(如果是这样的话)。首先,对数组的查找为O(N)。其次,陷入Python迭代(在您的列表理解中)首先破坏了使用numpy数组的目的。
A = np.array([1,2,3,4,5,6,7])
B = np.array([0,3,5])
mask = np.ones(len(A), dtype=bool)
mask[B] = False
not_in_b = np.arange(len(A))[mask]
修改
一些基准。
In [9]: a = np.ones(1000000)
In [10]: b = np.random.choice(1000000, size=10000, replace=False)
In [11]: def test1(a, b):
...: mask = np.ones(len(a), dtype=bool)
...: mask[b] = False
...: return np.arange(len(a))[mask]
...:
...:
In [12]: %timeit test1(a, b)
4.72 ms ± 15 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [13]: %timeit np.delete(np.arange(a.size), b)
4.72 ms ± 21.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
令人惊讶的是,@ Kasramvd的解决方案虽然比我的要干净得多,但它并不比我的解决方案快。鉴于此结果,如果np.delete
实际上是我实现的相同逻辑的精简包装,我不会感到惊讶。因此,我认为没有理由比@Kasramvd的解决方案更喜欢我的解决方案。