Numpy/Python:作为输入矩阵笛卡尔积乘法的有效矩阵
问题: 输入是(i,j)-矩阵M。期望输出是(i^n,j^n)矩阵K,其中n是所取乘积的数量。获取所需输出的详细方法如下Numpy/Python:作为输入矩阵笛卡尔积乘法的有效矩阵,python,arrays,numpy,matrix,Python,Arrays,Numpy,Matrix,问题: 输入是(i,j)-矩阵M。期望输出是(i^n,j^n)矩阵K,其中n是所取乘积的数量。获取所需输出的详细方法如下 生成n行排列I的所有数组(I**n个数组的总数) 生成n列置换J的所有数组(J**n个数组的总数) K[i,j]=m[i[0],j[0]]*…*m[I[n],J[n]]表示范围内的所有n(len(J)) 我所做的最简单的方法是,分别为行和列生成范围(len(np.shape(m)[0])和范围(len(np.shape(m)[1])中的所有n个数字排列的标签列表。之后,你
- 生成n行排列I的所有数组(I**n个数组的总数)
- 生成n列置换J的所有数组(J**n个数组的总数)
- K[i,j]=m[i[0],j[0]]*…*m[I[n],J[n]]表示范围内的所有n(len(J))
import numpy as np
import itertools
m=np.array([[1,2,3],[4,5,6]])
def f(m):
labels_i = [list(p) for p in itertools.product(range(np.shape(m)[0]),repeat=3)]
labels_j = [list(p) for p in itertools.product(range(np.shape(m)[1]),repeat=3)]
out = np.zeros([len(labels_i),len(labels_j)])
for i in range(len(labels_i)):
for j in range(len(labels_j)):
out[i,j] = m[labels_i[i][0],labels_j[j][0]] * m[labels_i[i][1],labels_j[j][1]] * m[labels_i[i][2],labels_j[j][2]]
return out
这应该起作用:
import numpy as np
import itertools
m=np.array([[1,2,3],[4,5,6]])
n=3 # change your n here
def f(m):
labels_i = [list(p) for p in itertools.product(range(np.shape(m)[0]),repeat=n)]
labels_j = [list(p) for p in itertools.product(range(np.shape(m)[1]),repeat=n)]
out = np.zeros([len(labels_i),len(labels_j)])
for i in range(len(labels_i)):
for j in range(len(labels_j)):
out[i,j] = np.prod([m[labels_i[i][k],labels_j[j][k]] for k in range(n)])
return out
这是一种矢量化方法,使用和的组合- 运行时测试和输出验证-
In [167]: # Inputs
...: n = 4
...: A = np.array([[1,2,3],[4,5,6]])
...:
...: def f(m):
...: labels_i = [list(p) for p in product(range(np.shape(m)[0]),repeat=n)]
...: labels_j = [list(p) for p in product(range(np.shape(m)[1]),repeat=n)]
...:
...: out = np.zeros([len(labels_i),len(labels_j)])
...: for i in range(len(labels_i)):
...: for j in range(len(labels_j)):
...: out[i,j] = m[labels_i[i][0],labels_j[j][0]] \
...: * m[labels_i[i][1],labels_j[j][1]] \
...: * m[labels_i[i][2],labels_j[j][2]] \
...: * m[labels_i[i][3],labels_j[j][3]]
...: return out
...:
...: def f_vectorized(A,n):
...: r,c = A.shape
...: arr_i = np.array(list(product(range(r), repeat=n)))
...: arr_j = np.array(list(product(range(c), repeat=n)))
...: return A.ravel()[(arr_i*c)[:,None,:] + arr_j].prod(2)
...:
In [168]: np.allclose(f_vectorized(A,n),f(A))
Out[168]: True
In [169]: %timeit f(A)
100 loops, best of 3: 2.37 ms per loop
In [170]: %timeit f_vectorized(A,n)
1000 loops, best of 3: 202 µs per loop
如果您实现了一个低效的版本,请添加到问题中?很抱歉。完成。因此,对于
n=4
,您需要在那里添加*m[labels_i[i][3],labels_j[j][3]
,对吗?我猜更高的n
也是如此。
In [167]: # Inputs
...: n = 4
...: A = np.array([[1,2,3],[4,5,6]])
...:
...: def f(m):
...: labels_i = [list(p) for p in product(range(np.shape(m)[0]),repeat=n)]
...: labels_j = [list(p) for p in product(range(np.shape(m)[1]),repeat=n)]
...:
...: out = np.zeros([len(labels_i),len(labels_j)])
...: for i in range(len(labels_i)):
...: for j in range(len(labels_j)):
...: out[i,j] = m[labels_i[i][0],labels_j[j][0]] \
...: * m[labels_i[i][1],labels_j[j][1]] \
...: * m[labels_i[i][2],labels_j[j][2]] \
...: * m[labels_i[i][3],labels_j[j][3]]
...: return out
...:
...: def f_vectorized(A,n):
...: r,c = A.shape
...: arr_i = np.array(list(product(range(r), repeat=n)))
...: arr_j = np.array(list(product(range(c), repeat=n)))
...: return A.ravel()[(arr_i*c)[:,None,:] + arr_j].prod(2)
...:
In [168]: np.allclose(f_vectorized(A,n),f(A))
Out[168]: True
In [169]: %timeit f(A)
100 loops, best of 3: 2.37 ms per loop
In [170]: %timeit f_vectorized(A,n)
1000 loops, best of 3: 202 µs per loop