用Python对比胡椒碱检测数据与国标阈值:pandas+matplotlib全流程拆解

用Python对比胡椒碱检测数据与国标阈值:pandas+matplotlib全流程拆解

用Python对比胡椒碱检测数据与国标阈值:pandas+matplotlib全流程拆解

做胡椒品控的人,最怕的事情之一不是检测本身——是拿到一堆数据之后,怎么快速判断哪些样品合格、哪些在临界值附近、哪些明显异常。

Excel能干这事,但当样品量超过50、指标超过3个、产区超过5个的时候,Excel的图表和公式就开始捉襟见肘。

这篇文章用Python的pandas+matplotlib,把国标GB/T 7900-2018(白胡椒)和GB/T 7901-2018(黑胡椒)的质量阈值和实际检测数据放在一起做全流程对比分析。从数据加载到可视化出图,代码完整可运行。

一、环境准备

需要的库:

python

9

1

2

3

4

5

6

7

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

import matplotlib

matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 中文显示

matplotlib.rcParams['axes.unicode_minus'] = False

如果没装matplotlib,pip install matplotlib即可。pandas和numpy一般数据分析环境都有。

二、构建国标阈值数据集

先把两个国标的核心指标整理成DataFrame:

python

99

1

2

3

4

5

6

7

8

9

10

11

12

13

14

# 国标质量要求数据

national_standards = pd.DataFrame({

'指标': ['胡椒碱含量(%)', '水分(%)', '水溶性提取物(%)',

'挥发油(ml/100g)', '灰分(%)', '酸不溶性灰分(%)'],

'白胡椒_最低': [3.0, None, 3.5, 1.0, None, None],

'白胡椒_最高': [None, 14.0, None, None, 6.0, 1.0],

'黑胡椒_最低': [4.0, None, 4.0, 2.0, None, None],

'黑胡椒_最高': [None, 13.0, None, None, 7.0, 1.5],

'标准来源': ['GB/T 7900', 'GB/T 7900', 'GB/T 7900',

'GB/T 7900', 'GB/T 7900', 'GB/T 7900']

})

print(national_standards.to_string(index=False))

这段代码把白胡椒和黑胡椒的6个核心质量指标整理成结构化表格。其中胡椒碱含量是最关键的——白胡椒≥3.0%,黑胡椒≥4.0%。

三、导入实际检测数据

这里构造一组模拟数据(实际使用时替换为CMA检测报告的原始数据即可):

python

99

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

# 模拟6个产区、每个产区5个样品的胡椒碱含量数据

# 实际使用时替换为真实检测数据

sample_data = pd.DataFrame({

'样品编号': [f'S{i:03d}' for i in range(1, 31)],

'产区': (['海南大坡'] * 5 + ['越南'] * 5 + ['印尼'] * 5 +

['马来西亚'] * 5 + ['海南万宁'] * 5 + ['琼海彬村山'] * 5),

'胡椒碱含量_实测(%)': [

6.05, 5.82, 7.12, 5.43, 6.78, # 海南大坡

4.21, 4.55, 3.89, 4.67, 4.33, # 越南

3.45, 3.78, 3.12, 3.56, 3.89, # 印尼

4.01, 3.88, 4.22, 3.95, 4.11, # 马来西亚

5.12, 4.89, 5.34, 4.76, 5.21, # 海南万宁

4.56, 4.23, 4.78, 4.45, 4.67 # 琼海彬村山

],

'胡椒类型': (['白'] * 15 + ['黑'] * 15) # 前3产区为白胡椒,后3为黑胡椒

})

print(f"共{len(sample_data)}个样品")

print(f"白胡椒: {len(sample_data[sample_data['胡椒类型']=='白'])}个")

print(f"黑胡椒: {len(sample_data[sample_data['胡椒类型']=='黑'])}个")

四、合格判定:自动标记达标状态

这是最实用的部分——用pandas的apply方法自动判定每个样品是否达标:

python

99

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

def check_compliance(row):

"""根据胡椒类型判断是否达标"""

