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

使用.loc在索引不同但长度相等的Series间赋值的问题

解决Series赋值时的索引匹配问题

这个问题的核心是pandas在赋值时会严格按索引对齐,而不是按你选中行的顺序来赋值。你选中的df.name == 'a'的行索引是[0,2],但vals_a的索引是[0,1]——pandas只会把vals_a中索引0的值给到df的0行,索引1的值找不到df中对应索引的行(df的1行不是name='a'),所以df的2行就只能填充NaN;同理vals_b的索引1对应df的1行,所以df的1行得到54,3行因为没有对应索引的值变成NaN。

下面给你几种可行的解决方案,适配不同的场景:

方案1:直接按顺序赋值(忽略索引)

如果你的vals_a和vals_b的顺序和df中筛选出的行顺序完全一致,最简单的方法是取Series的values属性(这会把它转换成numpy数组,不携带索引信息),这样pandas就会按顺序把值赋给筛选出的行:

import pandas as pd

df = pd.DataFrame({'name': ['a', 'b', 'a', 'b'], 
                   'num': [1, 1, 2, 2], 
                   'val': None})
vals_a = pd.Series([21,32])
vals_b = pd.Series([43,54])

df.loc[df.name == 'a', 'vals'] = vals_a.values
df.loc[df.name == 'b', 'vals'] = vals_b.values

执行后就能得到你想要的结果:

name  num   val  vals
0    a    1  None  21.0
1    b    1  None  43.0
2    a    2  None  32.0
3    b    2  None  54.0

方案2:通过关联键映射(更稳妥,适合复杂场景)

如果实际场景中vals_a/vals_b的顺序不一定和筛选行的顺序对应,但它们和num列是一一对应的(比如num=1对应第一个值,num=2对应第二个值),推荐用映射或合并的方式,避免索引带来的问题:

子方案2.1:用字典映射+apply

先把name、num和vals的对应关系整理成字典,再通过apply逐行匹配:

# 构建name -> (num: vals)的映射
vals_mapping = {
    'a': {1:21, 2:32},
    'b': {1:43, 2:54}
}

df['vals'] = df.apply(lambda row: vals_mapping[row['name']][row['num']], axis=1)

子方案2.2:合并小DataFrame

如果你的vals来自另一个DataFrame的切片,更清晰的方式是把vals整理成带关联键(name和num)的小DataFrame,再和原df合并:

# 模拟从其他DataFrame切片得到的vals数据
vals_df = pd.DataFrame({
    'name': ['a','a','b','b'],
    'num': [1,2,1,2],
    'vals': [21,32,43,54]
})

# 按name和num合并,保留原df的所有行
df = df.merge(vals_df, on=['name','num'], how='left')

这种方法的优势是逻辑清晰,不容易出错,尤其适合数据量较大或关联条件复杂的场景。


内容的提问来源于stack exchange,提问作者Cilantro Ditrek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:22:23