相应地从存储索引的数组更新列表中删除元素

时间:2016-11-30 19:18:55

标签: python arrays numpy

考虑以下形式的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_d中元素的索引。 idx_s中的索引不再a_d指向a中的相同元素,因为np.delete()移动了它们。例如:如果我从4删除索引a的元素,那么4idx_s之后的所有索引现在在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中存在的元素<{1}}中也存在(因此从idx_d中移除,而不存在于a中{1}})其索引也应该被丢弃。

2 个答案:

答案 0 :(得分:2)

您可以使用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 :(得分:1)

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]