Сортировать 2 списка, связанных друг с другом - PullRequest
0 голосов
/ 30 сентября 2018

Я застреваю в проблеме и не могу придумать какого-либо эффективного способа сделать это.Проблема заключается в следующем:

Я получил 2 списка, каждый с n до 10^3.

v = [v_1, v_2, ..., v_n]
w = [w_1, w_2, ..., w_n]

В следующем примере n = 3.

v = [60, 100 , 120] 
w = [20, 50, 30]

Мне нужно отсортировать оба списка в порядке убывания следующего уравнения: v_i/w_i

Так что в этом случае я получу:

v_1/w_1 = 3
v_2/w_2 = 2
v_3/w_3 = 4

После этого мне нужноотсортировать оба списка (зависимых друг от друга) по убыванию, и я получил бы следующий результат.

v_new = [120, 60, 100]
w_new = [30, 20, 50]

Я знаю, что есть способ с сортировкой (zip (X, Y), но при этомэто изменило бы мой список в кортеже, и мне нужно это как список. Любые предложения?

Ответы [ 4 ]

0 голосов
/ 30 сентября 2018

В вопросе не упоминается numpy, но я подумал, что добавлю ответ, используя numpy, потому что он действительно хорошо справляется с подобными вещами.У Numpy есть аргумент argsort, который можно использовать для применения порядка любого рода к другим массивам, например:

import numpy as np

v = np.array([60, 100 , 120])
w = np.array([20, 50, 30])

order = np.argsort(v / w)[::-1]
v_new = v[order]
w_new = w[order]

argsort не имеет аргумента reverse, но мы всегда можем просто инвертироватьвывод с использованием [::-1].

0 голосов
/ 30 сентября 2018

Функции сортировки Python могут принимать ключ, вы можете использовать лямбда-функцию для определения ключа, по которому вы хотите отсортировать.В этом случае я бы предложил отсортировать индексы, а затем применить порядок к v и w.Например:

v = [60, 100 , 120] 
w = [20, 50, 30]
order = sorted(range(len(v)), key=lambda i: v[i] / w[i], reverse=True)

v_new = [v[i] for i in order]
w_new = [w[i] for i in order]
0 голосов
/ 30 сентября 2018

Вы можете использовать панд:

import pandas as pd
v = [60, 100, 120]
w = [20, 50, 30]
vv = pd.Series(v)
ww = pd.Series(w)
new_index = list((vv/ww).sort_values(ascending=False).index.values)
v_new = list(vv.reindex(new_index))
w_new = list(ww.reindex(new_index))
print(v_new)
print(w_new)

Вывод:

[120, 60, 100]

[30, 20, 50]

0 голосов
/ 30 сентября 2018

Сортировка на основе условия с использованием key из sorted, который затем дает список кортежей, и мы используем zip, чтобы разделить их на два списка:

v = [60, 100 , 120] 
w = [20, 50, 30]

v, w = map(list, zip(*sorted(zip(v, w), key=lambda x: - x[0] / x[1])))

print(v)  # [120, 60, 100]
print(w)  # [30, 20, 50]

В качестве альтернативы, вы можете использоватьreverse=True в том же коде, как:

v = [60, 100 , 120] 
w = [20, 50, 30]

v, w = map(list, zip(*sorted(zip(v, w), key=lambda x: x[0] / x[1], reverse=True)))

, что также дает желаемое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...