Индекс таргетинга на новый список из старого списка - PullRequest
0 голосов
/ 11 февраля 2019

Допустим, у меня есть список, который выглядит следующим образом:

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 список, но теперь, как вы можете видеть, индексы размещаются не так, как раньше, поэтому удаляются неправильные элементы.И то же самое произойдет, если я сделаю это наоборот (т.е. сначала удаляю индексы, а затем использую слайс, чтобы начать с индекса 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 для удаления правильныхиндексы, которые будут соответствовать полному списку?

Ответы [ 3 ]

0 голосов
/ 11 февраля 2019
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)

Попробуйте это простым способом ...

0 голосов
/ 11 февраля 2019

Сначала давайте рассмотрим альтернативы для простого удаления (без этого изменения в вопросе начальной позиции):

Сначала создайте 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:] отсутствуют два значения.(Ну, я мог бы вывести это, сравнив некоторые атрибуты x и y, но не только из 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])
0 голосов
/ 11 февраля 2019

Вы можете изменить список 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...