提问人:Mahammad Ojagzada 提问时间:11/9/2023 最后编辑:Mahammad Ojagzada 更新时间:11/9/2023 访问量:75
合并后,如何只插值非空间隔?
After merging, how to interpolate only non-null intervals?
问:
我有两个示例数据帧:
df1 = pd.DataFrame({'Depth':[1100, 1110, 1120, 1130, 1140], 'GR':[40, 50, 60, np.nan, 70]})
df2 = pd.DataFrame({'Depth':[1100, 1112, 1118, 1128, 1138], 'VSH':[60, 70, np.nan, 40, 70]})
Depth GR
0 1100 40.0
1 1110 50.0
2 1120 60.0
3 1130 NaN
4 1140 70.0
Depth VSH
0 1100 60.0
1 1112 70.0
2 1118 NaN
3 1128 40.0
4 1138 70.0
第一个数据显示,从深度 1120 到 1140 的“GR”值为空。同样,在第二个数据帧中,从 1112 到 1128 的深度“VSH”为 null。我想通过“深度”上的外部连接来连接这些数据集,并通过插值填充空值,其中实际已知的是“GR”。我的意思是,在最终连接的数据集中,不应插值“GR”值(保持为空),其中“GR”的深度介于 1120 和 1140 之间,因为在此时间间隔内,“GR”与第一个数据集一样未知。同样,深度介于 1112 和 1128 之间的“VSH”值应为 null(不插值)。按特定间隔插值后的输出应为:
merged_df = pd.DataFrame({'Depth':[1100, 1110, 1112, 1118, 1120, 1128, 1130, 1138, 1140], 'GR':[40, 50, 53.3, 56.6, 60, np.nan, np.nan, np.nan, 70], 'VSH':[60, 65, 70, np.nan, np.nan, 40, 55, 70, np.nan]})
Depth GR VSH
0 1100 40.0 60.0
1 1110 50.0 65.0
2 1112 53.3 70.0
3 1118 56.6 NaN
4 1120 60.0 NaN
5 1128 NaN 40.0
6 1130 NaN 55.0
7 1138 NaN 70.0
8 1140 70.0 NaN
注意:我只是对 GR 和 VSH 的插值数字进行了近似的插值,它们分别在 df2 和 df1 中没有相应的深度。
你怎么能在熊猫身上做到这一点?
答:
3赞
mozway
11/9/2023
#1
假设您没有无限值,一种选择可能是使用 Inf 作为哨兵来标记这些值不进行插值:
out = (df1.fillna(np.inf)
.merge(df2.fillna(np.inf),
on='Depth',
how='outer',
sort=True)
.interpolate()
.replace(np.inf, np.nan)
)
输出:
Depth GR VSH
0 1100 40.000000 60.0
1 1110 50.000000 65.0
2 1112 53.333333 70.0
3 1118 56.666667 NaN
4 1120 60.000000 NaN
5 1128 NaN 40.0
6 1130 NaN 55.0
7 1138 NaN 70.0
8 1140 70.000000 70.0
如果要基于深度进行插值并避免外推:
out = (df1.fillna(np.inf)
.merge(df2.fillna(np.inf),
on='Depth',
how='outer',
sort=True)
.set_index('Depth')
.interpolate('index', limit_area='inside')
.replace(np.inf, np.nan)
.reset_index()
)
输出:
Depth GR VSH
0 1100 40.0 60.000000
1 1110 50.0 68.333333
2 1112 52.0 70.000000
3 1118 58.0 NaN
4 1120 60.0 NaN
5 1128 NaN 40.000000
6 1130 NaN 46.000000
7 1138 NaN 70.000000
8 1140 70.0 NaN
评论
0赞
Mahammad Ojagzada
11/9/2023
谢谢!只想提一下,我应该在函数中添加参数。limit_area = inside'
.interpolate()
0赞
mozway
11/9/2023
@Muhammad是的,如果您不想“推断”(而不是填充)外部 NaN ;)
2赞
Corralien
11/9/2023
#2
另一个具有实数深度插值的命题:
import scipy as sp
# Create interpolation function
gr = sp.interpolate.interp1d(df1['Depth'], df1['GR'], kind='linear', bounds_error=False)
vsh = sp.interpolate.interp1d(df2['Depth'], df2['VSH'], kind='linear', bounds_error=False)
# Compute interpolation for other depths
df1a = pd.DataFrame({'Depth': df2['Depth'], 'GR': gr(df2['Depth'])})
df2a = pd.DataFrame({'Depth': df1['Depth'], 'VSH': vsh(df1['Depth'])})
# Final dataframe
out = (pd.merge(pd.concat([df1, df1a]),
pd.concat([df2, df2a]))
.drop_duplicates('Depth')
.sort_values('Depth', ignore_index=True))
输出:
>>> out
Depth GR VSH
0 1100 40.0 60.000000
1 1110 50.0 68.333333
2 1112 52.0 70.000000
3 1118 58.0 NaN
4 1120 60.0 NaN
5 1128 NaN 40.000000
6 1130 NaN 46.000000
7 1138 NaN 70.000000
8 1140 70.0 NaN
对于 GR-1112 和 GR-1118,您期望 53.3 和 56.6,因为 GR-1110 (50) 和 GR-1120 (60) 之间有两个空值,但这没有考虑深度的实际值。对我来说,基于深度进行插值比缺失值的数量更有意义,对吧?
评论
0赞
Mahammad Ojagzada
11/9/2023
谢谢!您的解决方案也是正确的。
上一个:在多线图中插值 ggplot2
下一个:如何使用多个相邻点在熊猫中插值?
评论
df1.merge(df2, on='Depth', how='outer', sort=True)