问题
I have two lists.
a_num = [1, 3, 2, 4]
b_num = [1, 2, 3, 4]
I want to find a permutation matrix to convert a
to b
. Mathematically, a permutation matrix is a square matrix, whose elements are either 1 or 0. It can change the sequence of elements in a vector, by multiplying it.
In this particular example, the permutation matrix is:
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))
Could you please show me how to make that matrix p
? In my real application, there can be tens of elements in the lists with arbitrary sequence. And the two lists always contain str
instead of int
.
And how to make p
when the a
and b
are lists of str
?
a_str = ['c1', 'c2', 's1', 's2']
b_str = ['c1', 's1', 'c2', 's2']
回答1:
In pure Python you can do:
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]]
This assumes that a_str
and b_str
are in fact respective permutations.
回答2:
Edit: works only with numbers.
For arrays with the same length using 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.])
来源:https://stackoverflow.com/questions/53079668/how-to-make-permutation-matrix-for-two-lists-of-str-python3