Python Numpy拆分矩阵,并将块放入对角矩阵中

Python Numpy拆分矩阵,并将块放入对角矩阵中,python,numpy,matrix,split,Python,Numpy,Matrix,Split,早上好,我正在用Python编写一个小项目(我还在学习该语言),我有点卡住了。我有一个numpy阵列,如下所示: x1 0 0 0 0 x1 x1 0 0 0 x1 x1 x1 0 0 x1 x1 x1 x1 0 x1 x1 x1 x1 x1 x1 x1 x1 x1 x1 ... x x x x x y y y y y x2 0 0 0 0 x2 x2 0 0 0 x2 x2 x2 0 0 x2 x2 x2 x2 0 x2 x2 x2 x2 x2 ... 等等。由特定值“y”分隔的每个“部分”

早上好,我正在用Python编写一个小项目(我还在学习该语言),我有点卡住了。我有一个numpy阵列,如下所示:

x1 0 0 0 0
x1 x1 0 0 0
x1 x1 x1 0 0
x1 x1 x1 x1 0
x1 x1 x1 x1 x1
x1 x1 x1 x1 x1
...
x x x x x
y y y y y
x2 0 0 0 0
x2 x2 0 0 0
x2 x2 x2 0 0
x2 x2 x2 x2 0
x2 x2 x2 x2 x2
...
等等。由特定值“y”分隔的每个“部分”比前一个短5行;第一部分当然是最长的一部分。所有的“x”都是浮点数,它们的值我事先不知道,为了清楚起见,我把它们称为“x1”和“x2”。 我的目标是获得一个将所有块并排放置的三角形矩阵,例如:

x1 
x1 x1  
x1 x1 x1 
x1 x1 x1 x1 
x1 x1 x1 x1 x1
x1 x1 x1 x1 x1 x2
x1 x1 x1 x1 x1 x2 x2 
x1 x1 x1 x1 x1 x2 x2 x2
x1 x1 x1 x1 x1 x2 x2 x2 x2
x1 x1 x1 x1 x1 x2 x2 x2 x2 x2
...
x1 x1 x1 x1 x1 x2 x2 x2 x2 x2 x3 x3 x3 x3 x3 x4 x4 x4 x4 x4 ...xN xN xN xN xN
换句话说,我把“x2”块放在块“x1”附近,但下面有5行;我对“x3”和“x2”做同样的处理,直到矩阵结束。 我正在考虑最好的“蟒蛇式”方法 我想到的一个可能是在值“y”出现时拆分数组(np.split),并排放置块,然后手动放下“x2…xN”列。
否则,可以使用一些嵌套for循环将每个元素单独放置在正确的位置来完成任务。
有关于如何进行的建议吗?

提前感谢,并对不够清晰表示歉意。

您只需在数组中循环并存储每个块中的最后一个条目即可。对于下一个块,在前一个最后一个条目前加上前缀

试试这个:

import numpy as np

arr = np.array(
[
[1,0,0,0,0], 
[1,2,0,0,0], 
[1,2,3,0,0], 
[1,2,3,4,0], 
[1,2,3,4,5], 
[-1,-1,-1,-1,-1],
[6,0,0,0, 0], 
[6,7,0,0, 0], 
[6,7,8,0, 0], 
[6,7,8,9, 0], 
[6,7,8,9,10], 
[-1,-1,-1,-1,-1],
])


lst = []
lstprev = []
tmp = []
for r in arr:
   if r[0] == -1:
      lstprev.extend(tmp)
      continue
   tmp = [v for v in r if v != 0]
   lst.append(lstprev + tmp)
   print(lstprev + tmp)
输出

