You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将含x/y/z列的pandas DataFrame按行转为可运算向量

解决方案

不需要逐行拆分DataFrame生成独立Python列表向量,直接用numpy向量化运算处理是效率最高、代码最简洁的方案,逐行遍历、apply/lambda逐行处理的写法不仅冗余,数据量大时性能会差很多。

你提取的坐标数组天然支持所有向量、矩阵运算,完全满足笛卡尔转球坐标、旋转、转回笛卡尔坐标的需求,全流程不需要写显式for循环。

完整实现代码

import pandas as pd
import numpy as np

# 原始坐标数据
data = [[7.68, -0.3, -98.55],[7.59, 1.20, -99.26],[7.69, -0.2, -97.23],[6.98, 1.32, -98.98]]
# 构造DataFrame,如果你原始输入是字符串列表,再做astype转换即可
atomdata = pd.DataFrame(data, columns=['x','y','z'])

# 1. 提取所有坐标为形状(n,3)的numpy数组,每一行对应一个(x,y,z)向量
coords = atomdata[['x','y','z']].to_numpy()

# 2. 笛卡尔坐标转球坐标
def cart2sph(cart_coords):
    x, y, z = cart_coords[:,0], cart_coords[:,1], cart_coords[:,2]
    r = np.sqrt(x**2 + y**2 + z**2)
    elev = np.arcsin(z / r)  # 俯仰角,范围[-π/2, π/2]
    azim = np.arctan2(y, x)  # 方位角,范围[-π, π]
    return np.stack([r, elev, azim], axis=1)

# 3. 球坐标下按指定轴旋转theta角(theta单位为弧度)
def rotate_sph(sph_coords, theta, axis='z'):
    r, elev, azim = sph_coords[:,0], sph_coords[:,1], sph_coords[:,2]
    if axis == 'z':
        azim += theta
    elif axis == 'x':
        new_elev = np.arcsin(np.sin(elev)*np.cos(theta) + np.cos(elev)*np.sin(azim)*np.sin(theta))
        new_azim = np.arctan2(
            np.cos(elev)*np.sin(azim)*np.cos(theta) - np.sin(elev)*np.sin(theta),
            np.cos(elev)*np.cos(azim)
        )
        elev, azim = new_elev, new_azim
    elif axis == 'y':
        new_elev = np.arcsin(np.sin(elev)*np.cos(theta) - np.cos(elev)*np.cos(azim)*np.sin(theta))
        new_azim = np.arctan2(
            np.cos(elev)*np.sin(azim),
            np.cos(elev)*np.cos(azim)*np.cos(theta) + np.sin(elev)*np.sin(theta)
        )
        elev, azim = new_elev, new_azim
    return np.stack([r, elev, azim], axis=1)

# 4. 球坐标转回笛卡尔坐标
def sph2cart(sph_coords):
    r, elev, azim = sph_coords[:,0], sph_coords[:,1], sph_coords[:,2]
    x = r * np.cos(elev) * np.cos(azim)
    y = r * np.cos(elev) * np.sin(azim)
    z = r * np.sin(elev)
    return np.stack([x, y, z], axis=1)

# 调用示例:绕z轴旋转45度(π/4弧度)
theta = np.pi/4
sph_coords = cart2sph(coords)
rotated_sph = rotate_sph(sph_coords, theta, axis='z')
rotated_cart = sph2cart(rotated_sph)

# 结果写回原DataFrame
atomdata[['x_rot', 'y_rot', 'z_rot']] = rotated_cart

补充说明

  • 如果你确实需要逐行取出单独向量做自定义处理,直接遍历numpy数组即可:for vec in coords: 每次循环拿到的就是长度为3的一维数组,对应单行x/y/z值,直接支持各类向量运算。
  • 不建议用逐行apply+lambda的方式处理坐标运算,numpy向量化操作的速度比逐行apply快10~100倍,代码可读性也更高。
  • 如果你原始的ATOMS是字符串列表,只需要在构造DataFrame后做一次类型转换即可,不需要额外写循环逐行处理:
    atomdata = atomdata.astype({'x':float, 'y':float, 'z':float})
    

内容的提问来源于stack exchange,提问作者Landon Gaber

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 15:15:49