循环绘制子图时pandas loc()筛选数据不生效的原因
问题根因
这个现象和loc()方法本身没有任何关系,完全是代码执行顺序和变量赋值逻辑错误导致的:
- 你把
d = df.loc[df["new_ID"] == unique_sample]写在了for循环的外部,这行代码执行时循环还没启动,此时unique_sample并没有进入循环迭代的赋值流程,只会保留这个变量在当前环境下最后一次被赋予的值(通常是你之前跑通版本代码时,循环最后一次取到的分组值,比如sample3)。也就是说d从赋值完成开始,就只存储了某一个固定分组的数据集,不会随着循环推进自动更新。 - 循环内每次调用
sns.histplot都传入这个固定不变的d作为数据源,哪怕每次切换了子图、修改了子图标题,画的始终是同一份数据,自然4张子图内容完全一致。
单独绘制单张图时
loc能正常工作,是因为单图场景下你会先手动给unique_sample指定一个明确的分组值,再执行筛选逻辑,执行顺序是对的;放到循环场景下,你把依赖循环迭代变量的筛选步骤放在循环外,逻辑自然出问题。
修正方案
如果想把数据筛选逻辑移出循环,有两种可行写法:
方案1:把筛选步骤放在循环内部
和你最初能跑通的版本逻辑一致,只是把布尔索引换成loc写法即可,loc本身在循环内完全可以正常工作:
unique_list = list(df["new_ID"].unique()) fig, axs = plt.subplots(int(len(unique_list) / 2) , 2) for unique_sample, ax in zip(unique_list, axs.flat): # 每次迭代到当前分组时,再筛选对应数据 d = df.loc[df["new_ID"] == unique_sample] sns.histplot(data=d, x="A", ax=ax) ax.set_title(unique_sample)
方案2:循环外提前存储全部分组数据
如果一定要把筛选逻辑放在循环外,可以提前用字典把每个分组对应的数据集存好,循环时直接按key取值即可:
unique_list = list(df["new_ID"].unique()) # 提前遍历所有分组,把筛选结果存在字典中 group_dict = {sample: df.loc[df["new_ID"] == sample] for sample in unique_list} fig, axs = plt.subplots(int(len(unique_list) / 2) , 2) for unique_sample, ax in zip(unique_list, axs.flat): sns.histplot(data=group_dict[unique_sample], x="A", ax=ax) ax.set_title(unique_sample)
内容的提问来源于stack exchange,提问作者Ardalan1
相关产品推荐
相关产品推荐

