![](/img/trans.png)
[英]numpy: finding all pairs of numbers in a matrix that suffice on neighboring condition
[英]numpy to find products of all combinations of pairs of numbers in a matrix row
我得到了一個 nxm 矩陣,我的目標是找到所有特征的“叉積”,具體來說,乘積矩陣中的每一行都是 x ij jx ij' , j < j', j = 1, . . . , m, j' = (j + 1), . . . , m 使得結果行是該行中所有對組合的乘積。 有沒有一種優雅的方法可以使用 numpy 函數而不是 python 循環來做到這一點?
編輯:例子
[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
output:
array([ 2, 3, 4, 6, 8, 12])
從文檔:
itertools.combinations(iterables,r)
:按排序順序返回長度為 r 的元組,沒有重復元素。
c
中的元素數對應於二項式系數C(n,k)
: n
choose k
,其中n = len([1,2,3,4])
和k = 2
。
注意到itertools.combinations()
只隱藏了 for 循環,但是由於這個問題沒有封閉形式的公式,for 循環是不可避免的。
Numpy 唯一解決方案:
在您的特定情況下,如果您的可迭代對象是n
正整數[1,2,3,4,...,n]
的套裝,那么您會注意到長度為n-1
的上三角二維矩陣的正指數將產生與combinations
相同的結果,因此:
# 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
output:
array([ 2, 3, 4, 6, 8, 12])
或者(在@Nachikel 的幫助下,我不知道np.triu_indices()
的存在)一個班輪:
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()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.