[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[[4.1 0.  0.  0.  0.  0.  0.  0.  0. ]
 [4.1 4.1 0.  0.  0.  0.  0.  0.  0. ]
 [4.1 4.1 4.1 0.  0.  0.  0.  0.  0. ]
 [4.1 4.1 4.1 4.1 0.  0.  0.  0.  0. ]
 [4.1 4.1 4.1 4.1 4.1 0.  0.  0.  0. ]
 [4.1 4.1 4.1 4.1 4.1 3.2 0.  0.  0. ]
 [4.1 4.1 4.1 4.1 4.1 3.2 3.2 0.  0. ]
 [4.1 4.1 4.1 4.1 4.1 3.2 3.2 3.2 0. ]
 [4.1 4.1 4.1 4.1 4.1 3.2 3.2 3.2 3.8]]

您可以使用每个唯一值(
x1,x2,…,xn)创建新数组,并将它们水平堆叠,然后从该堆叠数组中获取下三角矩阵

import numpy as np

def full_stack_tril(arr: np.ndarray, y: int, delta_rows: int):
    _, idx = np.unique(arr[:, 0], return_index=True)
    values = arr[(np.sort(idx), 0)]
    values = np.delete(values, np.where(values==y))
    
    n = arr.shape[0] - values.shape[0] + 1 # number of rows in final array
    result = np.hstack(
        [np.full((n, arr.shape[1] - i * delta_rows), x)
            for i, x in enumerate(values)]
    )
    result = np.tril(result)
    return result

# parameters
y = -1 
delta_rows = 2
# sample with values that should not be sorted
# i.e. the order should be preserved
# each section has delta_rows less rows than the previous one
arr = np.array([
    [4.1, 0.0, 0.0, 0.0, 0.0],
    [4.1, 4.1, 0.0, 0.0, 0.0],
    [4.1, 4.1, 4.1, 0.0, 0.0],
    [4.1, 4.1, 4.1, 4.1, 0.0],
    [4.1, 4.1, 4.1, 4.1, 4.1],
    [y, y, y, y, y],
    [3.2, 0.0, 0.0, 0.0, 0.0],
    [3.2, 3.2, 0.0, 0.0, 0.0],
    [3.2, 3.2, 3.2, 0.0, 0.0],
    [y, y, y, y, y],
    [3.8, 0.0, 0.0, 0.0, 0.0]
])

result = full_stack_tril(arr, y, delta_rows)
输出

[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[[4.1 0.  0.  0.  0.  0.  0.  0.  0. ]
 [4.1 4.1 0.  0.  0.  0.  0.  0.  0. ]
 [4.1 4.1 4.1 0.  0.  0.  0.  0.  0. ]
 [4.1 4.1 4.1 4.1 0.  0.  0.  0.  0. ]
 [4.1 4.1 4.1 4.1 4.1 0.  0.  0.  0. ]
 [4.1 4.1 4.1 4.1 4.1 3.2 0.  0.  0. ]
 [4.1 4.1 4.1 4.1 4.1 3.2 3.2 0.  0. ]
 [4.1 4.1 4.1 4.1 4.1 3.2 3.2 3.2 0. ]
 [4.1 4.1 4.1 4.1 4.1 3.2 3.2 3.2 3.8]]

注意结果是如何用零填充的,因为标准的
ndarray
不支持锯齿形状。

您自己尝试过什么?请分享你的代码。此外,在该示例中是否缺少一行
x1
(即5x
x1
)?或者你是故意从4x
x1
跳到5x
x1
,后面跟着一个
x2
?你是对的,我在示例中犯了一个错误并编辑了它。目前我没有尝试任何东西,我在MATLAB中使用嵌套for循环完成了这项工作,并希望用python“翻译”脚本。我只是在考虑使用numpy的功能来做这件事的最佳方式。因此,这不是一个要求人们免费编写代码的地方——至少希望你自己努力去做,来这里询问你遇到的具体问题。阅读关于
numpy
的基础教程,或一些文档,然后试一试,稍后就问题提问。但我不想要一些代码,我只想作为一名学习者讨论这个过程,然后使用不同的方法编写我自己的代码;如果不清楚,我很抱歉。我期待着一个只使用文字的回复,就像我在结尾所举的两个例子一样。再次抱歉。Grismar是对的,该网站鼓励分享你的代码,但不是作为一名希望你在得到实际答案之前尝试失败的学校老师。。。只是大多数时候,像“我如何实现这个功能?”这样的问题往往过于宽泛,无法在一篇文章中回答。因此,它的最终使命是成为一种编码百科全书,它的政策是让每一篇文章尽可能简单和简洁。