将列值转换为行值的Numpy转换

3
我会尽力为您翻译以下it技术相关内容:将一个列(第三列)中的三个值提取出来,放入新的3列中,并将新旧列合并到一个新的矩阵A中。在输入的时间序列中,第1列和第2列的数值对应第3列的数值。
[x x 1]
[x x 2]
[x x 3]

输出:矩阵A

[x x 1 0 0 0]
[x x 2 0 0 0]
[x x 3 1 2 3]
[x x 4 2 3 4]

因篇幅所限,代码首先会生成一个6行/3列的矩阵。我想用最后一列填充3个额外的列,并将其合并成一个新的矩阵A。为了抵消初始位置,这个矩阵A已经预先填充了2行。
以下是我在代码中实现这个思路,但它处理大型数据集时需要很长时间。如何提高此转换的速度。
import  numpy as np

matrix = np.arange(18).reshape((6, 3))

nr=3 
A = np.zeros((nr-1,nr))

for x in range( matrix.shape[0]-nr+1):
    newrow =  (np.transpose( matrix[x:x+nr,2:3] ))
    A = np.vstack([A , newrow])

total= np.column_stack((matrix,A))
print (total)
1个回答

2
这里使用 broadcasting 来获取那些滑动窗口元素,然后只需一些堆叠就可以得到 A
col2 = matrix[:,2]
nrows = col2.size-nr+1
out = np.zeros((nr-1+nrows,nr))
col2_2D = np.take(col2,np.arange(nrows)[:,None] + np.arange(nr))
out[nr-1:] = col2_2D

这里有一种高效的替代方法,使用 NumPy strides 来获取 col2_2D -
n = col2.strides[0]
col2_2D = np.lib.stride_tricks.as_strided(col2, shape=(nrows,nr), strides=(n,n))

最好的方法是初始化一个大小为total的零输出数组,然后使用col2_2D和输入数组matrix分配值到其中。

运行时间测试

函数方法 -

def org_app1(matrix,nr):    
    A = np.zeros((nr-1,nr))
    for x in range( matrix.shape[0]-nr+1):
        newrow =  (np.transpose( matrix[x:x+nr,2:3] ))
        A = np.vstack([A , newrow])
    return A

def vect_app1(matrix,nr):    
    col2 = matrix[:,2]
    nrows = col2.size-nr+1
    out = np.zeros((nr-1+nrows,nr))
    col2_2D = np.take(col2,np.arange(nrows)[:,None] + np.arange(nr))
    out[nr-1:] = col2_2D
    return out

def vect_app2(matrix,nr):    
    col2 = matrix[:,2]
    nrows = col2.size-nr+1
    out = np.zeros((nr-1+nrows,nr))
    n = col2.strides[0]
    col2_2D = np.lib.stride_tricks.as_strided(col2, \
                        shape=(nrows,nr), strides=(n,n))
    out[nr-1:] = col2_2D
    return out

时间和验证 -
In [18]: # Setup input array and params
    ...: matrix = np.arange(1800).reshape((60, 30))
    ...: nr=3
    ...: 

In [19]: np.allclose(org_app1(matrix,nr),vect_app1(matrix,nr))
Out[19]: True

In [20]: np.allclose(org_app1(matrix,nr),vect_app2(matrix,nr))
Out[20]: True

In [21]: %timeit org_app1(matrix,nr)
1000 loops, best of 3: 646 µs per loop

In [22]: %timeit vect_app1(matrix,nr)
10000 loops, best of 3: 20.6 µs per loop

In [23]: %timeit vect_app2(matrix,nr)
10000 loops, best of 3: 21.5 µs per loop

In [28]: # Setup input array and params
    ...: matrix = np.arange(7200).reshape((120, 60))
    ...: nr=30
    ...: 

In [29]: %timeit org_app1(matrix,nr)
1000 loops, best of 3: 1.19 ms per loop

In [30]: %timeit vect_app1(matrix,nr)
10000 loops, best of 3: 45 µs per loop

In [31]: %timeit vect_app2(matrix,nr)
10000 loops, best of 3: 27.2 µs per loop

第一种选择没有时间上的改进。 - Jalo
@Jalo 在一个更大的数组上添加了时间记录。 - Divakar
谢谢,这是速度上的巨大改进! - Leon Berkers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接