【问题标题】:Python: Calculate area under the curvePython:计算曲线下的面积
【发布时间】:2021-06-26 11:33:26
【问题描述】:

我有两列“x”、“y”的 Pandas DataFrame:

tmp = pd.DataFrame()
tmp['x'] = [1, 2, 5, 9, 12, 14]
tmp['y'] = [0, 1, -2, 2, -1, 1] 
tmp.plot(x = 'x', y = 'y')

ax = plt.gca()
ax.set_aspect('equal')
ax.grid(True, which='both')


ax.axhline(y=0, color='k')
ax.axvline(x=0, color='k')
plt.show()

剧情如下:

我想分别得到 y=0 以上和 y=0 以下的三角形区域。

有没有简单的方法可以做到这一点?

我尝试使用集成,但似乎我做错了什么:

pos = tmp[tmp['y']>=0]
neg = tmp[tmp['y']<=0]
print(integrate.trapezoid(pos['y'], pos['x'])) # this gives 18.5 instead of desired 5.5
print(integrate.trapezoid(neg['y'], neg['x'])) # this gives -14.5 instead of desired 5
# seems this does correct calculation, but calculates areas as negative and positive and in total it gives small area
print(integrate.trapezoid(tmp['y'], tmp['x'])) # this gives 0.5 instead of desired 10.5

这是一个更小/更简单的代码来显示我想要做什么。其实我的数据很大。 我想我可以通过在 y = 0 的地方添加相应的 (x, y) 值来达到预期的效果,但我想知道是否有现有的函数可以完成类似的工作。

【问题讨论】:

  • 你的意思是高于 y=0 低于 y=0,对吧?
  • @lifezbeautiful 是的,感谢您指出这一点!
  • @Heghine,您的问题似乎与 this question 重复。

标签: python pandas scipy integral


【解决方案1】:

我希望你所说的面积是 x 轴和曲线之间的面积,因为没有开放曲线的面积,所以基于这个假设,我还假设 x 总是一个递增的数字
如果您检查 pos 和 neg 数据框,与您想要的相比,它们将变成完全不同的形状。要计算面积,您需要分别计算x轴上方和下方所有图形的面积,即识别所有x交叉点并找到交叉点之间的面积

我已经编写了一个通用代码,您仍然需要添加一些边缘情况,其中信号不以拦截方式开始或结束

tmp['change'] = tmp['y']*tmp['y'].shift(1)<0 ## points before which intercept would be found
tmp['slope']=(tmp['y']-tmp['y'].shift(1))/(tmp['x']-tmp['x'].shift(1))  ## identify slope
tmp['intersection']=-tmp['y']/tmp['slope']+tmp['x']  ## identify point of intersection
intersections=tmp[tmp['change']==True]  ## only take intersection from points where sign of 'y has changed

intersections=intersections[['intersection']]
intersections.rename(columns={"intersection":"x"}, inplace=True)
intersections['y']=int(0)

tmp = tmp[['x','y']]
tmp=tmp.append(intersections)
tmp=tmp.sort_values(by='x')
tmp=tmp.reset_index(drop=True)

crossing = tmp[tmp['y']==0].index  ## points between which area is to be identified
area=0
for i in range(len(crossing)-1):
    area_tmp=integrate.trapz(tmp[crossing[i]:crossing[i+1]+1]['y'],tmp[crossing[i]:crossing[i+1]+1]['x'])
    area+=abs(area_tmp)
    # print(area_tmp)
print(area)

这给出的答案是 10,你仍然需要为最后一个三角形添加边缘情况

P.S:无法评论问题

【讨论】:

    猜你喜欢
    • 2011-06-24
    • 2021-10-24
    • 2021-04-18
    • 1970-01-01
    • 2023-01-12
    • 2012-01-29
    • 2021-06-08
    • 2022-01-23
    相关资源
    最近更新 更多