簡體   English   中英

沿着下三角形numpy數組的每一行翻轉非零值

[英]Flip non-zero values along each row of a lower triangular numpy array

我有一個較低的三角形數組,如B:

B = np.array([[1,0,0,0],[.25,.75,0,0], [.1,.2,.7,0],[.2,.3,.4,.1]])

>>> B
array([[ 1.  ,  0.  ,  0.  ,  0.  ],
       [ 0.25,  0.75,  0.  ,  0.  ],
       [ 0.1 ,  0.2 ,  0.7 ,  0.  ],
       [ 0.2 ,  0.3 ,  0.4 ,  0.1 ]])

我想將它翻轉為:

array([[ 1.  ,  0.  ,  0.  ,  0.  ],
       [ 0.75,  0.25,  0.  ,  0.  ],
       [ 0.7 ,  0.2 ,  0.1 ,  0.  ],
       [ 0.1 ,  0.4 ,  0.3 ,  0.2 ]])

也就是說,我想獲取所有正值,並在正值內反轉,留下尾隨零。 這不是fliplr作用:

>>> np.fliplr(B)
array([[ 0.  ,  0.  ,  0.  ,  1.  ],
       [ 0.  ,  0.  ,  0.75,  0.25],
       [ 0.  ,  0.7 ,  0.2 ,  0.1 ],
       [ 0.1 ,  0.4 ,  0.3 ,  0.2 ]])

有小費嗎? 此外,我正在使用的實際數組將類似於B.shape = (200,20,4,4)而不是(4,4) 每個(4,4)塊看起來像上面的例子(在200個不同的條目中有不同的數字)。

這個怎么樣:

# row, column indices of the lower triangle of B
r, c = np.tril_indices_from(B)

# flip the column indices by subtracting them from r, which is equal to the number
# of nonzero elements in each row minus one
B[r, c] = B[r, r - c]

print(repr(B))
# array([[ 1.  ,  0.  ,  0.  ,  0.  ],
#        [ 0.75,  0.25,  0.  ,  0.  ],
#        [ 0.7 ,  0.2 ,  0.1 ,  0.  ],
#        [ 0.1 ,  0.4 ,  0.3 ,  0.2 ]])

相同的方法將推廣到由多個下三角形子矩陣組成的任意N維數組:

# creates a (200, 20, 4, 4) array consisting of tiled copies of B
B2 = np.tile(B[None, None, ...], (200, 20, 1, 1))

print(repr(B2[100, 10]))
# array([[ 1.  ,  0.  ,  0.  ,  0.  ],
#        [ 0.25,  0.75,  0.  ,  0.  ],
#        [ 0.1 ,  0.2 ,  0.7 ,  0.  ],
#        [ 0.2 ,  0.3 ,  0.4 ,  0.1 ]])

r, c = np.tril_indices_from(B2[0, 0])
B2[:, :, r, c] = B2[:, :, r, r - c]

print(repr(B2[100, 10]))
# array([[ 1.  ,  0.  ,  0.  ,  0.  ],
#        [ 0.75,  0.25,  0.  ,  0.  ],
#        [ 0.7 ,  0.2 ,  0.1 ,  0.  ],
#        [ 0.1 ,  0.4 ,  0.3 ,  0.2 ]])

對於上三角矩陣,您可以簡單地從c減去r ,例如:

r, c = np.triu_indices_from(B.T)
B.T[r, c] = B.T[c - r, c]

這是2D陣列案例的一種方法 -

mask = np.tril(np.ones((4,4),dtype=bool))
out = np.zeros_like(B)
out[mask] = B[:,::-1][mask[:,::-1]]

您可以使用相同的2D蒙版將其擴展為3D陣列大小寫,方法是用它來masking最后兩個軸,如下所示 -

out = np.zeros_like(B)
out[:,mask] = B[:,:,::-1][:,mask[:,::-1]]

..和類似的4D陣列情況,如此 -

out = np.zeros_like(B)
out[:,:,mask] = B[:,:,:,::-1][:,:,mask[:,::-1]]

可以看出,我們將掩蔽過程保持到(4,4)的最后兩個軸,並且解決方案基本保持不變。

樣品運行 -

In [95]: B
Out[95]: 
array([[ 1.  ,  0.  ,  0.  ,  0.  ],
       [ 0.25,  0.75,  0.  ,  0.  ],
       [ 0.1 ,  0.2 ,  0.7 ,  0.  ],
       [ 0.2 ,  0.3 ,  0.4 ,  0.1 ]])

In [96]: mask = np.tril(np.ones((4,4),dtype=bool))
    ...: out = np.zeros_like(B)
    ...: out[mask] = B[:,::-1][mask[:,::-1]]
    ...: 

In [97]: out
Out[97]: 
array([[ 1.  ,  0.  ,  0.  ,  0.  ],
       [ 0.75,  0.25,  0.  ,  0.  ],
       [ 0.7 ,  0.2 ,  0.1 ,  0.  ],
       [ 0.1 ,  0.4 ,  0.3 ,  0.2 ]])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM