Pandas DataFrame子框架赋值出现NaN的原因及解决方法
Pandas赋值出现NaN的问题分析与修复
问题复现
执行以下代码:
import pandas as pd df1 = pd.DataFrame({'1':[1,2,3,4,5,6], '2':[10,20,30,40,50,60],'3': [100,200,300,400,500,600]}) df2 = pd.DataFrame({'1':[22,22], '2':[22,22], '3':[22,22]}) df1.loc[[0,1],['2','3']] = df2.loc[[0,1],['1','2']]
实际得到的df1:
1 2 3 0 1.0 22.0 NaN 1 2.0 22.0 NaN 2 3.0 30.0 300.0 3 4.0 40.0 400.0 4 5.0 50.0 500.0 5 6.0 60.0 600.0
预期的df1:
1 2 3 0 1.0 22.0 22.0 1 2.0 22.0 22.0 2 3.0 30.0 300.0 3 4.0 40.0 400.0 4 5.0 50.0 500.0 5 6.0 60.0 600.0
原因分析
pandas中使用.loc赋值时,按列名匹配而非位置匹配:
- 右侧
df2.loc[[0,1],['1','2']]返回的是列名为'1'和'2'的DataFrame:1 2
0 22 22
1 22 22
- 赋值给左侧`df1.loc[[0,1],['2','3']]`时,只有列名`'2'`能在两侧匹配,对应位置被赋值为22;右侧的`'1'`列在左侧目标列中不存在,无法匹配,对应位置被填充为`NaN`。 ## 修复方案 ### 方案1:提取值数组(按位置赋值) 通过`.values`或`.to_numpy()`提取右侧数据的数值数组,忽略列名直接按位置赋值: ```python import pandas as pd df1 = pd.DataFrame({'1':[1,2,3,4,5,6], '2':[10,20,30,40,50,60],'3': [100,200,300,400,500,600]}) df2 = pd.DataFrame({'1':[22,22], '2':[22,22], '3':[22,22]}) df1.loc[[0,1],['2','3']] = df2.loc[[0,1],['1','2']].values
方案2:重命名右侧列名匹配目标列
修改右侧提取的DataFrame列名,使其与左侧目标列一致后再赋值:
import pandas as pd df1 = pd.DataFrame({'1':[1,2,3,4,5,6], '2':[10,20,30,40,50,60],'3': [100,200,300,400,500,600]}) df2 = pd.DataFrame({'1':[22,22], '2':[22,22], '3':[22,22]}) df1.loc[[0,1],['2','3']] = df2.loc[[0,1],['1','2']].rename(columns={'1':'2', '2':'3'})
方案3:使用.iloc按位置索引赋值
.iloc基于位置索引,直接按行和列的位置匹配赋值:
import pandas as pd df1 = pd.DataFrame({'1':[1,2,3,4,5,6], '2':[10,20,30,40,50,60],'3': [100,200,300,400,500,600]}) df2 = pd.DataFrame({'1':[22,22], '2':[22,22], '3':[22,22]}) # df1的[0,1]行、[1,2]列(对应原列'2','3');df2的[0,1]行、[0,1]列(对应原列'1','2') df1.iloc[[0,1],[1,2]] = df2.iloc[[0,1],[0,1]]
内容的提问来源于stack exchange,提问作者edamondo
相关产品推荐
相关产品推荐

