| name | numeric-extraction-and-distribution-analysis |
| description | 从带单位的字符串列中提取数值并清洗,生成包含直方图、饼图、条形图和累积分布图的多维度综合分布可视化图表,用于展示数据的集中趋势与分布特征。 |
Numeric_Extraction_and_Distribution_Analysis
Skill Steps
Step1 从原始数据中提取目标列,清理无效和空值数据,并安全地将带单位的字符串转换为数值类型
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
item_col = '项目名称'
value_col = '带单位的数值'
numeric_col = '提取数值'
unit_str = 'g'
def extract_numeric_value(val_str):
"""从带单位的字符串中提取数值"""
if pd.isna(val_str):
return None
try:
return float(str(val_str).replace(unit_str, '').strip())
except ValueError:
return None
df_clean = df.dropna(subset=[item_col, value_col]).copy()
df_clean = df_clean[df_clean[item_col] != '...']
df_clean[numeric_col] = df_clean[value_col].apply(extract_numeric_value)
df_clean = df_clean.dropna(subset=[numeric_col])
Step2 创建基础分布直方图,并添加平均值和中位数的参考线以展示数据的集中趋势
plt.figure(figsize=(12, 8))
plt.hist(df_clean[numeric_col], bins=10, alpha=0.7, color='skyblue', edgecolor='black')
mean_val = df_clean[numeric_col].mean()
median_val = df_clean[numeric_col].median()
plt.axvline(mean_val, color='red', linestyle='--', linewidth=2, label=f'平均值: {mean_val:.2f}')
plt.axvline(median_val, color='green', linestyle='--', linewidth=2, label=f'中位数: {median_val:.2f}')
plt.xlabel(f'{numeric_col}', fontsize=12)
plt.ylabel('频数', fontsize=12)
plt.title(f'{numeric_col}分布直方图', fontsize=14, fontweight='bold')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
Step3 生成包含直方图、饼图、条形图和累积分布图的综合分析面板,全面展示数值的分布特征并保存高分辨率图片
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(16, 12))
ax1.hist(df_clean[numeric_col], bins=8, alpha=0.7, color='lightblue', edgecolor='black', rwidth=0.8)
ax1.set_xlabel(f'{numeric_col}', fontsize=12)
ax1.set_ylabel('频数', fontsize=12)
ax1.set_title(f'{numeric_col}分布直方图', fontsize=14, fontweight='bold')
ax1.grid(True, alpha=0.3)
val_counts = df_clean[numeric_col].value_counts().sort_index()
colors = plt.cm.Set3(np.linspace(0, 1, len(val_counts)))
ax2.pie(val_counts.values, labels=[f'{x}' for x in val_counts.index], autopct='%1.1f%%', colors=colors, startangle=90)
ax2.set_title(f'{numeric_col}占比分布', fontsize=14, fontweight='bold')
val_counts.plot(kind='bar', ax=ax3, color='lightcoral', alpha=0.8)
ax3.set_xlabel(f'{numeric_col}', fontsize=12)
ax3.set_ylabel('数量', fontsize=12)
ax3.set_title(f'各{numeric_col}对应的数量', fontsize=14, fontweight='bold')
ax3.tick_params(axis='x', rotation=45)
ax3.grid(True, alpha=0.3)
sorted_values = np.sort(df_clean[numeric_col])
cumulative_freq = np.arange(1, len(sorted_values) + 1) / len(sorted_values) * 100
ax4.plot(sorted_values, cumulative_freq, marker='o', linewidth=2, markersize=6, color='darkgreen')
ax4.set_xlabel(f'{numeric_col}', fontsize=12)
ax4.set_ylabel('累积百分比 (%)', fontsize=12)
ax4.set_title(f'{numeric_col}累积分布', fontsize=14, fontweight='bold')
ax4.grid(True, alpha=0.3)
plt.tight_layout()
output_path = 'distribution_dashboard.png'
plt.savefig(output_path, dpi=300, bbox_inches='tight')
plt.show()