DataFrame存入列表后原地修改失效,合并结果不符预期求助
问题根源与解决办法
嗨,我来帮你拆解这个问题的核心原因,以及怎么解决它~
为什么全空列还存在?
问题根本不是列表创建了副本,而是你在循环里的操作没有真正修改原始的DataFrame a和b,具体来说:
- pandas的
dropna(axis=1, how='all')默认返回一个新的DataFrame副本,而不是直接修改原对象。 - 你在循环里写
item = item.dropna(...),只是把循环变量item的指向改成了这个新副本,但原来的a、b,还有列表里存储的原始DataFrame对象,完全没被改动。 - 所以当你后续执行
pd.merge(a, b, ...)时,用的还是没处理过的原始a和b,那些全空列自然还在,合并后就变成了(5,4)的shape。
你可以试试在循环结束后打印a.shape和b.shape,会发现它们还是(5,2),这就直接验证了原对象根本没被修改。
怎么修改才能达到预期效果?
有两种靠谱的方式:
方式一:用inplace=True原地修改
直接在dropna里加上inplace=True参数,这样会直接修改原DataFrame对象,不需要重新赋值:
for item in lis: item.dropna(axis=1, how='all', inplace=True) print(item.shape) # 依然是(5,1)
循环结束后,a和b就已经是删除了全空列的版本,再执行合并就能得到(5,2)的结果。
方式二:重新赋值替换原始对象(更推荐)
很多开发者不推荐用inplace=True(容易引发不易察觉的副作用),可以生成处理后的副本,再替换掉原来的a和b:
# 生成处理后的DataFrame列表 lis = [a.dropna(axis=1, how='all'), b.dropna(axis=1, how='all')] # 把处理后的结果重新赋值给a和b a, b = lis
之后再执行合并操作,就能得到你预期的(5,2)的shape了。
内容的提问来源于stack exchange,提问作者Moshee
相关产品推荐
相关产品推荐

