【问题标题】:Index targeting on new list from old list旧列表中新列表的索引定位
【发布时间】:2023-04-08 15:29:02
【问题描述】:

假设我有一个看起来像这样的列表:

x = [1, 0, 0, 1, 1, 1, 0, 0, 0, 0]

然后我有另一个列表,其中包含需要从列表 x 中删除的索引:

x_remove = [1, 4, 5]

然后我可以使用numpy 命令delete 将其从x 中删除并最终得到:

x_final = np.delete(x, x_remove)
>>> x_final = [0, 0, 1, 0, 0, 0, 0]

到目前为止一切顺利。现在我发现我不想使用整个列表 x,但可能从索引 2 开始。所以基本上:

x_new = x[2:]
>>> x_new = [0, 1, 1, 1, 0, 0, 0, 0]

然而,我仍然需要从x_remove 列表中删除索引,但是现在,正如您所看到的,索引的位置与以前不同,因此删除了错误的项目。如果我反过来(即首先删除索引,然后使用 slice 从索引 2 开始),也会发生同样的事情。所以基本上它会/应该看起来像:

x_new_final = [0, 1, 1, 0, 0]  (first use slice, and the remove list)
x_new_final_v2 = [1, 0, 0, 0, 0]  (first use remove list, and then slice)
x_new_final_correct_one = [0, 1, 0, 0, 0, 0]  (as it should be)

那么有什么方法可以让我从不同的索引开始我的列表(通过切片),并且仍然使用delete 命令删除与完整列表对应的正确索引?

【问题讨论】:

    标签: python list numpy


    【解决方案1】:

    您可以根据切片位置更改 x_remove 列表。例如:

    slice_location = 2
    x = [1, 0, 0, 1, 1, 1, 0, 0, 0, 0]
    x_remove = [1, 4, 5]
    
    x_new=x[slice_location:]
    x_remove = [x-slice_location for x in x_remove if x-slice_location>0]
    x_new = np.delete(x, x_remove)
    

    【讨论】:

      【解决方案2】:
      x = [1, 0, 0, 1, 1, 1, 0, 0, 0, 0]
      x_remove = [1, 4, 5]
      
      for index,value in enumerate(x):
          for remove_index in x_remove:
              if(index == remove_index-1):
                  x[index] = ""
      
      final_list = [final_value for final_value in x if(final_value != "")]
      print(final_list)
      

      试试这个简单的方法...

      【讨论】:

        【解决方案3】:

        首先让我们探索一下简单移除的替代方案(没有这个起始位置问题的变化):

        首先创建一个具有唯一且易于识别的值的x

        In [787]: x = list(range(10))
        In [788]: x
        Out[788]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        

        一种列表理解方法 - 可能不是最快的,但相当清晰且无错误:

        In [789]: [v for i,v in enumerate(x) if i not in x_remove]
        Out[789]: [0, 2, 3, 6, 7, 8, 9]
        

        您的np.delete 方法:

        In [790]: np.delete(x, x_remove)
        Out[790]: array([0, 2, 3, 6, 7, 8, 9])
        

        x 转换为数组有一个缺点,这不是一项简单的任务(时间方面)。它还创建了一个新数组。我的猜测是它更慢。

        尝试就地移除:

        In [791]: y=x[:]
        In [792]: for i in x_remove:
             ...:     del y[i]
             ...:     
        In [793]: y
        Out[793]: [0, 2, 3, 4, 6, 8, 9]
        

        哎呀——错了。我们需要从头开始(最大的索引)。这是一个众所周知的 Python '配方':

        In [794]: y=x[:]
        In [795]: for i in x_remove[::-1]:
             ...:     del y[i]
             ...:     
             ...:     
        In [796]: y
        Out[796]: [0, 2, 3, 6, 7, 8, 9]
        

        在幕后np.delete 采取蒙面方法:

        In [797]: arr = np.array(x)
        In [798]: arr
        Out[798]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
        In [799]: mask = np.ones(arr.shape, bool)
        In [800]: mask[x_remove] = False
        In [801]: mask
        Out[801]: 
        array([ True, False,  True,  True, False, False,  True,  True,  True,
                True])
        In [802]: arr[mask]
        Out[802]: array([0, 2, 3, 6, 7, 8, 9])
        

        现在来解决将x_remove 应用于x 的切片的问题。 x的切片没有切片参数的记录。也就是说,您无法轻易确定 y = x[2:] 缺少两个值。 (嗯,我可以通过比较xy 的一些属性来推断它,但不能仅从y 来推断)。

        所以无论你如何删除,你都必须先调整x_remove的值。

        In [803]: x2 = np.array(x_remove)-2
        In [804]: x2
        Out[804]: array([-1,  2,  3])
        In [805]: [v for i,v in enumerate(x[2:]) if i not in x2]
        Out[805]: [2, 3, 6, 7, 8, 9]
        

        这没问题,但-1 可能是个问题。我们不希望它意味着the last element。所以我们必须首先过滤掉负面指标才能安全。

        In [806]: np.delete(x[2:], x2)
        /usr/local/bin/ipython3:1: FutureWarning: in the future negative indices will not be ignored by `numpy.delete`.
          #!/usr/bin/python3
        Out[806]: array([2, 3, 6, 7, 8, 9])
        

        如果delete 没有忽略负数索引,它可能会得到这样的掩码 - 最后是False

        In [808]: mask = np.ones(arr[2:].shape, bool)
        In [809]: mask[x2] = False
        In [810]: mask
        Out[810]: array([ True,  True, False, False,  True,  True,  True, False])
        

        【讨论】:

          猜你喜欢
          • 2022-01-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-30
          • 1970-01-01
          • 2020-03-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多