Python numpy查找矩阵行中所有数字对组合的乘积
我得到了一个nxm矩阵,我的目标是找到所有特征的“叉积”,特别是乘积矩阵中的每一行都是这样的形式 xijjxij',jPython numpy查找矩阵行中所有数字对组合的乘积,python,numpy,matrix,Python,Numpy,Matrix,我得到了一个nxm矩阵,我的目标是找到所有特征的“叉积”,特别是乘积矩阵中的每一行都是这样的形式 xijjxij',j
[1,2,3,4]
应该成为
[1*2,1*3,1*4,2*3,2*4,3*4]
其中给出:
[2,3,4,6,8,12]
基本上,您希望生成包含原始集合中2个元素的所有可能子集
简短回答:
# With m = 4
c = np.multiply(*np.add(np.triu_indices(4,1),1))
任何输入数组的通用解决方案: 如果使用
itertools
是一个选项,那么您可以使用:
import numpy as np
import itertools
x = list(itertools.combinations([1,2,3,4], 2))
c = np.prod(x,-1)
c
输出:
array([ 2, 3, 4, 6, 8, 12])
array([ 2, 3, 4, 6, 8, 12])
从:
itertools.compositions(iterables,r)
:以
没有重复元素的排序顺序
而c
中的元素数量对应于c(n,k)
:n
选择k
,其中n=len([1,2,3,4])
和k=2
注意,itertools.combinations()
只隐藏for循环,但是由于这个问题没有闭合形式的公式,因此for循环是不可避免的
仅限Numpy的解决方案:
# With m = 4
c = np.multiply(*np.add(np.triu_indices(4,1),1))
在您的特定情况下,如果iterable是一套n
正整数[1,2,3,4,…,n]
,那么您可以注意到长度n-1
的上三角形2D矩阵的正标记将产生与组合相同的结果,因此:
# Number of elements in your array
n = 4
# Upper triangular matrice
x = np.triu(np.ones([n-1,n-1]))
# Get the result
c = np.prod(np.argwhere(x)+np.arange(1,3),-1)
然后再次c
输出:
array([ 2, 3, 4, 6, 8, 12])
array([ 2, 3, 4, 6, 8, 12])
或者(在@Nachikel的帮助下,我不知道是否存在np.triu_index()
)一行:
c = np.multiply(*np.add(np.triu_indices(4,1),1))
基准测试:
还有itertools:
守则:
import numpy as np
import itertools
import timeit
import matplotlib.pyplot as plt
def itertools1(m):
x = list(itertools.combinations(np.arange(1,m+1), 2))
np.prod(x,-1)
def numpy1(m):
n = m-1
x = np.triu(np.ones([n,n]))
np.prod(np.argwhere(x)+np.arange(1,3),-1)
def numpy2(m):
np.multiply(*np.add(np.triu_indices(m,1),1))
def benchmark_time(m):
SETUP_CODE = '''
from __main__ import numpy1
from __main__ import numpy2
from __main__ import itertools1
'''
x = np.zeros([3,len(m)])
for ind, m in enumerate(m):
print('For m = {}'.format(m))
TEST_CODE = '''
itertools1({})
'''.format(m)
# timeit.repeat statement
times = timeit.repeat(setup = SETUP_CODE,
stmt = TEST_CODE,
repeat = 10,
number = 50)
x[0,ind] = np.average(times)
print('Itertools1 give:\t{} s'.format(np.round(np.average(times),3)))
TEST_CODE = '''
numpy1({})
'''.format(m)
times = timeit.repeat(setup = SETUP_CODE,
stmt = TEST_CODE,
repeat = 10,
number = 50)
x[1,ind] = np.average(times)
print('Numpy1 give:\t\t{} s'.format(np.round(np.average(times),3)))
TEST_CODE = '''
numpy2({})
'''.format(m)
times = timeit.repeat(setup = SETUP_CODE,
stmt = TEST_CODE,
repeat = 10,
number = 50)
x[2,ind] = np.average(times)
print('Numpy2 give:\t\t{} s\n'.format(np.round(np.average(times),3)))
return x
m = np.arange(10,150,10)
x = benchmark_time(m)
plt.plot(m,x.T)
plt.legend(('itertools', 'numpy triu', 'numpy triu_indices'))
plt.xlabel('m')
plt.ylabel('sec')
plt.show()
您是否尝试过实现for-loop版本?能否请您使用1)您的数据样本和2)样本的预期输出更新问题?添加了一个示例行输入和输出查看@Mad Physical的答案: