问题描述
我无法获得正区域(y = 0以上)。数学上该区域应为1.125。
x=np.arange(1,5,1)
y=np.array([-1.5,-0.5,0.5,1.5])
但是下面的函数都没有给我答案。第一个为0。第二个为我1.25,它不会进行插值来计算面积。我需要得到答案1.125。有人可以帮忙吗?谢谢!
np.trapz(y,x)
np.trapz(y.clip(min=0),x)
解决方法
要执行此操作,必须找到数据的线性插值与x轴交叉的位置。此函数是我在另一个答案(Digitizing an analog signal)中包含的函数的变体:
def find_zero_crossings(t,y):
"""
Given the input signal `y` with samples at times `t`,find the times where the linearly interpolated graph
crosses 0.
`t` and `y` must be 1-D numpy arrays.
"""
transition_indices = np.where((np.sign(y[:-1]) * np.sign(y[1:])) == -1)[0]
# Linearly interpolate the time values where the transition occurs.
t0 = t[transition_indices]
t1 = t[transition_indices + 1]
y0 = y[transition_indices]
y1 = y[transition_indices + 1]
slope = (y1 - y0) / (t1 - t0)
transition_times = t0 - y0 / slope
return transition_times
您可以在以下脚本中将其用作示例:
xx = np.arange(1,5,1)
yy = np.array([-1.5,-0.5,0.5,1.5])
xz = find_zero_crossings(xx,yy)
print("xz:",xz)
# Insert the x intercepts into the data.
xx2 = np.append(xx,xz)
yy2 = np.append(yy,np.zeros_like(xz))
# Restore the order of xx2,and order yy2 in the same way.
k = xx2.argsort()
xx2 = xx2[k]
yy2 = yy2[k]
print("xx2:",xx2)
print("yy2:",yy2)
# pos_yy2 is the clipped version of yy2.
pos_yy2 = np.maximum(yy2,0.0)
print("pos_yy2:",pos_yy2)
# Compute the area with `trapz`.
pos_area = np.trapz(pos_yy2,xx2)
print("pos_area:",pos_area)
输出:
xz: [2.5]
xx2: [1. 2. 2.5 3. 4. ]
yy2: [-1.5 -0.5 0. 0.5 1.5]
pos_yy2: [0. 0. 0. 0.5 1.5]
pos_area: 1.125
一个可以完成所有任务的函数:
def pos_trapz(y,x=None,dx=1.0):
if x is None:
x = np.arange(len(y))*dx
xz = find_zero_crossings(x,y)
# Insert the x intercepts into the data.
x2 = np.append(x,xz)
y2 = np.append(y,np.zeros_like(xz))
# Restore the order of x2,and order y2 in the same way.
# (The function assumes that the input `x` is in ascending order.)
k = x2.argsort()
x2 = x2[k]
y2 = y2[k]
# pos_y2 is the clipped version of y2.
pos_y2 = np.maximum(y2,0.0)
# Compute the area with `trapz`.
return np.trapz(pos_y2,x2)
在ipython会话中:
In [107]: xx = np.arange(1,1)
In [108]: yy = np.array([-1.5,1.5])
In [109]: pos_trapz(yy,xx)
Out[109]: 1.125