Как сделать матрицу перестановок для двух списков str, Python3

У меня есть два списка.

a_num = [1, 3, 2, 4]
b_num = [1, 2, 3, 4]

Я хочу найти матрицу перестановок для преобразования a в b. Математически матрица перестановок - это квадратная матрица, элементы которой равны 1 или 0. Она может изменять последовательность элементов в векторе, умножая ее. В этом конкретном примере матрица перестановок:

p = [[1,0,0,0],
     [0,0,1,0],
     [0,1,0,0],
     [0,0,0,1]]
# check whether p is correct.
b_num == np.dot(np.array(p), np.array(a_num).reshape(4,1))

Не могли бы вы показать мне, как сделать эту матрицу p? В моем реальном приложении в списках могут быть десятки элементов с произвольной последовательностью. И два списка всегда содержат str вместо int. А как сделать p, когда a и b - это списки str?

a_str = ['c1', 'c2', 's1', 's2']
b_str = ['c1', 's1', 'c2', 's2']
В чем разница между методом "==" и equals()
В чем разница между методом "==" и equals()
Это один из наиболее часто задаваемых вопросов новичкам на собеседовании. Давайте обсудим его на примере.
Замена символа по определенному индексу в JavaScript
Замена символа по определенному индексу в JavaScript
В JavaScript существует несколько способов заменить символ в строке по определенному индексу.
0
0
257
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В чистом Python вы можете:

a_str = ['c1', 'c2', 's1', 's2']
b_str = ['c1', 's1', 'c2', 's2']

from collections import defaultdict

dd = defaultdict(lambda: [0, []])
for i, x in enumerate(b_str):  # collect indexes of target chars
    dd[x][1].append(i)

matrix = [[0]*len(a_str) for x in b_str]

for i, a in enumerate(a_str):
    # set cell at row (src index) and col (next tgt index) to 1
    matrix[i][dd[a][1][dd[a][0]]] = 1  
    # increment index for looking up next tgt index
    dd[a][0] += 1

matrix
# [[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]

Это предполагает, что a_str и b_str на самом деле являются соответствующими перестановками.

Обновлено: работает только с числами.

Для массивов одинаковой длины с использованием NumPy:

import numpy as np

a_num = [1, 3, 2, 4]
b_num = [4, 2, 3, 1]
a = np.array(a_num)
b = np.array(b_num)
len_v = len(a)  # = len(b)

A = np.zeros((len_v, len_v))
A[np.argsort(a), np.arange(len_v)] = 1

B = np.zeros((len_v, len_v))
B[np.argsort(b), np.arange(len_v)] = 1

np.dot(np.linalg.inv(B), np.dot(A, a))  # array([4., 2., 3., 1.])

Другие вопросы по теме