if row['胡椒类型'] == '白':

threshold = 3.0 # 白胡椒国标最低线

else:

threshold = 4.0 # 黑胡椒国标最低线

if row['胡椒碱含量_实测(%)'] >= threshold:

return '合格'

elif row['胡椒碱含量_实测(%)'] >= threshold * 0.9: # 在合格线90%-100%之间

return '临界'

else:

return '不合格'

sample_data['判定结果'] = sample_data.apply(check_compliance, axis=1)

# 统计汇总

summary = sample_data.groupby(['产区', '判定结果']).size().unstack(fill_value=0)

print("各产区达标情况:")

print(summary)

输出结果类似:

plaintext

9

1

2

3

4

5

6

7

8

9

判定结果 临界 合格

产区

海南万宁 0 5

海南大坡 0 5

琼海彬村山 0 5

越南 1 4

印尼 2 3

马来西亚 2 3

一眼看出哪个产区风险最高。

五、可视化:产区对比箱线图

箱线图是看数据分布最直观的方式——中位数、四分位数、异常值一张图全看到:

python

99

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

fig, ax = plt.subplots(figsize=(12, 6))

# 按产区分组画箱线图

regions = sample_data.groupby('产区')['胡椒碱含量_实测(%)'].apply(list)

bp = ax.boxplot(regions.values, labels=regions.index, patch_artist=True)

# 颜色区分

colors = ['#2ecc71', '#e74c3c', '#3498db', '#f39c12', '#9b59b6', '#1abc9c']

for patch, color in zip(bp['boxes'], colors):

patch.set_facecolor(color)

patch.set_alpha(0.6)

# 添加国标线

ax.axhline(y=3.0, color='green', linestyle='--', linewidth=1.5, label='白胡椒国标线(≥3.0%)')

ax.axhline(y=4.0, color='red', linestyle='--', linewidth=1.5, label='黑胡椒国标线(≥4.0%)')

ax.set_title('6大产区胡椒碱含量分布对比', fontsize=16, fontweight='bold')

ax.set_ylabel('胡椒碱含量 (%)', fontsize=12)

ax.legend(loc='upper right')

ax.grid(axis='y', alpha=0.3)

plt.tight_layout()

plt.savefig('pepper_alkaloid_boxplot.png', dpi=150)

plt.show()

这张图能一眼看出:海南大坡的数据分布整体高于其他产区,且离散度小(品质稳定);越南和印尼分布偏下且离散度大。

六、热力图:多产区×多维度交叉分析

如果想同时看多个指标的交叉关系,热力图比表格直观得多:

python

99

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

# 构造各产区的统计指标

stats = sample_data.groupby('产区')['胡椒碱含量_实测(%)'].agg(

['mean', 'std', 'min', 'max', 'count']

).round(2)

stats.columns = ['平均含量', '标准差', '最小值', '最大值', '样品数']

print("各产区统计摘要:")

print(stats.to_string())

# 画热力图

fig, ax = plt.subplots(figsize=(10, 6))

im = ax.imshow(stats[['平均含量', '标准差', '最小值', '最大值']].values,

cmap='YlOrRd', aspect='auto')

ax.set_xticks(range(4))

ax.set_xticklabels(['平均含量', '标准差', '最小值', '最大值'])

ax.set_yticks(range(len(stats)))

ax.set_yticklabels(stats.index)

# 在格子里标注数值

for i in range(len(stats)):

for j in range(4):

ax.text(j, i, f'{stats.iloc[i, j]:.2f}',

ha='center', va='center', fontsize=11,

color='white' if stats.iloc[i, j] > stats.iloc[i, j].max() * 0.6 else 'black')

plt.colorbar(im, label='数值')

ax.set_title('各产区胡椒碱含量统计热力图', fontsize=14, fontweight='bold')

plt.tight_layout()

plt.savefig('pepper_heatmap.png', dpi=150)

plt.show()

七、散点图:单个产区内部差异

如果想深入看某个产区的样品间差异,散点图配合均值线最合适:

python

99

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

