如何用Pandas透视Sensor列生成箱线图所需格式的DataFrame
长格式DataFrame转箱线图专用宽格式方案
可复现样本数据
基于你提供的字段结构生成模拟数据,方便测试验证:
import pandas as pd import numpy as np np.random.seed(42) df = pd.DataFrame({ 'experiment': np.repeat(['exp1', 'exp2'], 25), 'round': np.tile(np.arange(1,6), 10), 'kali': np.random.randint(1, 10, 50), 'pH': np.tile([4.0, 5.0, 6.0, 7.0, 8.0], 10), 'sensor': np.tile([f'sensor{i}' for i in range(1,6)], 10), 'measurement': np.random.normal(50, 10, 50) })
核心转换代码
使用pivot_table(比pivot更适配重复行场景)完成转换,直接得到无多级索引的宽格式:
# 转换为宽格式,保留所有非sensor字段+pH分组列 wide_df = df.pivot_table( index=['experiment', 'round', 'kali', 'pH'], # 需保留的非sensor列 columns='sensor', values='measurement', aggfunc='first' # 若同一索引组合有重复值,可替换为'mean'/'median'做聚合 ).reset_index() # 清理列名,移除自动生成的多级索引 wide_df.columns = wide_df.columns.droplevel(0) wide_df = wide_df.rename(columns={'': 'experiment'}).rename_axis(None, axis=1)
转换后结果(符合期望格式)
转换后的数据结构如下(截取前3行):
| experiment | round | kali | pH | sensor1 | sensor2 | sensor3 | sensor4 | sensor5 |
|---|---|---|---|---|---|---|---|---|
| exp1 | 1 | 7 | 4.0 | 54.9671 | 48.6173 | 56.4769 | 47.3846 | 52.7508 |
| exp1 | 2 | 4 | 5.0 | 49.5072 | 54.5369 | 48.6173 | 56.4769 | 47.3846 |
| exp1 | 3 | 1 | 6.0 | 56.4769 | 47.3846 | 52.7508 | 54.9671 | 48.6173 |
箱线图绘制
基于转换后的宽格式,用seaborn直接绘制以pH为分组的箱线图:
import seaborn as sns import matplotlib.pyplot as plt # 单传感器箱线图 sns.boxplot(data=wide_df, x='pH', y='sensor1') plt.title('Sensor 1 Measurements by pH') plt.show() # 多传感器子图批量绘制 fig, axes = plt.subplots(2, 3, figsize=(16, 10)) sensor_cols = [col for col in wide_df.columns if 'sensor' in col] for ax, sensor in zip(axes.flat, sensor_cols): sns.boxplot(data=wide_df, x='pH', y=sensor, ax=ax) ax.set_title(f'{sensor} vs pH') plt.tight_layout() plt.show()
错误排查(针对你之前的多级索引问题)
你之前出现多级索引的常见原因:
- 使用
pivot时未指定足够的索引列,导致重复行触发自动多级索引 - 转换后未执行
reset_index()将索引字段转回普通列 - 未清理
pivot_table生成的列层级(即未用droplevel(0)移除列的顶层名称)
如果仅需保留pH作为唯一分组依据(忽略experiment/round/kali),可简化转换代码:
wide_df_simple = df.pivot_table( index='pH', columns='sensor', values='measurement', aggfunc='median' # 用中位数聚合同一pH下的所有测量值 ).reset_index().rename_axis(None, axis=1)
内容的提问来源于stack exchange,提问作者Shannas M
相关产品推荐
相关产品推荐

