【问题标题】:flattening of a numpy array along columns, in the order: lower triangle, diagonal, upper triangle沿列展平numpy数组,顺序为:下三角形,对角线,上三角形
【发布时间】:2019-09-12 04:01:16
【问题描述】:

这是我要解决的一个问题。假设我们有一个方阵:

In [10]: arr
Out[10]: 
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12],
       [13, 14, 15, 16]])

我想要的是按特定顺序展平这个数组:首先我想沿轴 0 展平下三角形,然后选择对角线,最后再次沿轴 0 展平上三角形,最终将展平数组为:

#              | lower triangle     |diag.elements| upper triangle  |  
res = np.array([5, 9, 13, 10, 14, 15, 1, 6, 11, 16, 2, 3, 7, 4, 8, 12])

到目前为止,这是我的部分解决方案,但还没有给出预期的结果。

In [16]: arr[np.tril(arr, k=-1) != 0]
Out[16]: array([ 5,  9, 10, 13, 14, 15])   # not correct!

In [17]: np.diag(arr)
Out[17]: array([ 1,  6, 11, 16])

In [18]: arr[np.triu(arr, k=1) != 0]
Out[18]: array([ 2,  3,  4,  7,  8, 12])  # not correct!

最后,连接这 3 个中间结果。如何正确索引以获得期望的结果?或者,还有其他方法可以解决这个问题吗?

【问题讨论】:

  • 查看np.tri 以了解该组函数如何生成索引。您也许可以简化事情,特别是如果您对不同的 arr 数组重复执行此操作。
  • @hpaulj 您想详细说明一下这个答案吗?我很想看到解决这个问题的替代方法。

标签: python numpy multidimensional-array flatten


【解决方案1】:

这是基于maskingconcatenating/stacking 的一个-

In [50]: r = np.arange(len(arr))

In [51]: mask = r[:,None]<r

In [54]: np.concatenate((arr.T[mask],np.diag(arr),arr.T[mask.T]))
Out[54]: array([ 5,  9, 13, 10, 14, 15,  1,  6, 11, 16,  2,  3,  7,  4,  8, 12])

另一个完全基于masking -

n = len(arr)
r = np.arange(n)
mask = r[:,None]<r
diag_mask = r[:,None]==r
comp_mask = np.vstack((mask[None],diag_mask[None],mask.T[None]))
out = np.broadcast_to(arr.T,(3,n,n))[comp_mask]

【讨论】:

    【解决方案2】:

    使用转置

    lower = np.tril(a, -1).T.ravel()
    diag = np.diag(a)
    upper = np.triu(a, 1).T.ravel()
    
    result = np.concatenate([lower[lower != 0], diag, upper[upper != 0]])
    
    print(result)
    

    输出:

    [ 5  9 13 10 14 15  1  6 11 16  2  3  7  4  8 12]
    

    【讨论】:

      【解决方案3】:

      我正在使用索引来选择(numpy广播)

      ary=ary.T
      
      i,c=ary.shape
      x=np.arange(i)
      y=np.arange(c)
      np.concatenate([ary[x[:,None]<y],ary[x[:,None]==y],ary[x[:,None]>y]])
      Out[1065]: array([ 5,  9, 13, 10, 14, 15,  1,  6, 11, 16,  2,  3,  7,  4,  8, 12])
      

      【讨论】:

      • @kmario23 检查更新,只需要添加 T :-)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多