如何用Pandas识别岩性占比主导项并处理占比平分情况?
解决方案:提取岩性占比最高值并处理平分情况
以下是针对你的需求的分步实现方案,直接基于你已有的代码扩展:
核心逻辑拆解
- 将岩性字符串解析为「岩性名称-占比数值」的结构化数据
- 找出每个水井中占比最高的岩性(可能多个)
- 对存在平分情况的水井,展开生成多条记录
- 基于处理后的数据绘制直方图
完整代码实现
import pandas as pd import matplotlib.pyplot as plt import numpy as np # 读取并合并数据(保留你原有的代码) df1 = pd.read_excel(r"data1.xlsx", 'sheet2') df2 = pd.read_excel(r"data2.xlsx", 'sheet2') df = pd.concat([df1, df2]) # 清洗岩性列(保留你原有的代码) df['INDTAG_LITHOLOGI'].replace('', np.nan, inplace=True) df.dropna(subset=['INDTAG_LITHOLOGI'], inplace=True) # 统一列名方便后续处理 df.rename(columns={'INDTAG_LITHOLOGI': 'LITHOLOGY'}, inplace=True) # 1. 解析岩性字符串为结构化列表 def parse_lithology(litho_str): # 分割每个岩性项,去除多余空格 items = [item.strip() for item in litho_str.split(',')] litho_list = [] for item in items: # 分割岩性名称和占比,处理中间的空格 name, percent_str = [p.strip() for p in item.split(':')] # 提取数字并转换为浮点数 percentage = float(percent_str.replace('%', '')) litho_list.append((name, percentage)) return litho_list df['litho_parsed'] = df['LITHOLOGY'].apply(parse_lithology) # 2. 提取所有占比最高的岩性(处理平分情况) def get_top_lithologies(litho_list): # 获取当前水井的最高占比数值 max_percent = max(percent for _, percent in litho_list) # 筛选出所有达到最高占比的岩性 return [name for name, percent in litho_list if percent == max_percent] df['top_lithologies'] = df['litho_parsed'].apply(get_top_lithologies) # 3. 展开平分记录:将列表型列拆分为多条行记录 final_df = df.explode('top_lithologies').rename(columns={'top_lithologies': 'DOMINANT_LITHOLOGY'}) # 保留需要的列(替换为你实际的氟化物列名,比如'FLUORIDE') final_df = final_df[['WELL_ID', 'DOMINANT_LITHOLOGY', 'FLUORIDE']] # 4. 按岩性分组绘制氟化物浓度直方图 for litho, group in final_df.groupby('DOMINANT_LITHOLOGY'): plt.figure(figsize=(8, 5)) plt.hist(group['FLUORIDE'], bins=20, edgecolor='black') plt.title(f'氟化物浓度直方图 - 岩性: {litho}') plt.xlabel('氟化物浓度') plt.ylabel('水井数量') plt.show()
关键细节说明
- 字符串解析函数:处理了岩性字符串中的多余空格(比如
l : 4%这种格式),确保能正确提取岩性名称和占比数值 - 平分情况处理:通过筛选所有等于最高占比的岩性,再用
explode函数自动展开为多条记录,无需手动循环处理 - 性能适配:针对9000条数据,该方案完全基于pandas矢量化操作,效率远高于逐行循环
内容的提问来源于stack exchange,提问作者Aslak Holm Brunvand
相关产品推荐
相关产品推荐

