Как изменить индекс элементов в массиве - PullRequest
0 голосов
/ 31 декабря 2018

У меня есть массив:

b = [1,2,3,4,5,6,7,8,9,10,11]

Я хочу изменить индекс элементов в b на основании этого:

ind = [6, 4, 3, 9, 10, 8, 1, 5, 2, 7, 0]

правильно изменено b будет:

modified_b = [11,7,9,3,2,8,1,10,6,4,5]

Вот что я попробовал:

b = [1,2,3,4,5,6,7,8,9,10,11]

ind = [6, 4, 3, 9, 10, 8, 1, 5, 2, 7, 0]

b_modified = []

for j in range(0,len(b)):
   b_modified.insert(ind[j],b[j])
print (b_modified)

Результаты не верны:

[11, 1, 7, 9, 2, 3, 4, 8, 10, 5, 6]

Есть идеи, как это сделать на python?

Ответы [ 4 ]

0 голосов
/ 31 декабря 2018

В общем случае сортировка занимает время O ( n log n ), тогда как время O ( n ) должно быть достаточным.Для решения O ( n ) вы можете использовать цикл for с zip:

b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
ind = [6, 4, 3, 9, 10, 8, 1, 5, 2, 7, 0]

res = [0] * len(b)
for val, idx in zip(b, ind):
    res[idx] = val

# [11, 7, 9, 3, 2, 8, 1, 10, 6, 4, 5]

list.insert здесь не подходит, так как вы не можетеполучить доступ к индексам, которых еще нет в списке.Так как вы заранее знаете размер вашего результата, вы можете просто создать экземпляр списка с таким размером.

Вы также можете использовать стороннюю NumPy , которая поддерживает векторизованную индексацию:

import numpy as np

b = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
ind = np.array([6, 4, 3, 9, 10, 8, 1, 5, 2, 7, 0])

res = np.empty(b.shape)
res[ind] = b

# array([11.,  7.,  9.,  3.,  2.,  8.,  1., 10.,  6.,  4.,  5.])
0 голосов
/ 31 декабря 2018

Вы можете сделать это с помощью встроенной функции sort типа list:

sorted(b, key=lambda x: ind[x-1])

вернет новый список, отсортированный по желанию.

Если вы хотите сделатьсортировка на месте:

b.sort(key=lambda x: ind[x-1])
0 голосов
/ 31 декабря 2018

Вы можете создать новый список на основе сжатого объекта индекса и значений:

>>> [t[1] for t in sorted(zip(ind,b))]
[11, 7, 9, 3, 2, 8, 1, 10, 6, 4, 5]

Или выполнить назначение среза, чтобы изменить b вместо:

>>> b[:]=[t[1] for t in sorted(zip(ind,b))]
>>> b
[11, 7, 9, 3, 2, 8, 1, 10, 6, 4, 5]

Это будет иметь разумную производительность для списков малого и среднего размера O(n log n).Если скорость имеет значение, вы можете заменить соответствующие элементы напрямую, используя enumerate, чтобы получить O(n):

mod_b=[None]*len(b)
for i,x in enumerate(ind):
    mod_b[x]=b[i]

>>> mod_b
[11, 7, 9, 3, 2, 8, 1, 10, 6, 4, 5]
0 голосов
/ 31 декабря 2018

Создайте новый пустой массив и назначьте индексы:

b = [1,2,3,4,5,6,7,8,9,10,11]
ind = [6, 4, 3, 9, 10, 8, 1, 5, 2, 7, 0]

b_modified = [0] * len(b)

for i in range(len(ind)):
    b_modified[ind[i]] = b[i]

print(b_modified)

>>> [11,7,9,3,2,8,1,10,6,4,5]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...