Pandas函数中DataFrame赋值异常:两DataFrame被意外覆盖求助
问题根源:DataFrame的引用赋值陷阱
嗨,你遇到的问题完全是Python中可变对象的引用传递导致的——Pandas的DataFrame属于可变对象,当你执行:
Gen=Fisso Gen1=Fisso
这并不是创建两个新的DataFrame副本,而是让Gen和Gen1都指向内存中同一个Fisso实例。所以不管你后续修改Gen还是Gen1,本质上都是在修改同一个DataFrame,最后返回的两个结果自然完全一致。
至于你之前分两次调用函数结果正常,是因为每次调用时传入的Fisso是独立的实例,两次修改的是不同的对象,所以不会互相干扰。
解决方案:使用
.copy()创建独立副本 要解决这个问题,你需要显式创建DataFrame的副本,使用Pandas提供的.copy()方法,这样Gen和Gen1就会指向内存中两个完全独立的DataFrame实例,修改其中一个不会影响另一个:
修改你的代码开头部分:
def GeneraTabellaCovarianze(Fisso,Var): # 用.copy()创建独立副本,而不是引用赋值 Gen=Fisso.copy() Gen1=Fisso.copy() # 后续逻辑保持不变 if Var=="DifAtt": Pow1=Gen['ForzaDif'][a]*Gen['Dif'][a]/Gen['ForzaOff'][b]*Gen['Att'][b] #print(Gen['Squadra'][a],Pow1) Pow2=Gen['ForzaOff'][a]*Gen['Att'][a]/Gen['ForzaDif'][b]*Gen['Dif'][b] #print(Gen['Squadra'][a],Pow2) print(a,b,count) Gen.at[a,count]=Pow1 #difensivo Gen.at[b,count]=(1/Pow2) #difensivo Gen1.at[a,count]=Pow2 #offensivo Gen1.at[b,count]=(1/Pow1) #offensivo count=count+1 Gen=Gen.drop(['Squadra','Forza', 'Gen','Att','Dif','ForzaOff','ForzaDif','CostoPor'], axis=1) Gen1=Gen1.drop(['Squadra','Forza', 'Gen','Att','Dif','ForzaOff','ForzaDif','CostoPor'], axis=1) return(Gen,Cov,Gen1,Cov1) (Dif,CovDif,Att,CovAtt)=GeneraTabellaCovarianze(Sq,'DifAtt')
这里补充一点:.copy()默认是深拷贝,会复制DataFrame的所有数据和结构,完全隔离原对象;如果只需要浅拷贝(比如DataFrame里没有嵌套的可变对象),可以传入deep=False,但对于你的场景,默认的深拷贝是最安全的选择。
这样修改后,Gen和Gen1就会各自保留你赋予的不同值,返回结果就会符合你的预期啦!
内容的提问来源于stack exchange,提问作者Filippo Fedeli
相关产品推荐
相关产品推荐

