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

识别3D NumPy孔隙度数组中贯穿各层同类孔隙区的首层网格单元

储层孔隙度分类与井位识别方案优化

一、先解决“统计层数为0”的核心问题

你遇到的统计结果全为0,基本是两个原因:要么分类阈值和孔隙度数据范围不匹配,要么分类/统计的轴方向搞反了。下面是修正后的完整代码,先把基础逻辑跑通:

import numpy as np
from scipy.ndimage import gaussian_filter
import matplotlib.pyplot as plt

# 1. 生成符合储层特征的孔隙度数据(0-1范围,模拟真实分布)
porosity_array = np.random.normal(loc=0.3, scale=0.15, size=(40, 50, 50))
porosity_array = np.clip(porosity_array, 0.1, 0.8)  # 限制合理范围,避免极端值

# 2. 高斯平滑处理
smoothed_poro = gaussian_filter(porosity_array, sigma=(1, 2, 2))  # 层间平滑弱,平面内平滑强

# 3. 用分位数设置分类阈值(比固定值更适配数据分布)
low_thresh = np.percentile(smoothed_poro, 33)
mid_thresh = np.percentile(smoothed_poro, 67)

# 4. 分类:(层,行,列) → 每个网格点的类别(0=差,1=中,2=优)
poro_classes = np.zeros_like(smoothed_poro, dtype=int)
poro_classes[smoothed_poro >= mid_thresh] = 2  # 优(高孔隙度)
poro_classes[(smoothed_poro >= low_thresh) & (smoothed_poro < mid_thresh)] = 1  # 中
poro_classes[smoothed_poro < low_thresh] = 0  # 差(低孔隙度)

# 5. 统计每个首层网格(第0层)垂直方向穿过各类别的层数
# 注意:axis=0是层方向,统计每个(行,列)点在40层中属于各类别的次数
count_low = np.sum(poro_classes[:, :, :] == 0, axis=0)
count_mid = np.sum(poro_classes[:, :, :] == 1, axis=0)
count_high = np.sum(poro_classes[:, :, :] == 2, axis=0)

# 验证:打印首层几个点的统计结果,应该不会全为0
print("首层随机点的低孔隙度层数:", count_low[10,10])
print("首层随机点的中孔隙度层数:", count_mid[10,10])
print("首层随机点的高孔隙度层数:", count_high[10,10])

二、高效实现井位识别(分散+垂直穿透多)

要同时满足“垂直穿透对应类别多”和“井位不聚集”,可以用贪心筛选+空间约束的思路:

步骤1:对每个类别生成优先级图

比如针对高孔隙度(优)类别,直接拿count_high作为优先级,值越高的点越优先选。

步骤2:贪心选点+排除邻域

def select_wells(priority_map, num_wells, exclude_radius=3):
    """
    从优先级图中选分散的井位
    :param priority_map: (50,50)的优先级数组(值越高越优先)
    :param num_wells: 要选的井位数
    :param exclude_radius: 选点后排除周围N个网格
    :return: 选中的井位坐标列表[(行,列), ...]
    """
    wells = []
    priority_copy = priority_map.copy()
    
    for _ in range(num_wells):
        # 找当前优先级最高的点
        max_idx = np.unravel_index(np.argmax(priority_copy), priority_copy.shape)
        wells.append(max_idx)
        
        # 排除该点周围radius范围内的所有点,避免聚集
        r = exclude_radius
        row, col = max_idx
        # 限制边界,防止越界
        row_min = max(0, row - r)
        row_max = min(priority_copy.shape[0], row + r + 1)
        col_min = max(0, col - r)
        col_max = min(priority_copy.shape[1], col + r + 1)
        priority_copy[row_min:row_max, col_min:col_max] = -np.inf  # 设为极小值,不再选中
    
    return wells

# 示例:选5个高孔隙度优先的分散井位
high_wells = select_wells(count_high, num_wells=5, exclude_radius=4)
print("选中的高孔隙度井位:", high_wells)

三、Jet色图可视化优化

直接用matplotlib的jet色图对应分类,同时叠加井位标记:

# 1. 首层孔隙度分类可视化
plt.figure(figsize=(8,8))
im = plt.imshow(poro_classes[0, :, :], cmap='jet', vmin=0, vmax=2)
# 标记选中的井位
for (row, col) in high_wells:
    plt.scatter(col, row, marker='*', s=200, c='white', edgecolor='black')
plt.colorbar(im, ticks=[0,1,2], label='孔隙度类别:0=差(蓝),1=中(黄),2=优(红)')
plt.title('首层孔隙度分类与井位分布')
plt.show()

# 2. 垂直剖面可视化(比如沿着某口井的列方向)
well_row, well_col = high_wells[0]
plt.figure(figsize=(10,4))
im = plt.imshow(poro_classes[:, well_row, :], cmap='jet', aspect='auto', vmin=0, vmax=2)
plt.scatter(well_col, 0, marker='*', s=200, c='white', edgecolor='black')
plt.colorbar(im, ticks=[0,1,2], label='孔隙度类别')
plt.title(f'井位({well_row},{well_col})垂直剖面孔隙度分布')
plt.xlabel('列')
plt.ylabel('层')
plt.show()

关键优化点总结

  • 用分位数阈值替代固定值:避免因随机数据分布变化导致分类失效,更适配真实储层数据的统计特征
  • 向量化统计:完全用numpy的sum(axis=0)替代循环,效率提升几个数量级
  • 贪心选点+邻域排除:简单高效,保证井位分散,比聚类算法更容易理解和调整
  • 可视化叠加标记:直接验证井位是否落在目标区域,垂直剖面可直观看到穿透层数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 07:53:11