为什么存储for循环的运行结果仅能得到最后一个值?
代码问题定位
第一种实现的问题
- 循环中每次生成的
x是和daily行数完全等长的、针对单个pc21日期的比对结果(命中位置为1,其余为0),你直接把每次的x追加到空列表l中,最终l是3个独立Series组成的列表,既没有对这些比对结果做按行合并(只要任意一次比对命中就标记为1的逻辑),也没有把合并结果写回daily表,自然得不到预期的标记列。
第二种实现的问题
- 每次循环执行
daily['newcol'] = 比对结果时,都会全量覆盖newcol列的所有值,完全不会保留之前循环已经标记为1的位置,等三次循环跑完,newcol里只剩下最后一次比对(对应4月22日)的结果,自然没有前两个日期的标记,这也是你观察到“结果仅包含循环最后一个值”的核心原因。 - 你写的
daily['newcol'].append(daily['newcol'])逻辑完全不成立:Series.append的作用是把两个序列拼接成更长的序列,你每次拿当前的newcol和自己拼接,既达不到合并标记的效果,这个方法在新版pandas中也已经被弃用。
最优实现方案
不需要写循环,用pandas内置的isin方法就能高效完成判断,代码更简洁、运行速度也远高于逐次循环比对:
# 提取pc21的日期集合,利用集合的O(1)查找特性提升比对效率 pc_dates = set(pc21['Date']) # 逐行判断daily的日期是否在pc21的日期集合中,转成0/1标记 daily['is_pc_date'] = daily['Date'].isin(pc_dates).astype(int)
这种写法不管待匹配的日期是3个还是3000个,运行效率都不会有明显下降,是pandas中处理存在性判断的标准写法。
如果一定要用循环逻辑实现,需要修正“全量覆盖”的问题,只更新命中位置的标记值,而不是整列重写:
# 先初始化全为0的标记列 daily['newcol'] = 0 for _, row in pc21.iterrows(): # 只把命中当前pc21日期的行的标记值更新为1,不会覆盖之前的标记 daily.loc[daily['Date'].eq(row['Date']), 'newcol'] = 1
内容的提问来源于stack exchange,提问作者Rollo99
相关产品推荐
相关产品推荐