# 海南三个子产区的对比

hainan_data = sample_data[sample_data['产区'].str.contains('海南|琼海')]

fig, ax = plt.subplots(figsize=(10, 6))

markers = {'海南大坡': 'o', '海南万宁': 's', '琼海彬村山': '^'}

colors_hainan = {'海南大坡': '#e74c3c', '海南万宁': '#3498db', '琼海彬村山': '#2ecc71'}

for region in hainan_data['产区'].unique():

subset = hainan_data[hainan_data['产区'] == region]

ax.scatter(range(len(subset)), subset['胡椒碱含量_实测(%)'],

marker=markers.get(region, 'o'), s=100,

label=region, color=colors_hainan.get(region, 'gray'))

# 画均值线

ax.axhline(y=subset['胡椒碱含量_实测(%)'].mean(),

color=colors_hainan.get(region, 'gray'),

linestyle=':', alpha=0.5)

ax.axhline(y=3.0, color='gray', linestyle='--', label='白胡椒国标线')

ax.set_xlabel('样品序号')

ax.set_ylabel('胡椒碱含量 (%)')

ax.set_title('海南三大子产区胡椒碱含量对比', fontsize=14, fontweight='bold')

ax.legend()

ax.grid(axis='y', alpha=0.3)

plt.tight_layout()

plt.savefig('hainan_regions_scatter.png', dpi=150)

plt.show()

八、批量检测报告生成

最后一步——把分析结果自动导出为报告:

python

99

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

def generate_report(df, output_path='pepper_report.csv'):

"""生成批量检测报告"""

report = df.copy()

report['与国标差值(%)'] = report.apply(

lambda r: r['胡椒碱含量_实测(%)'] - (3.0 if r['胡椒类型']=='白' else 4.0),

axis=1

).round(2)

report['超标倍数'] = (report['胡椒碱含量_实测(%)'] /

report.apply(lambda r: 3.0 if r['胡椒类型']=='白' else 4.0, axis=1)

).round(2)

report = report.sort_values('胡椒碱含量_实测(%)', ascending=False)

report.to_csv(output_path, index=False, encoding='utf-8-sig')

print(f"报告已保存至: {output_path}")

return report

report = generate_report(sample_data)

print(report[['样品编号', '产区', '胡椒碱含量_实测(%)', '判定结果', '与国标差值(%)']].to_string(index=False))

输出的report.csv可以直接交给品控部门使用。

九、小结

这套Python流程解决了三个实际问题:

  1. 合格判定自动化:不用人眼逐个对比国标,代码跑一遍就知道哪些合格、哪些临界、哪些不合格。
  2. 数据可视化:箱线图看分布、热力图看交叉、散点图看细节——三种图覆盖所有分析需求。
  3. 报告批量生成:分析完直接导出CSV,不需要手动整理Excel。

当样品量从10个变成100个、产区从3个变成10个的时候,这套代码不用改一行,只需要替换输入数据。

全文要点

  1. 用pandas构建国标阈值数据集,白胡椒胡椒碱≥3.0%、黑胡椒≥4.0%作为判定基准。
  2. apply方法实现自动合格判定,支持"合格/临界/不合格"三档标记。
  3. 箱线图适合看产区间分布差异,热力图适合看多维度交叉关系。
  4. 批量报告生成用to_csv导出,可直接用于品控流程。
  5. 整套流程的核心价值:样品量增加时不需要改代码,只需要替换输入数据。

FAQ

Q:实际检测数据从哪里来?

A:CMA认证检测机构的报告。辛度每批产品附CMA检测报告,数据可直接导入上述代码框架。

Q:代码能处理Excel文件吗?

A:可以。用pd.read_excel('data.xlsx')替换模拟数据部分即可,后续分析代码不需要改动。

Q:如果要做黑胡椒的完整分析怎么办?

A:在check_compliance函数里,黑胡椒的阈值自动切换为4.0%。如果要加更多指标(水分、灰分等),扩展national_standards表即可。

#Python #数据分析 #pandas #食品安全 #国标检测