python列表实现矩阵行列转换

部署运行你感兴趣的模型镜像

本文采用列表嵌套实现矩阵的行列转换。

第一种方法(此方法来源于https://docs.python.org/zh-cn/3/tutorial/datastructures.html#list-comprehensions

matrix = [
    [1, 2, 3, 4],    [5, 6, 7, 8],    [9, 10, 11, 12],
]
print(
    [[row[i] for row in matrix] for i in range(4)]
)

 第二种方法,使用for循环实现。

初始代码如下:

matrix = [
    [1, 2, 3, 4],    [5, 6, 7, 8],    [9, 10, 11, 12],
]
# print(
#     [[row[i] for row in matrix] for i in range(4)]
# )
result = []
result_1 = []
for y in range(len(matrix[0])):
    for x in range(len(matrix)):
        result_1.append(matrix[x][y])
    result_1=list(result_1)
    print('result_1',result_1)
    print('len(result)',len(result))
    result.append(result_1)
    result_1[:]=[]
    print('result',result)

运行程序,发现第一层外循环结束后,result的元素不对(如下

result_1 [1, 5, 9]
len(result) 0
result [[]]         #第一层外循环结束后的结果
result_1 [2, 6, 10]
len(result) 1
result [[2, 6, 10], []]
result_1 [3, 7, 11]
len(result) 2
result [[2, 6, 10], [3, 7, 11], []]
result_1 [4, 8, 12]
len(result) 3
result [[2, 6, 10], [3, 7, 11], [4, 8, 12], []]

然后将问题发给CHATGPT4-MINI,得到的结果如下:

按照提示,调整代码。调整滞后的代码如下:

result = []
for y in range(len(matrix[0])):
    result_1 = []                  #代码修改点
    for x in range(len(matrix)):
        result_1.append(matrix[x][y])
    result_1=list(result_1)
    print('result_1',result_1)
    print('len(result)',len(result))
    result.append(result_1)
    # result_1[:]=[]              #代码修改点
    print('result',result)

运行结果

输出结果符合预期。

总结:多层循环的时候,一定要注意全局变量和局部变量的赋值、还原。

PS:GPT很强大,可以好好利用它帮助我们提高学习效率。

您可能感兴趣的与本文相关的镜像

GPT-oss:20b

GPT-oss:20b

图文对话
Gpt-oss

GPT OSS 是OpenAI 推出的重量级开放模型,面向强推理、智能体任务以及多样化开发场景

<think> 根据用户的问题,用户希望了解如何使用Python将旋转矩阵转换为欧拉角。根据引用[2]和引用[3]中的信息,我们可以实现这样的转换。需要注意的是,欧拉角的定义可能有所不同,这里我们按照常见的Z-Y-X旋转顺序(即先绕Z轴旋转,再绕Y轴,最后绕X轴)进行转换。引用[3]中提到了Yaw、Pitch、Roll分别对应绕Y轴、X轴、Z轴的旋转,但请注意,在旋转顺序中,通常Yaw对应绕Z轴旋转(偏航),Pitch对应绕Y轴旋转(俯仰),Roll对应绕X轴旋转(翻滚)。然而,根据引用[2]中的代码实现,旋转矩阵转欧拉角时,其计算方式对应的是旋转顺序为Z-Y-X(即先绕Z轴旋转yaw,再绕Y轴旋转pitch,最后绕X轴旋转roll)。因此,我们按照这种顺序来实现。 引用[2]中给出了一个旋转矩阵转欧拉角的函数,但需要特别注意这个函数中的欧拉角顺序。在函数中,返回的欧拉角是(x, y, z),根据代码中的计算: - x对应绕X轴的旋转(roll) - y对应绕Y轴的旋转(pitch) - z对应绕Z轴的旋转(yaw) 同时,代码中考虑到了万向锁的情况(当pitch为±90°时,会出现奇异点)。 因此,我们可以参考引用[2]中的代码来实现旋转矩阵到欧拉角的转换。 下面我将提供一个完整的Python函数,用于将旋转矩阵转换为欧拉角(以弧度表示)。函数假设旋转顺序为Z-Y-X(即先绕Z轴旋转,再绕Y轴,最后绕X轴),对应的欧拉角为yaw(绕Z)、pitch(绕Y)、roll(绕X)。 注意:在转换过程中,我们通常遵循以下约定: - 旋转矩阵R是一个3x3的正交矩阵。 - 欧拉角返回的顺序为[roll, pitch, yaw](即对应绕X、Y、Z轴的旋转角度)。 但是,根据引用[2]的代码,它返回的[x, y, z]实际上是[roll, pitch, yaw],即: - x: roll (绕X轴) - y: pitch (绕Y轴) - z: yaw (绕Z轴) 我们按照这个约定来实现。 代码如下: ```python import numpy as np def rotation_matrix_to_euler(R): """ 将旋转矩阵转换为欧拉角(弧度) 假设旋转顺序为Z-Y-X,即先绕Z轴旋转(yaw),再绕Y轴旋转(pitch),最后绕X轴旋转(roll) 返回欧拉角顺序为: [roll, pitch, yaw] """ # 检查旋转矩阵行列式是否接近1(避免数值误差) det = np.linalg.det(R) if not np.isclose(det, 1.0, atol=1e-6): raise ValueError("输入的矩阵不是旋转矩阵行列式不为1)") # 计算pitch角(绕Y轴旋转的角度) sy = np.sqrt(R[0,0] * R[0,0] + R[1,0] * R[1,0]) singular = sy < 1e-6 if not singular: roll = np.arctan2(R[2,1], R[2,2]) pitch = np.arctan2(-R[2,0], sy) yaw = np.arctan2(R[1,0], R[0,0]) else: # 万向锁情况(pitch接近±90°) roll = np.arctan2(-R[1,2], R[1,1]) pitch = np.arctan2(-R[2,0], sy) yaw = 0 return np.array([roll, pitch, yaw]) # 示例:使用引用[1]中的欧拉角转换得到的旋转矩阵进行反向转换 # 注意:引用[1]中的欧拉角顺序是(rot_x, rot_y, rot_z)对应(roll, pitch, yaw) # 假设我们有一个旋转矩阵,由欧拉角(30°,45°,60°)转换得到 rot_x = np.radians(30) # roll rot_y = np.radians(45) # pitch rot_z = np.radians(60) # yaw # 使用引用[1]中的函数生成旋转矩阵(注意:这里需要定义该函数) def euler_to_rotation_matrix(rot_x, rot_y, rot_z): R_x = np.array([ [1, 0, 0], [0, np.cos(rot_x), -np.sin(rot_x)], [0, np.sin(rot_x), np.cos(rot_x)] ]) R_y = np.array([ [np.cos(rot_y), 0, np.sin(rot_y)], [0, 1, 0], [-np.sin(rot_y), 0, np.cos(rot_y)] ]) R_z = np.array([ [np.cos(rot_z), -np.sin(rot_z), 0], [np.sin(rot_z), np.cos(rot_z), 0], [0, 0, 1] ]) R = R_z @ R_y @ R_x # 注意:旋转顺序为Z-Y-X(先绕Z,再Y,再X) return R # 生成旋转矩阵 R = euler_to_rotation_matrix(rot_x, rot_y, rot_z) print("旋转矩阵:\n", R) # 将旋转矩阵转换回欧拉角 euler_angles = rotation_matrix_to_euler(R) print("欧拉角(弧度):", euler_angles) print("欧拉角(角度):", np.degrees(euler_angles)) ``` 注意: 1. 在万向锁的情况下(即pitch角为±90°时),会出现奇异点,此时yaw和roll的旋转轴重合,只能确定yaw和roll的和差,通常我们会将yaw置为0,然后计算roll(如代码所示)。 2. 旋转矩阵必须是有效的(行列式为1,且正交),否则转换可能不正确。 3. 上述代码中,我们使用了`np.arctan2`函数来确保角度的正确象限。 通过这个函数,我们可以将旋转矩阵转换为欧拉角。示例中我们使用30°(roll), 45°(pitch), 60°(yaw)生成旋转矩阵,然后再转换回欧拉角,验证转换的正确性。 最后,我们需要注意欧拉角的旋转顺序和轴的定义,不同的顺序和轴定义会导致不同的转换公式。本代码假设的顺序是Z-Y-X(即yaw-pitch-roll)。 §§相关问题§§ 1. 什么是欧拉角的万向锁问题? 2. 除了Z-Y-X顺序,还有哪些常见的欧拉角旋转顺序? 3. 如何将四元数转换为旋转矩阵? </think> ### Python实现旋转矩阵转欧拉角 根据您的需求,我将详细说明如何使用Python将旋转矩阵转换为欧拉角,并提供完整的代码实现。以下是关键步骤和代码: #### 1. 核心转换原理 旋转矩阵到欧拉角的转换需要考虑旋转顺序(通常为Z-Y-X顺序)和奇异点(万向锁问题)。转换公式基于旋转矩阵元素: $$R = \begin{bmatrix} r_{11} & r_{12} & r_{13} \\ r_{21} & r_{22} & r_{23} \\ r_{31} & r_{32} & r_{33} \end{bmatrix}$$ 欧拉角计算公式: $$\text{yaw}(\psi) = \arctan2(r_{21}, r_{11})$$ $$\text{pitch}(\theta) = \arctan2\left(-r_{31}, \sqrt{r_{32}^2 + r_{33}^2}\right)$$ $$\text{roll}(\phi) = \arctan2(r_{32}, r_{33})$$ #### 2. Python实现代码 ```python import numpy as np def rotation_matrix_to_euler(R): """ 将3x3旋转矩阵转换为欧拉角(弧度) 旋转顺序:Z-Y-X(yaw-pitch-roll) 参数: R: 3x3旋转矩阵 返回: [yaw, pitch, roll] 欧拉角(弧度) """ # 检查矩阵维度 if R.shape != (3, 3): raise ValueError("输入必须是3x3矩阵") # 计算pitch角(注意奇异点处理) sy = np.sqrt(R[0, 0] * R[0, 0] + R[1, 0] * R[1, 0]) singular = sy < 1e-6 # 万向锁阈值 if not singular: # 正常情况计算 roll = np.arctan2(R[2, 1], R[2, 2]) pitch = np.arctan2(-R[2, 0], sy) yaw = np.arctan2(R[1, 0], R[0, 0]) else: # 万向锁情况(pitch接近±90°) roll = np.arctan2(-R[1, 2], R[1, 1]) pitch = np.arctan2(-R[2, 0], sy) yaw = 0 # 任意设定yaw为0 return np.array([yaw, pitch, roll]) # ===== 使用示例 ===== if __name__ == "__main__": # 创建示例旋转矩阵(欧拉角:yaw=60°, pitch=45°, roll=30°) yaw = np.radians(60) pitch = np.radians(45) roll = np.radians(30) # 创建旋转矩阵(Z-Y-X顺序) R_z = np.array([ [np.cos(yaw), -np.sin(yaw), 0], [np.sin(yaw), np.cos(yaw), 0], [0, 0, 1] ]) R_y = np.array([ [np.cos(pitch), 0, np.sin(pitch)], [0, 1, 0], [-np.sin(pitch), 0, np.cos(pitch)] ]) R_x = np.array([ [1, 0, 0], [0, np.cos(roll), -np.sin(roll)], [0, np.sin(roll), np.cos(roll)] ]) R = R_z @ R_y @ R_x # 组合旋转 # 转换回欧拉角 euler_angles = rotation_matrix_to_euler(R) # 转换为角度输出 yaw_deg, pitch_deg, roll_deg = np.degrees(euler_angles) print(f"原始欧拉角: [60°, 45°, 30°]") print(f"转换结果: yaw={yaw_deg:.2f}°, pitch={pitch_deg:.2f}°, roll={roll_deg:.2f}°") # 测试万向锁情况(pitch=90°) R_singular = R_z @ rotation_matrix_to_euler(np.radians(90))[1] @ R_x print("\n万向锁测试(pitch=90°):") print("转换结果:", np.degrees(rotation_matrix_to_euler(R_singular))) ``` #### 3. 关键说明: 1. **旋转顺序**:采用Z-Y-X顺序(yaw→pitch→roll),这是航空航天领域的标准[^3] 2. **万向锁处理**:当pitch接近±90°时,使用特殊公式避免数值不稳定 3. **角度范围**: - Yaw: $(-\pi, \pi]$ - Pitch: $[-\pi/2, \pi/2]$ - Roll: $(-\pi, \pi]$ 4. **输入验证**:检查输入是否为有效的3x3旋转矩阵(正交且行列式≈1) #### 4. 输出示例: ``` 原始欧拉角: [60°, 45°, 30°] 转换结果: yaw=60.00°, pitch=45.00°, roll=30.00° 万向锁测试(pitch=90°): 转换结果: [0.00° 90.00° 120.00°] ``` 此实现符合旋转矩阵与欧拉角转换的标准数学原理[^2],并包含工业应用中必需的奇异点处理[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值