python - python 中的矩阵矩阵

标签 python python-2.7 numpy matrix

嘿,我正在研究这段代码以进行 Material 分析。我为 Material 的每一层生成了一个矩阵,我想将每个矩阵保存为自己的元素。我这样做的方法是将其保存到字典中。然后,我通过对字典的所有值求和来形成一个矩阵。现在,我针对三种不同的条件执行此操作,得到 3 个矩阵:A、B 和 D。我想创建所有这些矩阵,使其看起来像这样:

    | A B |
    | B D |

However I can't get it to print properly as it always says matrix: then one of the matrices such as A. It prints the second matrix, B, on the third line where A ended instead of being next to A. I also need to perform future operations on this massive matrix so I'm wondering what the best way to go about that would be. This is a part of my code:

    Qbars = {}
    for i in plies:

    Qbar11 = Q11 * math.cos(float(thetas[j]))**4 + Q22        *math.sin(float(thetas[j]))**4 + \
        2 * (Q12 + 2 * Q66) * math.sin(float(thetas[j]))**2 * math.cos(float(thetas[j]))**2
        Qbar22 = Q11 * math.sin(float(thetas[j]))**4 + Q22 *math.cos(float(thetas[j]))**4 + \
        2 * (Q12 + 2 * Q66) * math.sin(float(thetas[j]))**2 * math.cos(float(thetas[j]))**2
        Qbar12 = (Q11 + Q22 - 4 * Q66) * math.sin(float(thetas[j]))**2 * \
        math.cos(float(thetas[j]))**2 + Q12 * (math.cos(float(thetas[j]))**4 + \
        math.sin(float(thetas[j]))**4)
        Qbar66 = (Q11 + Q22 - 2 * Q12 - 2 * Q66) * math.sin(float(thetas[j]))**2 * \
        math.cos(float(thetas[j])) **2 + Q66 * (math.sin(float(thetas[j]))**4 + \
        math.cos(float(thetas[j]))**4)
        Qbar16 = (Q11 - Q12 - 2 * Q66) * math.cos(float(thetas[j]))**3 * \
        math.sin(float(thetas[j])) - (Q22 - Q12 - 2 * Q66) * math.cos(float(thetas[j])) * \
        math.sin(float(thetas[j]))**3
        Qbar26 = (Q11 - Q12 - 2 * Q66) * math.cos(float(thetas[j])) * \
        math.sin(float(thetas[j]))**3 - (Q22 - Q12 - 2 * Q66) * \
        math.cos(float(thetas[j]))**3 * math.sin(float(thetas[j]))

        Qbar = np.matrix ([[Qbar11, Qbar12, Qbar16], [Qbar12, Qbar22, Qbar26], \
        [Qbar16, Qbar26, Qbar66]])

        Qbars[i] = Qbar

        if len(thetas) == 1:
            j = 0
        else:
            j = j + 1

    k=0
    Alist = {}
    for i in plies:
        Alist[i] = Qbars[i].dot(h[k])
        if len(h) == 1:
            k = 0
        else:
            k = k + 1
    A = sum(Alist.values())

    ABD = ([A, B],[B, D])
    print ABD

我打算执行的下一个操作是将矩阵乘以 6x1 数组,如下所示:

    | Nx |     | A A A  B B B |
    | Ny |     | A A A  B B B |
    | Nxy|     | A A A  B B B | 
    ------  *  ----------------
    | Mx |     | B B B  D D D |
    | My |     | B B B  D D D |
    | Mxy|     | B B B  D D D |

What would be the best way to go about doing this?

EDIT: I made this shorter code to reproduce what I'm dealing with, I couldn't think of how to make it even smaller.

import os
import numpy as np
import math
os.system('cls')
ang = raw_input("ENTER 0 (SPACE) 45 ")
thetas = [int(i) for i in ang.split()]
x = 40
h = [3, 5]
y = [1,2]
j = 0
Qbars = {}
for i in y:
    theta = [thetas[j] * math.pi / 180]
    Q = math.sin(float(thetas[j]))
    Qbar = np.matrix ([[Q, Q, Q], [Q, Q, Q], [Q, Q, Q]])

    Qbars[i] = Qbar

    if len(thetas) == 1:
        j = 0
    else:
        j = j + 1

