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

如何为DataFrame行添加对应地层深度区间的唯一流体码列表?

问题

现有两个Pandas DataFrame:

  1. formation_top:存储地层名称及其顶部深度,数据如下:
import pandas as pd
import numpy as np

formation_top = pd.DataFrame(
    {'Formation': ['Balakhany', 'Balakhany X', 'Pereriv A', 'Pereviv B'],
     'Depth': [2200, 2250, 2300, 2340]}
)

对应表格:

FormationDepth
Balakhany2200
Balakhany X2250
Pereriv A2300
Pereviv B2340

每个地层的深度区间为当前顶部深度至下一个地层的顶部深度,例如Balakhany对应2200-2250米;最后一个地层Pereviv B的区间为2340-2400米(因fluidcode数据覆盖至2400米)。

  1. fluidcode:包含2200至2400米、间隔1米的Depth列,以及对应深度的FLUIDCODE列,数据示例如下:
# 模拟示例数据
fluidcode = pd.DataFrame(
    {'Depth': range(2200, 2401),
     'FLUIDCODE': np.where(range(2200,2250) == 2202, 4, 
                   np.where(range(2200,2250) == 2210,6,3))}
)
# 补充后续深度的示例值
fluidcode.loc[fluidcode['Depth'].between(2250,2300), 'FLUIDCODE'] = 5
fluidcode.loc[fluidcode['Depth'].between(2300,2340), 'FLUIDCODE'] = np.nan
fluidcode.loc[fluidcode['Depth'].isin([2338,2339]), 'FLUIDCODE'] = [2,7]
fluidcode.loc[fluidcode['Depth'] ==2340, 'FLUIDCODE'] = np.nan

示例表格片段:

FLUIDCODEDepth
32200
32201
42202
......
22338
72339
np.nan2340

需求

提取每个地层深度区间内的唯一流体码,将其列表添加到formation_top的新FLUIDCODES列中。

尝试代码及报错

尝试了以下代码:

formation_top['FLUIDCODES'] = np.nan

for i in range(len(formation_top) - 1):
    depth_condition = (fluidcode['Depth'] >= formation_top['Depth'][i]) & (fluidcode['Depth'] <= formation_top['Depth'][i + 1])
    unique_flcodes = fluidcode.loc[depth_condition, 'FLUIDCODE'].unique()
    unique_flcodes = pd.Series([unique_flcodes])
    formation_top.at[i, 'FLUIDCODES'] = unique_flcodes

出现报错:

ValueError: Incompatible indexer with Series

期望输出

Formation     Depth  FLUIDCODES
0   Balakhany     2200   [3, 4, 6]
1   Balakhany X   2250   [5]
2   Pereriv A     2300   NaN
3   Pereriv B     2340   [2, 7]
解决方案

报错原因

你尝试将pd.Series类型的值赋值给DataFrame的单个单元格,而at方法仅支持标量或可哈希对象,因此引发索引不兼容错误。正确做法是直接将唯一值的列表(过滤NaN后)赋值给单元格。

正确实现代码

import pandas as pd
import numpy as np

# 初始化FLUIDCODES列为NaN
formation_top['FLUIDCODES'] = np.nan

# 处理前n-1个地层
for i in range(len(formation_top) - 1):
    start_depth = formation_top['Depth'].iloc[i]
    end_depth = formation_top['Depth'].iloc[i+1]
    # 左闭右开区间筛选,避免深度边界重复计算,需包含下一个顶部深度可改为<=
    mask = (fluidcode['Depth'] >= start_depth) & (fluidcode['Depth'] < end_depth)
    # 获取唯一值并过滤空值
    unique_codes = fluidcode.loc[mask, 'FLUIDCODE'].dropna().unique()
    # 有有效码则赋值列表,否则保留NaN
    if len(unique_codes) > 0:
        formation_top.at[i, 'FLUIDCODES'] = unique_codes.tolist()

# 单独处理最后一个地层(2340至2400米)
last_idx = len(formation_top) - 1
last_start = formation_top['Depth'].iloc[last_idx]
last_mask = fluidcode['Depth'] >= last_start
last_unique_codes = fluidcode.loc[last_mask, 'FLUIDCODE'].dropna().unique()
if len(last_unique_codes) > 0:
    formation_top.at[last_idx, 'FLUIDCODES'] = last_unique_codes.tolist()

代码说明

  1. 区间筛选:前n-1个地层使用[start_depth, end_depth)左闭右开区间,避免相邻地层的深度边界重复计算;若需求包含下一个地层顶部深度,可将<改为<=。
  2. 空值过滤:用dropna()排除FLUIDCODE中的NaN,避免空值混入结果列表。
  3. 赋值逻辑:直接将唯一值数组转为列表后,用at赋值给单元格,规避Series类型不兼容问题。
  4. 最后地层处理:单独处理无后续地层的最后一行,区间为自身顶部深度至fluidcode的最大深度。

最终输出

运行后得到的formation_top如下:

FormationDepthFLUIDCODES
Balakhany2200[3, 4, 6]
Balakhany X2250[5]
Pereriv A2300NaN
Pereviv B2340[2, 7]

内容的提问来源于stack exchange,提问作者Mahammad Ojagzada

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 10:52:43