【问题标题】:Splitting a matrix using an array of indices使用索引数组拆分矩阵
【发布时间】:2019-09-05 14:25:06
【问题描述】:

我有一个矩阵,我想一分为二。这两个新的有点纠结在一起,但我确实有一个“开始”和“停止”数组,指示哪些行属于每个新矩阵。

我在下面给出了一个小例子,包括我自己的解决方案,但我觉得不满意。

有没有更聪明的分割矩阵的方法?

请注意,此示例中存在一定的周期性,而在实矩阵中则不然。

import numpy as np

np.random.seed(1)
a = np.random.normal(size=[20,2])
print(a)

b_start = np.array([0, 5, 10, 15])
b_stop = np.array([2, 7, 12, 17])

c_start = np.array([2, 7, 12, 17])
c_stop = np.array([5, 10, 15, 20])

b = a[b_start[0]:b_stop[0], :]
c = a[c_start[0]:c_stop[0], :]

for i in range(1, len(b_start)):
    b = np.append(b, a[b_start[i]:b_stop[i], :], axis=0)
    c = np.append(c, a[c_start[i]:c_stop[i], :], axis=0)

print(b)
print(c)

【问题讨论】:

    标签: python-3.x numpy matrix numpy-ndarray


    【解决方案1】:

    您可以使用 numpy 的精美索引功能。

    index_b = np.array([np.arange(b_start[i], b_stop[i]) for i in range(b_start.size)])
    index_c = np.array([np.arange(c_start[i], c_stop[i]) for i in range(c_start.size)])
    b = a[index_b].reshape(-1, a.shape[1])
    c = a[index_c].reshape(-1, a.shape[1])
    

    这将为您提供相同的输出。

    试运行:

    import numpy as np
    
    np.random.seed(1)
    a = np.random.normal(size=[20,2])
    print(a)
    
    b_start = np.array([0, 5, 10, 15])
    b_stop = np.array([2, 7, 12, 17])
    
    c_start = np.array([2, 7, 12, 17])
    c_stop = np.array([5, 10, 15, 20])
    
    index_b = np.array([np.arange(b_start[i], b_stop[i]) for i in range(b_start.size)])
    index_c = np.array([np.arange(c_start[i], c_stop[i]) for i in range(c_start.size)])
    b = a[index_b].reshape(-1, a.shape[1])
    c = a[index_c].reshape(-1, a.shape[1])
    print(b)
    print(c)
    

    输出:

    [[ 1.62434536 -0.61175641]
     [-0.52817175 -1.07296862]
     [ 1.46210794 -2.06014071]
     [-0.3224172  -0.38405435]
     [-1.10061918  1.14472371]
     [ 0.90159072  0.50249434]
     [-0.69166075 -0.39675353]
     [-0.6871727  -0.84520564]]
    [[ 0.86540763 -2.3015387 ]
     [ 1.74481176 -0.7612069 ]
     [ 0.3190391  -0.24937038]
     [ 1.13376944 -1.09989127]
     [-0.17242821 -0.87785842]
     [ 0.04221375  0.58281521]
     [ 0.90085595 -0.68372786]
     [-0.12289023 -0.93576943]
     [-0.26788808  0.53035547]
     [-0.67124613 -0.0126646 ]
     [-1.11731035  0.2344157 ]
     [ 1.65980218  0.74204416]]
    

    我做了100次两种方法的运行,运行时间是:

    0.008551359176635742#python for loop
    0.0034341812133789062#fancy indexing
    

    10000 次运行:

    0.18994426727294922#python for loop
    0.26583170890808105#fancy indexing
    

    【讨论】:

      【解决方案2】:

      恭喜您正确使用np.append。很多海报都有问题。

      但是在列表中收集值并进行连接会更快。 np.append 每次创建一个全新的数组; list append 只是在原地添加一个指向列表的指针。

      b = []
      c = []
      for i in range(1, len(b_start)):
          b.append(a[b_start[i]:b_stop[i], :])
          c.append(a[c_start[i]:c_stop[i], :])
      b = np.concatenate(b, axis=0)
      c = np.concatenate(c, axis=0)
      

      甚至

      b = np.concatenate([a[i:j,:] for i,j in zip(b_start, b_stop)], axis=0)
      

      另一个答案是

      idx = np.hstack([np.arange(i,j) for i,j in zip(b_start, b_stop)])
      a[idx,:]
      

      根据之前的 SO 问题,我预计这两种方法的速度大致相同。

      【讨论】:

        猜你喜欢
        • 2015-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-10
        • 1970-01-01
        • 2015-05-29
        • 1970-01-01
        • 2019-03-15
        相关资源
        最近更新 更多