取下存储索引阵列更新列表元素相应

问题描述:

考虑一个numpy阵列的形式为:取下存储索引阵列更新列表元素相应

> a = np.random.uniform(0., 100., (10, 1000)) 

和索引到数组中的元素,我想跟踪的列表:

> idx_s = [0, 5, 7, 9, 12, 17, 19, 32, 33, 35, 36, 39, 40, 41, 42, 45, 47, 51, 53, 57, 59, 60, 61, 62, 63, 65, 66, 70, 71, 73, 75, 81, 83, 85, 87, 88, 89, 90, 91, 93, 94, 96, 98, 100, 106, 107, 108, 118, 119, 121, 124, 126, 127, 128, 129, 133, 135, 138, 142, 143, 144, 146, 147, 150] 

我也有要素的指标,我需要从a删除列表:

> idx_d = [4, 12, 18, 20, 21, 22, 26, 28, 29, 31, 37, 43, 48, 54, 58, 74, 80, 86, 99, 109, 110, 113, 117, 134, 139, 140, 141, 148, 154, 156, 160, 166, 169, 175, 183, 194, 198, 199, 219, 220, 237, 239, 241, 250] 

我删除与:

> a_d = np.delete(arr, idx_d, axis=1) 

但这个过程会改变元素的索引中a_didx_s中的索引不再指向a_da中的相同元素,因为np.delete()移动了它们。例如:如果我从a中删除索引4的元素,那么在idx_s4之后的所有索引现在在a_d的位置右移1。

    v Index 5 points to 'f' in a 
     0 1 2 3 4 5 6 
a -> a b c d e f g ... # Remove 4th element 'e' from a 
a_d -> a b c d f g h ... # Now index 5 no longer points to 'f' in a_d, but to 'g' 
     0 1 2 3 4 5 6 

如何更新索引的idx_s列表,以便被指向a,同样的元素都指向a_d

在一个元件的情况下,其存在于idx_s也存在idx_d(并因此从a取出,并在a_d不存在的)其指数也应被丢弃。

+0

,而不是删除它们,你能不能批量更新他们都是0或无? –

+0

在中间步骤可能是(如果它有助于实现目标),但在某些时候,我确实需要'a_d'数组,这些元素从'a'中移除,并且正在跟踪我正在跟踪的元素的正确索引。 – Gabriel

+1

一个小的变化:'a = np.random.uniform(0,100,(10,1000))' – hpaulj

你可以使用np.searchsorted获得每个元素的转变在idx_s,然后简单地减去那些从idx_s转向向下值,就像这样 -

idx_s - np.searchsorted(idx_d, idx_s) 

如果idx_d尚未排序,我们需要提供一个分类版本。因此,为了简单起见,假设这些作为数组,我们将有 -

idx_s = idx_s[~np.in1d(idx_s, idx_d)] 
out = idx_s - np.searchsorted(np.sort(idx_d), idx_s) 

样品运行,以帮助获得更好的画面 -

In [530]: idx_s 
Out[530]: array([19, 5, 17, 9, 12, 7, 0]) 

In [531]: idx_d 
Out[531]: array([12, 4, 18]) 

In [532]: idx_s = idx_s[~np.in1d(idx_s, idx_d)] # Remove matching ones 

In [533]: idx_s 
Out[533]: array([19, 5, 17, 9, 7, 0]) 

In [534]: idx_s - np.searchsorted(np.sort(idx_d), idx_s) # Updated idx_s 
Out[534]: array([16, 4, 15, 8, 6, 0]) 
+1

我几乎完成了这个功能,但是这个功能有多酷! :) –

+0

这很好用,但它显然不会从'idx_d'中删除'idx_s'中的元素(即从'a'中删除)。例如:'idx_s = [0,5,7,9,12,17,19]; idx_d = [4,12,18]'returns'[0 4 6 8 11 15 16]'。 '12'元素被删除,所以它不应该出现为'11',它不应该在那里。 – Gabriel

+0

进一步解释:'a'中的'12'元素不会出现在新的'a_d'数组中,所以在这种情况下,它的索引不需要更新,它需要被删除。 – Gabriel

idx_s = [0, 5, 7, 9, 12, 17, 19] 
idx_d = [4, 12, 18] 

def worker(a, v, i=0): 
    if not a: 
     return [] 
    elif not v: 
     return [] 
    elif a[0] == v[0]: 
     return worker(a[1:], v[1:], i+1) 
    elif a[0] < v[0]: 
     return [a[0]-i] + worker(a[1:], v, i) 
    else: 
     return [a[0]-i-1] + worker(a[1:], v[1:], i+1) 

worker(idx_s, idx_d) 
# [0, 5, 6, 8, 15, 16] 
+0

谢谢罗马。你介意我是否编辑你的答案来删除'>>>'和'...'?它使复制/粘贴代码更容易。 – Gabriel

+1

@加布里埃尔肯定会继续 –