使用iterrows遍历Pandas DataFrame时,如何绘制每行光谱数据的直方图?
用Pandas DataFrame单行数据绘制直方图的实用方案
嘿,我刚好折腾过类似的光谱数据可视化需求!你用iterrows()遍历的思路没问题,但其实还有更高效的实现方式,下面一步步给你拆解:
1. 基础实现:结合iterrows()与Matplotlib
既然你已经在使用iterrows(),那咱们先从这个思路落地。核心就是遍历每行时,把当前行的数值提取出来,传给matplotlib.pyplot.hist()即可。注意要给每个直方图加标题(比如用行索引或样本名称),如果要画多个图,记得单独创建画布避免重叠。
示例代码:
import pandas as pd import matplotlib.pyplot as plt import numpy as np # 构造模拟光谱数据:5行(样本),100列(波长/通道) np.random.seed(42) df = pd.DataFrame( np.random.normal(loc=100, scale=15, size=(5, 100)), index=[f"样本{i+1}" for i in range(5)] ) # 用iterrows遍历每行画直方图 for idx, row in df.iterrows(): plt.figure(figsize=(8, 4)) plt.hist(row.values, bins=20, edgecolor='black', alpha=0.7) plt.title(f"光谱数据直方图 - {idx}") plt.xlabel("信号强度") plt.ylabel("频数") plt.grid(axis='y', linestyle='--', alpha=0.7) plt.show()
2. 更高效的方案:使用df.apply()
iterrows()在处理大数据量时性能一般,因为它会把每行转成Series对象。用df.apply()直接对每行操作会更高效,代码也更简洁:
# 定义通用绘图函数 def plot_row_hist(row): plt.figure(figsize=(8, 4)) plt.hist(row, bins=20, edgecolor='black', alpha=0.7) plt.title(f"光谱数据直方图 - {row.name}") plt.xlabel("信号强度") plt.ylabel("频数") plt.grid(axis='y', linestyle='--', alpha=0.7) plt.show() # 对每行应用绘图函数 df.apply(plot_row_hist, axis=1)
3. 进阶:将所有直方图排列成子图网格
如果你的样本数很多,一个个单独显示图会很麻烦,可以把所有直方图排列成子图网格,方便对比不同光谱的分布特征:
rows = df.shape[0] cols = 2 # 每行显示2个图 fig, axes = plt.subplots( nrows=(rows + cols - 1)//cols, ncols=cols, figsize=(16, 10) ) axes = axes.flatten() # 把二维轴数组转成一维,方便遍历 for idx, (row_name, row_data) in enumerate(df.iterrows()): axes[idx].hist(row_data, bins=20, edgecolor='black', alpha=0.7) axes[idx].set_title(f"{row_name}") axes[idx].set_xlabel("信号强度") axes[idx].set_ylabel("频数") axes[idx].grid(axis='y', linestyle='--', alpha=0.7) # 隐藏多余的子图(如果样本数不是cols的整数倍) for i in range(idx+1, len(axes)): axes[i].axis('off') plt.tight_layout() # 自动调整子图间距 plt.show()
内容的提问来源于stack exchange,提问作者sw14928
相关产品推荐
相关产品推荐

