Pandas使用combine_first未实现预期值替换问题求助
Pandas combine_first未按预期替换值的解决方案
问题重现
现有以下Pandas代码:
import pandas as pd df1 = pd.DataFrame({ 'Lat':('-10.1','-10.2','-10.3','-10.4','-10.5','-10.6'), 'Lon':('90.000','90.050','90.100','90.150','90.200','90.250'), 'Position':('-9999.999','-9999.999','-9999.999','-9999.999','-9999.999','-9999.999')}) df1 = df1.set_index(['Lat','Lon']) df2 = pd.DataFrame({ 'Lat':('-10.2','-10.5'), 'Lon':('90.050','90.200'), 'Position':('50','100') }) df2 = df2.set_index(['Lat','Lon']) output=df1.combine_first(df2).reset_index()
执行后得到结果:
Lat Lon Position 0 -10.1 90.000 -9999.999 1 -10.2 90.050 -9999.999 2 -10.3 90.100 -9999.999 3 -10.4 90.150 -9999.999 4 -10.5 90.200 -9999.999 5 -10.6 90.250 -9999.999
但期望输出为:
Lat Lon Position 0 -10.1 90.000 -9999.999 1 -10.2 90.050 50.0 2 -10.3 90.100 -9999.999 3 -10.4 90.150 -9999.999 4 -10.5 90.200 100.0 5 -10.6 90.250 -9999.999
原因分析
- combine_first逻辑限制:
combine_first仅会替换调用方(此处为df1)中的NaN缺失值,而df1的Position列值是字符串'-9999.999',不属于Pandas认定的缺失值,因此不会被df2的对应值替换。 - 数据类型不匹配:两个DataFrame的
Position列均为字符串类型,即便df2的值是数字字符串,也无法直接覆盖df1的占位符字符串。
解决方案
方法1:转换占位符为NaN后使用combine_first
先将df1中的'-9999.999'转为NaN,并将两列转为数值类型,再调用combine_first:
import pandas as pd df1 = pd.DataFrame({ 'Lat':('-10.1','-10.2','-10.3','-10.4','-10.5','-10.6'), 'Lon':('90.000','90.050','90.100','90.150','90.200','90.250'), 'Position':('-9999.999','-9999.999','-9999.999','-9999.999','-9999.999','-9999.999')}) df1 = df1.set_index(['Lat','Lon']) df2 = pd.DataFrame({ 'Lat':('-10.2','-10.5'), 'Lon':('90.050','90.200'), 'Position':('50','100') }) df2 = df2.set_index(['Lat','Lon']) # 将占位符转为NaN,并转换为数值类型 df1['Position'] = pd.to_numeric(df1['Position'], errors='coerce') df2['Position'] = pd.to_numeric(df2['Position'], errors='coerce') # 执行合并替换 output = df1.combine_first(df2).reset_index() print(output)
方法2:使用update直接覆盖对应值
update方法会直接用df2中的值覆盖df1对应索引位置的值,适合需要强制替换的场景:
import pandas as pd df1 = pd.DataFrame({ 'Lat':('-10.1','-10.2','-10.3','-10.4','-10.5','-10.6'), 'Lon':('90.000','90.050','90.100','90.150','90.200','90.250'), 'Position':('-9999.999','-9999.999','-9999.999','-9999.999','-9999.999','-9999.999')}) df1 = df1.set_index(['Lat','Lon']) df2 = pd.DataFrame({ 'Lat':('-10.2','-10.5'), 'Lon':('90.050','90.200'), 'Position':('50','100') }) df2 = df2.set_index(['Lat','Lon']) # 转换数值类型 df1['Position'] = pd.to_numeric(df1['Position'], errors='coerce') df2['Position'] = pd.to_numeric(df2['Position'], errors='coerce') # 用df2的值覆盖df1对应位置 df1.update(df2) output = df1.reset_index() print(output)
两种方法均可得到预期输出,可根据实际需求选择。
内容的提问来源于stack exchange,提问作者Azam
相关产品推荐
相关产品推荐

