Pandas DataFrame深拷贝后通过列索引修改列名导致原DataFrame列名变更的原因及解决方案
问题解析:深拷贝后修改列名影响原DataFrame的原因与解决办法
嘿,这个问题踩中了Pandas深拷贝里一个容易忽略的细节,我来给你讲清楚:
为什么修改df2的列名会影响df1?
你用df1.copy()的时候,默认是开启深拷贝(deep=True),按道理数据和结构都应该和原DataFrame完全独立,但这里的关键在于Pandas的列名是用不可变的Index对象存储的。
当你通过df2.columns.values去访问列名时,得到的是底层的numpy数组引用——而深拷贝DataFrame时,这个底层数组并没有被完整复制,df1和df2的列名底层其实共享了同一块内存空间。你直接修改df2.columns.values[1],相当于直接操作了这块共享内存里的值,自然会同步影响到df1的列名。
简单说:你绕过了Pandas的Index不可变机制,直接修改了共享的底层数组,所以原DataFrame跟着变了。
如何避免这个问题?
要解决这个问题,核心是先给列名做一份独立的副本,修改副本后再赋值回df2的列名,这样就不会和原DataFrame共享内存了。给你两种实用的方法:
方法1:复制numpy数组后修改
import pandas as pd df1 = pd.DataFrame({'col1':[1,2,3,4],'col2':[2,3,4,3],'col3':[4,3,1,5]}) df2 = df1.copy() # 先复制列名的numpy数组,得到独立副本 new_cols = df2.columns.values.copy() # 修改指定索引的列名 new_cols[1] = 'new_col_name' # 将修改后的数组赋值回df2的列名 df2.columns = new_cols
方法2:转换成列表后修改(更直观)
import pandas as pd df1 = pd.DataFrame({'col1':[1,2,3,4],'col2':[2,3,4,3],'col3':[4,3,1,5]}) df2 = df1.copy() # 把列名转换为列表(自动创建副本) cols_list = list(df2.columns) # 修改指定索引的列名 cols_list[1] = 'new_col_name' # 将修改后的列表赋值回df2的列名 df2.columns = cols_list
这两种方法都会创建一个独立于原DataFrame的列名副本,修改后赋值时会生成全新的Index对象,彻底和df1的列名解耦,这样就不会影响原DataFrame了。
内容的提问来源于stack exchange,提问作者Pubudu
相关产品推荐
相关产品推荐

