news 2026/6/14 9:21:16

土壤重金属数据怎么分析?Python+Pandas+GeoPandas快速处理Cr、Pb、Cu、Zn、As、Hg、Cd数据

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
土壤重金属数据怎么分析?Python+Pandas+GeoPandas快速处理Cr、Pb、Cu、Zn、As、Hg、Cd数据

土壤重金属数据实战分析:Python自动化处理与空间可视化指南

当面对数百个土壤采样点的重金属数据时,传统的手工统计和Excel操作不仅效率低下,还容易出错。本文将带你用Python生态中的Pandas、GeoPandas和Matplotlib工具链,实现从原始数据到专业分析报告的全流程自动化处理。

1. 数据准备与初步探索

拿到土壤重金属数据的第一件事,是检查数据质量和结构。典型的土壤重金属数据集通常包含采样点ID、经纬度坐标、采样深度以及各种元素(Cr、Pb、Cu等)的浓度值。假设我们有一个CSV格式的原始数据文件soil_samples.csv

import pandas as pd # 读取数据并显示前5行 df = pd.read_csv('soil_samples.csv') print(df.head()) # 检查数据基本信息 print(df.info()) # 描述性统计 stats = df.describe(percentiles=[.25, .5, .75, .95]) print(stats.loc[['mean', 'std', 'min', '50%', 'max']])

常见的数据质量问题包括:

  • 缺失值(特别是偏远地区的采样点)
  • 异常值(可能是录入错误或真实污染)
  • 单位不统一(ppm与mg/kg混用)
  • 坐标系统不一致(WGS84与GCJ02混用)

数据清洗示例

# 处理缺失值 - 按元素中位数填充 elements = ['Cr', 'Pb', 'Cu', 'Zn', 'As', 'Hg', 'Cd'] for elem in elements: df[elem].fillna(df[elem].median(), inplace=True) # 移除极端异常值(超过99百分位) for elem in elements: upper_limit = df[elem].quantile(0.99) df = df[df[elem] <= upper_limit]

2. 重金属统计分析技术

2.1 基础统计量计算

除了常规的平均值、标准差外,土壤重金属分析需要特别关注:

  • 超标倍数:相对于区域背景值的比率
  • 变异系数:反映元素空间分布均匀性
  • 偏态系数:判断污染源分布特征
# 定义区域背景值(单位:mg/kg) background = { 'Cr': 61.0, 'Pb': 26.0, 'Cu': 22.6, 'Zn': 74.2, 'As': 11.2, 'Hg': 0.065, 'Cd': 0.097 } # 计算各元素超标倍数 exceedance = {} for elem in elements: mean_val = df[elem].mean() exceedance[elem] = mean_val / background[elem] # 转换为DataFrame便于查看 exceed_df = pd.DataFrame.from_dict(exceedance, orient='index', columns=['Exceedance']) print(exceed_df.sort_values('Exceedance', ascending=False))

2.2 元素相关性分析

重金属元素之间的相关性可以揭示共同污染源。使用Pandas计算相关系数矩阵:

corr_matrix = df[elements].corr() # 可视化热力图 import seaborn as sns import matplotlib.pyplot as plt plt.figure(figsize=(10,8)) sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0) plt.title('重金属元素相关性热力图') plt.show()

典型的相关模式:

  • 工业污染特征:Pb、Zn、Cd高度相关
  • 农业污染特征:As、Hg与其它元素相关性低
  • 自然背景特征:Cr与其它元素相关性弱

3. 空间分布可视化

3.1 地理数据处理

使用GeoPandas将普通数据框转换为地理数据框:

import geopandas as gpd from shapely.geometry import Point # 创建几何对象 geometry = [Point(xy) for xy in zip(df['经度'], df['纬度'])] gdf = gpd.GeoDataFrame(df, geometry=geometry, crs="EPSG:4326") # 转换为适合分析的投影(如Web墨卡托) gdf = gdf.to_crs(epsg=3857)

3.2 制作元素分布图

绘制Cd元素的空间分布散点图:

fig, ax = plt.subplots(figsize=(12,10)) # 背景地图(需安装contextily) import contextily as ctx gdf.plot(ax=ax, alpha=0.5) ctx.add_basemap(ax, source=ctx.providers.Stamen.Terrain) # 按Cd浓度分级着色 scatter = gdf.plot(column='Cd', cmap='viridis', legend=True, markersize=50, ax=ax, scheme='quantiles', edgecolor='white', linewidth=0.3) ax.set_title('土壤Cd含量空间分布', fontsize=16) ax.set_axis_off() plt.show()

3.3 空间插值(可选)

虽然GeoPandas不直接支持空间插值,但可以结合scipy进行简单插值:

from scipy.interpolate import griddata import numpy as np # 准备插值网格 x = gdf.geometry.x y = gdf.geometry.y z = gdf['Cd'] # 创建网格 xi = np.linspace(x.min(), x.max(), 100) yi = np.linspace(y.min(), y.max(), 100) xi, yi = np.meshgrid(xi, yi) # 执行插值 zi = griddata((x, y), z, (xi, yi), method='cubic') # 绘制等高线图 plt.figure(figsize=(12,10)) contour = plt.contourf(xi, yi, zi, levels=15, cmap='Reds') plt.colorbar(contour) plt.scatter(x, y, c='k', s=5) plt.title('Cd含量空间插值结果') plt.show()

