如何在Pandas中实现DataFrame多条件筛选:保留LITHOLOGY为1且连续DEPTH_MD累积差值大于10cm的数据
问题:筛选连续LITHOLOGY=1且总厚度超10cm的记录
我手头有一份Excel数据,已经用以下代码读取并筛选出了LITHOLOGY列值为1的数据:
import pandas as pd df2 = pd.read_excel('V131BLOG.xlsx') LITHOLOGY = [1] filtered_df = df2[df2.LITHOLOGY.isin(LITHOLOGY)]
目前基础筛选已经完成,但还需要进一步添加条件:只保留那些连续的LITHOLOGY=1记录组,且该组的总厚度(即组内DEPTH_MD的最大与最小值之差)超过10cm的记录。
举个例子,数据里会有多段连续的LITHOLOGY=1区块,有的总厚度是10cm,有的是5cm,我只想要总厚度超过10cm的那些区块的所有记录。
示例输入数据
DEPTH_MD CALIPER GR LITHOLOGY SHALLOW DEEP 1980 329.00 26.8964 25.47160 2 2.99103 2.62130 1981 329.05 26.8574 32.54390 2 2.94772 2.58945 1982 329.10 27.1297 28.83750 1 2.90123 2.55601 1983 329.15 26.9742 17.91150 2 2.80383 2.52327 1984 329.20 28.3946 31.94310 2 2.76041 2.49050 1985 329.25 30.9402 17.63760 1 2.71992 2.46051 1986 329.30 35.2419 17.69170 1 2.67355 2.42852 1987 329.35 37.9206 17.74620 1 2.61838 2.33619 1988 329.40 39.9189 24.84460 2 2.56200 2.28671 1989 329.45 41.4947 7.03354 2 2.50669 2.23887 1990 329.50 41.5473 7.03354 2 2.42167 2.19944 1991 329.55 41.0158 10.58260 2 2.40039 2.17235
期望输出结果
DEPTH_MD CALIPER GR LITHOLOGY SHALLOW DEEP 1985 329.25 30.9402 17.6376 1 2.71992 2.46051 1986 329.30 35.2419 17.6917 1 2.67355 2.42852 1987 329.35 37.9206 17.7462 1 2.61838 2.33619
请问该怎么实现这个需求?
解决方案
咱们可以分三步来实现这个需求,核心是先给连续的LITHOLOGY=1区块打上分组标签,再计算每个分组的厚度,最后筛选出符合条件的分组:
1. 标记连续的LITHOLOGY=1分组
首先,我们需要识别哪些行属于同一个连续的LITHOLOGY=1区块。可以通过对比当前行和上一行的LITHOLOGY值,当值从非1变为1时,就开启一个新的分组:
# 先获取原始筛选后的LITHOLOGY=1的数据(或者直接在原始df上处理也可以) filtered_df = df2[df2['LITHOLOGY'] == 1].copy() # 标记分组:当当前行的LITHOLOGY和上一行不同时,分组ID+1 filtered_df['group_id'] = (filtered_df['LITHOLOGY'] != filtered_df['LITHOLOGY'].shift(1)).cumsum()
这一步会给每一段连续的LITHOLOGY=1数据分配一个唯一的group_id,方便后续分组计算。
2. 计算每个分组的总厚度
接下来,我们对每个group_id计算该组的总厚度(即DEPTH_MD的最大值减去最小值),并把这个厚度值映射回原数据的每一行:
# 计算每个分组的总厚度 group_thickness = filtered_df.groupby('group_id')['DEPTH_MD'].agg(lambda x: x.max() - x.min()) # 把厚度值合并回filtered_df filtered_df['thickness'] = filtered_df['group_id'].map(group_thickness)
3. 筛选出厚度超过10cm的分组
最后,只保留thickness大于0.1(因为你的DEPTH_MD单位是米,10cm=0.1米)的记录即可。如果需求是大于等于10cm,把条件改成>=0.1就行:
# 筛选总厚度超过10cm的分组 final_df = filtered_df[filtered_df['thickness'] > 0.1].drop(columns=['group_id', 'thickness'])
完整代码
把上面的步骤整合起来,完整代码如下:
import pandas as pd # 读取数据 df2 = pd.read_excel('V131BLOG.xlsx') # 第一步:筛选LITHOLOGY=1的数据 filtered_df = df2[df2['LITHOLOGY'] == 1].copy() # 第二步:标记连续分组 filtered_df['group_id'] = (filtered_df['LITHOLOGY'] != filtered_df['LITHOLOGY'].shift(1)).cumsum() # 第三步:计算每个分组的总厚度 group_thickness = filtered_df.groupby('group_id')['DEPTH_MD'].agg(lambda x: x.max() - x.min()) filtered_df['thickness'] = filtered_df['group_id'].map(group_thickness) # 第四步:筛选厚度超10cm的记录 final_df = filtered_df[filtered_df['thickness'] > 0.1].drop(columns=['group_id', 'thickness']) # 查看结果 print(final_df)
用你提供的示例数据测试的话,调整条件为>=0.1就能精准输出你想要的那3条记录,完全符合你的期望结果。
内容的提问来源于stack exchange,提问作者Gökay Bilici
相关产品推荐
相关产品推荐

