使用pandas loc赋值时列B变为NaN的问题及修复方法
解决pandas loc多列赋值时列B出现NaN的问题
你的赋值写法df.loc[((df['Active'] =='N') & (df['A'].isna())), ['A', 'B']] = [99, df['C']]存在索引对齐隐患。当给多列批量赋值时,右侧的df['C']是全量Series,若后续数据中筛选行的索引与df['C']无法完全对齐,或被pandas广播机制误解,就会导致未预期的NaN值。
以下是两种可靠的修正方案:
方法一:分开赋值(直观不易出错)
先定义筛选条件,再分别给A、B列赋值,彻底避免多列赋值的对齐问题:
import pandas as pd import numpy as np data = { 'Name' : ['Abby', 'Bob', 'Chris'], 'Active' : ['Y', 'Y', 'N'], 'A' : [89, 92, np.nan], 'B' : ['eye', 'hand', np.nan], 'C' : ['right', 'left', 'right'] } df = pd.DataFrame(data) # 定义筛选掩码 mask = (df['Active'] == 'N') & (df['A'].isna()) # 单独给A列赋值 df.loc[mask, 'A'] = 99 # 给符合条件的B列赋值对应行的C值 df.loc[mask, 'B'] = df.loc[mask, 'C'] print(df)
执行后得到期望结果:
| Name | Active | A | B | C |
|---|---|---|---|---|
| Abby | Y | 89.0 | eye | right |
| Bob | Y | 92.0 | hand | left |
| Chris | N | 99.0 | right | right |
方法二:构造匹配形状的赋值对象
若想在一行代码中完成赋值,可构造与左侧选中区域形状完全匹配的二维数据,确保pandas正确识别赋值逻辑:
import pandas as pd import numpy as np data = { 'Name' : ['Abby', 'Bob', 'Chris'], 'Active' : ['Y', 'Y', 'N'], 'A' : [89, 92, np.nan], 'B' : ['eye', 'hand', np.nan], 'C' : ['right', 'left', 'right'] } df = pd.DataFrame(data) mask = (df['Active'] == 'N') & (df['A'].isna()) # 构造与选中行数量匹配的二维数组 assign_values = np.column_stack((np.full(mask.sum(), 99), df.loc[mask, 'C'])) df.loc[mask, ['A', 'B']] = assign_values print(df)
这种方法通过np.column_stack将标量99广播为对应长度的数组,再与筛选后的C列值合并,保证赋值结构与左侧完全匹配,从根源避免对齐错误。
内容的提问来源于stack exchange,提问作者Shane S
相关产品推荐
相关产品推荐

