如何将多组2D DataFrames合并为3D xarray并调整维度?
解决xarray合并多组DataFrames为3D结构的问题
问题背景
我有多组2D DataFrames,结构如下:
表格1
| 5 6 4 | 8 -1 3 | angle | |
|---|---|---|---|
| 5 | 105.87 | 459.62 | 0.1 |
| 10 | 211.74 | 919.24 | 0.1 |
表格2
| 5 6 4 | 8 -1 3 | angle | |
|---|---|---|---|
| 5 | 125.87 | 439.62 | 0.2 |
| 10 | 241.74 | 949.24 | 0.2 |
目标是合并为3D xarray,期望结构:
Dimensions: (xyz: 2, thickness: 2, angle: 2) Coordinates: * xyz (xyz) object '5 6 4' '8 -1 3' * thickness (thickness) int 5 10 * angle (angle) float64 0.1 0.2 Data variables: # 存储对应数值的变量,比如命名为intensity
当前转换方式:xa = xarray.Dataset.from_dataframe(df).set_coords("angle"),得到的2D xarray结构:
Dimensions: (thickness: 2) Coordinates: * thickness (thickness) int 5 10 angles (thickness) float64 0.1 0.1 Data variables: 5 6 4 (thickness) float64 105.87 211.74 8 -1 3 (thickness) float64 459.62 919.24
合并时出现错误:MergeError: conflicting values for variable '0 0 0 ' on objects to be combined. You can skip this check by specifying compat='override'.
咨询以下两个问题:
- 如何将angle转换为维度(而非普通坐标)?
- 如何将'5 6 4'、'8 -1 3'这类xyz坐标转换为名为xyz的维度?
解决方案
1. 将angle转为维度
每组DataFrame里的angle值是统一的(比如表格1全为0.1),转换时直接给数据集添加angle维度即可:
- 提取单个DataFrame的唯一angle值
- 移除angle列后,用
expand_dims添加angle维度
示例代码:
import xarray as xr # 处理表格1的df1 angle_val = df1['angle'].iloc[0] xa1 = xr.Dataset.from_dataframe(df1.drop(columns='angle')) xa1 = xa1.expand_dims(angle=[angle_val])
处理后,xarray会包含thickness和angle两个维度,angle是维度而非普通坐标。
2. 将xyz列转为xyz维度
当前xyz列是数据变量,需要转成维度并整合数值到单个数据变量中,可通过melt将DataFrame转成长格式后再转xarray:
# 处理单个df(以df1为例) # 1. 转成长格式:保留thickness和angle,将xyz列转为行 melted_df1 = df1.reset_index().melt(id_vars=['index', 'angle'], var_name='xyz', value_name='intensity') # 2. 设置xarray的维度 xa1 = xr.Dataset.from_dataframe(melted_df1).set_index(thickness='index', angle='angle', xyz='xyz')
处理后,单个xarray会包含thickness、angle、xyz三个维度,数值存储在intensity变量中(可自定义变量名)。
合并多个xarray
所有DataFrame处理完成后,用xr.concat直接合并即可:
# 假设xa1、xa2是处理后的两个数据集 combined_xa = xr.concat([xa1, xa2], dim='angle')
完整流程示例
import pandas as pd import xarray as xr # 构造示例DataFrame df1 = pd.DataFrame({ '5 6 4': [105.87, 211.74], '8 -1 3': [459.62, 919.24], 'angle': [0.1, 0.1] }, index=[5, 10]) df1.index.name = 'thickness' df2 = pd.DataFrame({ '5 6 4': [125.87, 241.74], '8 -1 3': [439.62, 949.24], 'angle': [0.2, 0.2] }, index=[5, 10]) df2.index.name = 'thickness' # 定义统一处理函数 def process_df(df): melted = df.reset_index().melt(id_vars=['thickness', 'angle'], var_name='xyz', value_name='intensity') return xr.Dataset.from_dataframe(melted).set_index(thickness='thickness', angle='angle', xyz='xyz') # 处理并合并 xa_list = [process_df(df1), process_df(df2)] combined = xr.concat(xa_list, dim='angle') # 查看结果 print(combined)
输出结构与期望一致:
Dimensions: (thickness: 2, angle: 2, xyz: 2) Coordinates: * thickness (thickness) int64 5 10 * angle (angle) float64 0.1 0.2 * xyz (xyz) object '5 6 4' '8 -1 3' Data variables: intensity (thickness, angle, xyz) float64 105.87 459.62 125.87 ... 949.24
内容的提问来源于stack exchange,提问作者Anavae
相关产品推荐
相关产品推荐

