【问题标题】:Numpy conversion of column values in to row values将列值转换为行值的 Numpy
【发布时间】:2016-10-19 10:34:04
【问题描述】:

我取一列(第三个)的 3 个值并将这些值放入 3 个新列的一行中。并将新旧列合并成一个新矩阵A

在 col nr3 中输入时间序列值,在 col nr 1 和 2 中

[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 rows / 3 col。最后一列我想用来填充 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)

【问题讨论】:

    标签: python performance numpy matrix


    【解决方案1】:

    这是一种使用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 在更大的阵列上添加了计时。
    • Tx 这是一个巨大的速度提升!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    • 2019-05-19
    相关资源
    最近更新 更多