You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pandas如何用.loc实现单行值覆盖多行?对比iloc赋值差异

pandas使用.loc赋值单行值到多行时出现NaN的解决方法

问题复现

需求为将DataFrame中某一行的多个列值,批量赋值给其他若干行。使用.iloc按位置赋值可正常实现,但使用带筛选条件的.loc赋值时,目标位置全部返回NaN,复现代码如下:

  1. 构造测试数据集
import pandas as pd
df = pd.DataFrame(dict(A = [1,2,0,0],B=[0,0,0,10],C=[3,4,5,6]))
df.index = ['a','b','c','d']
  1. 使用.loc执行赋值操作(两种写法均失败)
# 条件筛选赋值
df.loc[df['A']>0, ['B','C']] = df.loc['d',['B','C']]
# 指定索引名赋值
df.loc[['a','b'], ['B','C']] = df.loc['d',['B','C']]

运行后a、b行的B、C列全部为NaN,结果如下:

A       B       C
a   1.0     NaN     NaN
b   2.0     NaN     NaN
c   0.0     0.0     5.0
d   0.0     10.0    6.0
  1. 使用.iloc按位置赋值可得到预期结果
df.iloc[0:2,1:3] = df.iloc[3,1:3]

运行结果符合预期:

A   B   C
a   1   10  6
b   2   10  6
c   0   0   5
d   0   10  6

根本原因

问题出在pandas默认的索引对齐机制:

  • 右侧df.loc['d',['B','C']]返回的是一个Series,它的行标签是d,列方向索引是['B','C'];当把它赋值给左侧行标签为a、b的切片时,pandas会先按行标签做匹配,a、b和d完全匹配不上,匹配不到的位置就会自动填充NaN。
  • .iloc是纯按位置操作,完全忽略索引标签,所以赋值时直接按位置把值填进去,不会出现对齐失败的问题。

解决方案

不需要把布尔筛选条件转换成行号改用iloc,只要把右侧待赋值的序列转成不带索引的数组/列表,跳过索引对齐逻辑,就可以直接用.loc实现需求:

# 方法1:使用.values获取numpy数组,是最常用的写法
df.loc[df['A']>0, ['B','C']] = df.loc['d',['B','C']].values

# 方法2:转成原生list,效果一致
df.loc[['a','b'], ['B','C']] = df.loc['d',['B','C']].tolist()

注意:如果赋值的右侧是多行多列的DataFrame切片,只要保证左右两侧切片的形状完全一致,加.values转成数组后同样可以正常赋值,不会出现NaN问题。

内容的提问来源于stack exchange,提问作者Peter Lustig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 12:36:17