获得对角线“条纹"来自 NumPy 或 PyTorch 中的矩阵 [英] Getting diagonal "stripe" from matrix in NumPy or PyTorch

查看:89
本文介绍了获得对角线“条纹"来自 NumPy 或 PyTorch 中的矩阵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要得到对角线的条纹";的矩阵.假设我有一个大小为 KxN (K>N) 的矩阵:

[[ 0 1 2][ 3 4 5][ 6 7 8][ 9 10 11]]

我需要从中提取对角线条纹,在本例中,是通过截断原始条纹创建的矩阵 MxV 大小:

[[ 0 x x][ 3 4 x][×7 8][ x x 11]]

所以结果矩阵为:

[[ 0 4 8][ 3 7 11]]

我可以像这样定义一个 bolean 掩码:

将 numpy 导入为 npX=np.arange(12).reshape(4,3)掩码= np.asarray([[对,错,错],[对,对,错],[假,真,真],[假,假,真]])>>>X数组([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])>>>X.T[mask.T].reshape(3,2).T数组([[ 0, 4, 8],[ 3, 7, 11]])

但我不知道如何为任意 KxN 矩阵(例如 39x9、360x96)自动生成这样的掩码

numpyscipypytorch 中是否有自动执行此操作的函数?


附加问题:是否有可能获得反向条纹"?反而?即

[[ x x 2][×4 5][ 6 7 x][9 x x]]

解决方案

stride_tricks 解决方案:

<预><代码>>>>将 numpy 导入为 np>>>>>>定义条纹(a):... a = np.asanyarray(a)... *sh, i, j = a.shape...断言 i >= j... *st, k, m = a.strides...返回 np.lib.stride_tricks.as_strided(a, (*sh, i-j+1, j), (*st, k, k+m))...>>>a = np.arange(24).reshape(6, 4)>>>一种数组([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11],[12, 13, 14, 15],[16, 17, 18, 19],[20, 21, 22, 23]])>>>条纹(一)数组([[ 0, 5, 10, 15],[ 4, 9, 14, 19],[ 8, 13, 18, 23]])

如果 a 是一个数组,这会创建一个可写的视图,这意味着如果你觉得很喜欢,你可以做类似的事情

<预><代码>>>>条纹(a)[...] *= 10>>>一种数组([[ 0, 1, 2, 3],[ 40, 50, 6, 7],[ 80, 90, 100, 11],[ 12, 130, 140, 150],[ 16, 17, 180, 190],[ 20, 21, 22, 230]])

更新:可以以相同的精神获得左下至右上的条纹.唯一的小问题:它与原始数组的地址不同.

<预><代码>>>>def reverse_stripe(a):... a = np.asanyarray(a)... *sh, i, j = a.shape...断言 i >= j... *st, k, m = a.strides...返回 np.lib.stride_tricks.as_strided(a[..., j-1:, :], (*sh, i-j+1, j), (*st, k, m-k))...>>>a = np.arange(24).reshape(6, 4)>>>反向条纹(一)数组([[12, 9, 6, 3],[16, 13, 10, 7],[20, 17, 14, 11]])

I need to get the diagonal "stripe" of a matrix. Say I have a matrix of size KxN (K>N):

[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]

From it I need to extract a diagonal stripe, in this case, a matrix MxV size that is created by truncating the original one:

[[ 0  x  x]
 [ 3  4  x]
 [ x  7  8]
 [ x  x  11]]

So the result matrix is:

[[ 0  4  8]
 [ 3  7  11]]

I could define a bolean mask like so:

import numpy as np

X=np.arange(12).reshape(4,3)
mask=np.asarray([
  [ True,  False,  False],
  [ True,  True,  False], 
  [ False, True,  True], 
  [ False, False,  True]
])

>>> X
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11]])

>>> X.T[mask.T].reshape(3,2).T
array([[ 0,  4,  8],
       [ 3,  7, 11]])

But I don't see how such a mask could be automatically generated to an arbitrary KxN matrix (e.g. 39x9, 360x96)

Is there a function that does this automatically either in numpy, scipy or pytorch?


Additional question: is it possible to get a "reverse stripe" instead? i.e.

[[ x   x   2]
 [ x   4   5]
 [ 6   7   x]
 [ 9   x   x]]

解决方案

stride_tricks do the trick:

>>> import numpy as np
>>> 
>>> def stripe(a):
...    a = np.asanyarray(a)
...    *sh, i, j = a.shape
...    assert i >= j
...    *st, k, m = a.strides
...    return np.lib.stride_tricks.as_strided(a, (*sh, i-j+1, j), (*st, k, k+m))
... 
>>> a = np.arange(24).reshape(6, 4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23]])
>>> stripe(a)
array([[ 0,  5, 10, 15],
       [ 4,  9, 14, 19],
       [ 8, 13, 18, 23]])

If a is an array this creates a writable view, meaning that if you feel so inclined you can do things like

>>> stripe(a)[...] *= 10
>>> a
array([[  0,   1,   2,   3],
       [ 40,  50,   6,   7],
       [ 80,  90, 100,  11],
       [ 12, 130, 140, 150],
       [ 16,  17, 180, 190],
       [ 20,  21,  22, 230]])

UPDATE: bottom-left to top-right stripes can be obtained in the same spirit. Only minor complication: It is not based at the same address as the original array.

>>> def reverse_stripe(a):
...     a = np.asanyarray(a)
...     *sh, i, j = a.shape
...     assert i >= j
...     *st, k, m = a.strides
...     return np.lib.stride_tricks.as_strided(a[..., j-1:, :], (*sh, i-j+1, j), (*st, k, m-k))
... 
>>> a = np.arange(24).reshape(6, 4)
>>> reverse_stripe(a)
array([[12,  9,  6,  3],
       [16, 13, 10,  7],
       [20, 17, 14, 11]])

这篇关于获得对角线“条纹"来自 NumPy 或 PyTorch 中的矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