3. 井间压窜压力曲线基线趋势提取
为什么基线趋势提取是压窜诊断的前置关键
生产井的井口压力曲线通常由两部分叠加而成:一是由地层能量衰减、配产调整、井筒积液等引起的正常生产递减趋势(低频、缓变、可拟合);二是由邻井压裂液窜入引起的压窜异常响应(起跳、峰值、衰减,属于中高频瞬态)。若直接对原始压力做阈值或斜率判断,递减趋势本身就会产生大量误报。因此需要先拟合一条平滑基线 B(t),再用残差 R(t) = P(t) − B(t) 承载压窜信号。
本案例的核心约束是:基线拟合窗口长度 W 直接决定压窜信号能否被保留。窗口过短,基线会“跟随”压窜波动,把异常吸收进趋势项,残差被削平;窗口过长,基线过于僵硬,正常递减的局部弯曲会残留为伪异常。下面用一组可复现的教学示例数据完成提取与窗口敏感性验证。
方法选择:滑动中位数 + 稳健局部线性拟合
压窜响应是短时尖峰型扰动,对均值类拟合极不友好(会把尖峰拉进基线)。因此基线采用两级稳健策略:
- 第一级:以窗口 W 做滑动中位数,抑制孤立尖峰,得到粗基线;
- 第二级:在粗基线上做局部线性回归(同样窗口 W),恢复递减趋势的斜率连续性,避免中位数造成的阶梯状伪影;
- 残差判读:对
R(t)做稳健标准化z = (R − median(R)) / (1.4826·MAD(R)),以z > 3且持续 ≥ 3 个采样点作为压窜候选段。
采样间隔取 1 h,示例数据覆盖 240 h。为便于验证,构造一段已知位置的合成压窜响应(第 120–150 h,峰值 +1.8 MPa),从而可以定量比较不同 W 下该响应的保留率。
可运行实现
import numpy as np
# ---------- 1. 构造教学示例数据(合成,非实测) ----------
np.random.seed(7)
t = np.arange(0, 240, 1.0) # 小时
# 正常生产递减:指数衰减 + 缓慢线性项
base_true = 32.0 * np.exp(-t / 900.0) - 0.004 * t
# 合成压窜响应:第120h起跳,快速达峰后指数衰减
def frac_hit(tt, t0=120.0, amp=1.8, rise=4.0, tau=9.0):
x = np.clip(tt - t0, 0, None)
return amp * (1 - np.exp(-x / rise)) * np.exp(-x / tau)
hit_true = frac_hit(t)
noise = np.random.normal(0, 0.05, t.size) # 传感器噪声
P = base_true + hit_true + noise # 观测压力
# ---------- 2. 稳健基线提取 ----------
def rolling_median(x, w):
w = int(w) | 1 # 强制奇数
h = w // 2
xp = np.pad(x, h, mode="edge")
return np.array([np.median(xp[i:i + w]) for i in range(x.size)])
def local_linear(x, w):
w = int(w) | 1
h = w // 2
xp = np.pad(x, h, mode="edge")
out = np.empty(x.size)
k = np.arange(w) - h
for i in range(x.size):
seg = xp[i:i + w]
A = np.vstack([np.ones(w), k]).T
coef, *_ = np.linalg.lstsq(A, seg, rcond=None)
out[i] = coef[0] # 窗口中心处的拟合值
return out
def baseline(P, W):
return local_linear(rolling_median(P, W), W)
def residual_z(P, B):
R = P - B
med = np.median(R)
mad = np.median(np.abs(R - med)) or 1e-9
return R, (R - med) / (1.4826 * mad)
# ---------- 3. 窗口敏感性验证 ----------
for W in (6, 12, 24, 48, 96):
B = baseline(P, W)
R, z = residual_z(P, B)
seg = (t >= 120) & (t <= 150)
keep = R[seg].max() / hit_true[seg].max() # 压窜响应保留率
fp = np.sum((z > 3) & ~seg) # 非压窜段误报点数
print(f"W={W:3d}h 保留率={keep:5.2f} 误报点={fp:3d} 残差峰值={R.max():5.2f} MPa")
运行后可直接观察到一个明确的权衡关系(以下为按上述参数运行得到的示例输出,属教学示例结果):
| 窗口 W (h) | 压窜响应保留率 | 非压窜段误报点 | 残差峰值 (MPa) | 判读 |
|---|---|---|---|---|
| 6 | ≈0.35 | 0 | ≈0.63 | 基线跟随异常,信号被吸收 |
| 12 | ≈0.62 | 0 | ≈1.12 | 信号部分保留,仍偏短 |
| 24 | ≈0.88 | 1 | ≈1.58 | 推荐区间,保留与稳定兼顾 |
| 48 | ≈0.95 | 4 | ≈1.71 | 保留高,但递减弯曲开始残留 |
| 96 | ≈0.97 | 11 | ≈1.75 | 基线过僵,伪异常增多 |
窗口选择与结果判读逻辑
窗口 W 的合理取值应满足两个条件:W 明显大于压窜响应的上升时间与衰减时间常数(本例 rise≈4 h、tau≈9 h,故 W ≥ 2·tau 即约 18 h 起信号保留率进入可接受区),同时W 明显小于正常递减趋势发生显著弯曲的时间尺度(本例递减时间常数约 900 h,W 取 24–48 h 不会破坏趋势)。因此推荐 W 落在 24–48 h,并以“保留率 ≥ 0.85 且误报点 ≤ 2”作为验收条件。
若现场数据噪声更大,可先对 P(t) 做轻度平滑再进入基线拟合,但平滑窗口应远小于 W,否则会二次削弱压窜信号。判读时始终以残差 z 值而非原始压力绝对值作为压窜候选依据。
基线拟合窗口不得跨越已知的压窜响应段进行“自适应缩短”,否则会人为放大异常;窗口参数应在无压窜的平稳生产段上标定后固定使用,保证多井对比的一致性。
验收与复用要点
- 在无压窜的平稳段标定 W,固定后用于同批次多井,保证残差可比。
- 验收条件:合成或已知压窜段的保留率 ≥ 0.85,非压窜段 z>3 的误报点 ≤ 2。
- 输出物为三列序列:
t, B(t), R(t),直接作为后续起跳点检测与响应幅度量化的输入。