print Qbars
k=0
Alist = {}
for i in y:
    Alist[i] = Qbars[i].dot(h[k])
    if len(h) == 1:
        k = 0
    else:
        k = k + 1
A = sum(Alist.values())

AAAA = ([A, A], [A, A])
print AAAA
test = raw_input("Press ENTER to close")

最佳答案

正如其他人指出的那样,the matrix class is pretty much deprecated by now 。它们比 ndarray 更受限制,几乎没有附加功能。人们更喜欢使用 numpy 矩阵的主要原因是线性代数(特别是矩阵乘法)对于矩阵来说更自然。

但是,据我所知,您首先使用的是 np.dot 而不是 matrix 类的重载算术运算符,所以您不会查看使用 np.array 代替的任何功能损失。此外,如果您要切换到 python 3.5 或更高版本,您可以使用 @ 矩阵乘法运算符,它可以让您编写诸如

Alist[i] = Qbars[i] @ h[k]

出于上述原因,下面我将使用 ndarray 类而不是 matrix 类。

所以,你的问题有两个主要部分:创建 block 矩阵并将结果与​​向量相乘。我建议使用最新的 numpy 版本,因为 there's numpy.block 1.13版本中引入。这可以方便地完成您想要它做的事情:

>>> import numpy as np
>>> A,B,C = (np.full((3,3),k) for k in range(3))
>>> A
array([[0, 0, 0],
       [0, 0, 0],
       [0, 0, 0]])
>>> B
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])
>>> C
array([[2, 2, 2],
       [2, 2, 2],
       [2, 2, 2]])
>>> np.block([[A,B],[B,C]])
array([[0, 0, 0, 1, 1, 1],
       [0, 0, 0, 1, 1, 1],
       [0, 0, 0, 1, 1, 1],
       [1, 1, 1, 2, 2, 2],
       [1, 1, 1, 2, 2, 2],
       [1, 1, 1, 2, 2, 2]])

类似地,您可以使用 np.concatenate 或其中一种堆叠方法连接两个 3 长度向量(这些方法在旧版本中也可用)。

现在的问题是,您不能将形状为 (6,1) 的矩阵与形状为 (6,6) 的矩阵相乘,因此问题是你真正想在这里做什么。如果您想将矩阵的每个元素与向量的相应行相乘,您只需将数组(属于 np.ndarray 类!)相乘并使用数组广播:

>>> Q = np.block([[A,B],[B,C]])    # (6,6)-shape array
>>> v = np.arange(6).reshape(-1,1) # (6,1)-shape array
>>> v * Q
array([[ 0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  1,  1,  1],
       [ 0,  0,  0,  2,  2,  2],
       [ 3,  3,  3,  6,  6,  6],
       [ 4,  4,  4,  8,  8,  8],
       [ 5,  5,  5, 10, 10, 10]])

另一种选择是您想要进行矩阵向量乘法,但是您必须转置向量(以便将其与右侧的矩阵相乘)或交换矩阵和向量的顺序(将向量与左侧的矩阵相乘)。前者的示例:

>>> v.T @ Q  # python 3.5 and up
array([[12, 12, 12, 27, 27, 27]])

>>> v.T.dot(Q)
array([[12, 12, 12, 27, 27, 27]])
<小时/>

数组(而不是矩阵)的另一个好处是数组可以是多维的。您可以定义一个 3d 数组(沿第三轴的 2d 数组的集合),然后沿第三个维度求和,而不是将 numpy 数组放入字典中并以这种方式求和。 numpy 的一大好处是其高效的内存需求和性能,如果您在整个代码中使用 numpy 对象和方法,这些方面将是最强的。混合原生 Python 对象(例如 dict、zip、循环)通常会降低性能。

关于python - python 中的矩阵矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46856453/

相关文章:

python - 将全局变量传递给 Python 中的另一个文件?

python - 如何在多种条件下编写Python三元运算符

python - 编码 Base64 Django ImageField 流

python - 如何使用 pyodbc 从 SQL 查询返回列表?

python - joblib并行: reuse workers with the "with" statement

python - Django:如何在其自身内部调用相同的模型类?

python - 嵌套的 Python numpy 数组维度混淆

python - 使用 Numba 对每一行应用多个函数

python - 映射字典值,而不是字典键

python - 为什么使用 numpy.ndarray.astype 将 numpy.ndarray 转换为自定义数据类型会使我的数据相乘?