4. 高级分析与报告生成

4.1 污染评价指数计算

常用的土壤污染评价方法包括:

  • 单因子污染指数:$P_i = C_i / S_i$
  • 内梅罗综合指数:$P_{综合} = \sqrt{(P_{avg}^2 + P_{max}^2)/2}$
# 定义土壤环境质量标准(二级标准,pH>7.5) standard = { 'Cr': 250, 'Pb': 350, 'Cu': 100, 'Zn': 300, 'As': 25, 'Hg': 1.0, 'Cd': 0.6 } # 计算单因子指数 for elem in elements: df[f'{elem}_PI'] = df[elem] / standard[elem] # 计算综合指数 df['P_avg'] = df[[f'{e}_PI' for e in elements]].mean(axis=1) df['P_max'] = df[[f'{e}_PI' for e in elements]].max(axis=1) df['P_nemerow'] = np.sqrt((df['P_avg']**2 + df['P_max']**2)/2) # 污染等级划分 bins = [0, 0.7, 1.0, 2.0, 3.0, float('inf')] labels = ['安全', '警戒线', '轻度污染', '中度污染', '重度污染'] df['Pollution_Level'] = pd.cut(df['P_nemerow'], bins=bins, labels=labels)

4.2 自动化报告生成

使用Jupyter Notebook结合Python代码可以生成交互式分析报告。以下是一个静态报告生成示例:

from fpdf import FPDF class PDF(FPDF): def header(self): self.set_font('Arial', 'B', 15) self.cell(0, 10, '土壤重金属分析报告', 0, 1, 'C') def chapter_title(self, title): self.set_font('Arial', 'B', 12) self.cell(0, 10, title, 0, 1, 'L') self.ln(4) def chapter_body(self, body): self.set_font('Arial', '', 12) self.multi_cell(0, 10, body) self.ln() # 创建PDF pdf = PDF() pdf.add_page() # 添加内容 pdf.chapter_title('1. 分析概述') pdf.chapter_body(f"本次分析共处理{len(df)}个采样点,覆盖{len(df['地区'].unique())}个地区。" "主要分析了Cr、Pb、Cu、Zn、As、Hg、Cd七种重金属元素的含量分布特征。") pdf.chapter_title('2. 主要发现') pdf.chapter_body(f"- Cd的平均超标倍数最高,达到{exceedance['Cd']:.1f}倍\n" f"- {df['Pollution_Level'].value_counts().idxmax()}区域占比最大") # 保存文件 pdf.output('soil_analysis_report.pdf')

4.3 交互式可视化(可选)

使用Plotly创建交互式地图:

import plotly.express as px fig = px.scatter_mapbox(df, lat="纬度", lon="经度", color="Cd", size="Cd", hover_name="采样点ID", hover_data=elements, color_continuous_scale=px.colors.sequential.Viridis, zoom=10) fig.update_layout(mapbox_style="open-street-map") fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0}) fig.show()

这套分析方法已经成功应用于多个农业土壤调查项目。在实际项目中,建议将上述代码封装成函数和类,并通过配置文件管理不同地区的背景值和标准值。对于超大规模数据集(10万+采样点),可以考虑使用Dask替代Pandas进行分布式计算。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/14 9:12:52

14804华夏之光永存:黄大年茶思屋榜文148期 第4题 热仿真加速

华夏之光永存&#xff1a;黄大年茶思屋榜文148期 第4题 热仿真加速 摘要 本文针对先进芯片热仿真规模爆炸式增长导致计算效率极低的行业痛点&#xff0c;提出了一种基于物理信息神经网络(PINNs)分层加速自适应网格降阶多尺度耦合求解的工程化解决方案。该方案在华为指定验证案例…

作者头像 李华
网站建设 2026/6/14 9:12:02

从iPhone LiDAR数据到高质量三维重建:TSDF、BundleFusion方案实测与性能对比(含环境配置踩坑记录)

iPhone LiDAR三维重建实战&#xff1a;TSDF与BundleFusion方案深度评测与技术选型指南 当iPhone Pro系列搭载LiDAR传感器的那一刻起&#xff0c;移动端三维重建的门槛被彻底降低。不同于传统深度相机动辄数万元的设备投入&#xff0c;现在你口袋里的手机就能采集毫米级精度的深…

作者头像 李华
网站建设 2026/6/14 9:12:01

维基百科温室气体数据爬取与聚类分析实战

1. 项目概述&#xff1a;为什么从维基百科抓取温室气体数据值得认真对待在数据科学的实际工作中&#xff0c;我见过太多人一上来就扎进复杂的模型调参&#xff0c;却连干净、可靠、有明确物理意义的原始数据都拿不稳。这篇内容讲的不是“怎么用工具点几下”&#xff0c;而是带你…

作者头像 李华