Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:添加包含列元素成对乘积的列的最快方法_Python_Arrays_Numpy_Matrix_Linear Algebra - Fatal编程技术网

Python:添加包含列元素成对乘积的列的最快方法

Python:添加包含列元素成对乘积的列的最快方法,python,arrays,numpy,matrix,linear-algebra,Python,Arrays,Numpy,Matrix,Linear Algebra,假设我有一个numpy数组 X = np.array([[1,2,3], [4,5,6], [7,8,9]]) 我想扩展这个矩阵,将所有可能的列对相乘,在左边添加列。在这个例子中,它将成为 X = np.array([[1, 2, 3, 2, 6], [4,5,6,20,24,30], [7,8,9,56,63,72]]) 其中第四列是X[:,0]和X[:,1]的乘积,第五列是X[

假设我有一个numpy数组

X = np.array([[1,2,3],
              [4,5,6],
              [7,8,9]])
我想扩展这个矩阵,将所有可能的列对相乘,在左边添加列。在这个例子中,它将成为

X = np.array([[1, 2, 3, 2, 6],
              [4,5,6,20,24,30],
              [7,8,9,56,63,72]])
其中第四列是X[:,0]和X[:,1]的乘积,第五列是X[:,0]和X[:,2]的乘积,第六列是X[:,1]和X[:,2]的乘积

我的尝试

我想用np.hstack来做这个。然而,我也知道使用循环会减慢速度,但如果没有循环,我不知道如何正确地完成

for i in range(matrix.shape[1]-1):
    for j in range(matrix.shape[1])[i:]:
        matrix2 = np.hstack((matrix, (matrix[:,i]*matrix[:,j]).reshape(-1,1))).copy()
这样做的问题是速度很慢,而且我必须使用不同的矩阵,否则它将继续添加列。。有更好的主意吗?

方法1

使用np.triu_索引获取成对列索引。使用这些选项选择从输入数组的列索引中获得的两组块。使用这些块执行元素乘法,最后将它们作为新列与输入数组一起堆叠,并使用np.concatenate

因此,实施-

n = X.shape[1]
r,c = np.triu_indices(n,1)
out0 = X[:,r] * X[:,c]
out = np.concatenate(( X, out0), axis=1)
方法2

对于内存效率和性能,特别是对于大型阵列,我们的灵感来自于通过成对组进行循环-

m,n = X.shape
N = n*(n-1)//2
idx = np.concatenate(( [0], np.arange(n-1,0,-1).cumsum() ))+n
start, stop = idx[:-1], idx[1:]
out = np.empty((m,n+N),dtype=X.dtype)
out[:,:n] = X
for j,i in enumerate(range(n-1)):
    out[:, start[j]:stop[j]] = X[:,i,None]*X[:,i+1:]
运行时测试
我有点搞不清楚这是怎么回事好吧,我明白了。谢谢你。triu_Indes是我从未见过的woo-doo魔法,但似乎非常有用。第二种方法只是更高效的内存,对吗?还是速度更快?@Euler_Salter是的,有大量的Col阵列。增加了时间和评论。
In [403]: X = np.random.randint(0,9,(10,100))

In [404]: %timeit app1(X)
     ...: %timeit app2(X)
     ...: 
1000 loops, best of 3: 277 µs per loop
1000 loops, best of 3: 350 µs per loop

In [405]: X = np.random.randint(0,9,(10,1000))

In [406]: %timeit app1(X)
     ...: %timeit app2(X)
     ...: 
10 loops, best of 3: 68.6 ms per loop
100 loops, best of 3: 12.5 ms per loop

In [407]: X = np.random.randint(0,9,(10,2000))

In [408]: %timeit app1(X)
     ...: %timeit app2(X)
     ...: 
1 loop, best of 3: 311 ms per loop
10 loops, best of 3: 44.8 ms per loop