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

使用Pandas的loc与apply更新列时遇NaN或形状不匹配问题求助

Pandas按条件更新多列的返回值类型问题

问题场景

测试DataFrame df_test:

col1    col2    col3    col4
0   A       1       1       2
1   B       2       1       2
2   A       3       1       2
3   B       4       1       2

尝试通过loc结合apply更新col1=='A'对应的col3和col4列,执行代码:

df_test.loc[df_test['col1']=='A', ['col3', 'col4']] = df_test[df_test['col1']=='A'].apply(lambda row: pd.Series([10,20]), axis=1)

结果col3、col4变为NaN;若将返回值替换为np.array([10,20])或[10,20],则触发报错:

ValueError: shape mismatch: value array of shape (2,2) could not be broadcast to indexing result of shape (2,)

期望得到的最终结果:

col1    col2    col3    col4
0   A       1       10      20
1   B       2       1       2
2   A       3       10      20
3   B       4       1       2

核心原因

问题本质是赋值时的对齐匹配失败:

  • 返回无索引的pd.Series时,生成的临时结果列名为默认的0、1,与目标列col3、col4不匹配,Pandas无法对齐,导致赋值后变为NaN。
  • 返回列表/数组时,apply会生成一个元素为列表/数组的Series(形状(2,)),而左侧loc选中的是(2,2)的DataFrame,形状不匹配引发广播错误。

解决方案

方法1:给apply返回的Series指定目标列名

让返回的Series索引与目标列名一致,确保列对齐:

mask = df_test['col1'] == 'A'
df_test.loc[mask, ['col3', 'col4']] = df_test[mask].apply(
    lambda row: pd.Series([10, 20], index=['col3', 'col4']),
    axis=1
)

方法2:跳过apply直接赋值(最优方案)

如果不需要基于行内数据计算,直接给匹配行的目标列赋值固定值,Pandas会自动广播到所有符合条件的行:

df_test.loc[df_test['col1'] == 'A', ['col3', 'col4']] = [10, 20]

方法3:将apply返回的列表/数组转为二维数组

若必须用apply(比如需基于行数据动态计算值),可将返回结果转为二维numpy数组,匹配左侧选区的形状:

mask = df_test['col1'] == 'A'
update_vals = np.array(df_test[mask].apply(lambda row: [10,20], axis=1).tolist())
df_test.loc[mask, ['col3', 'col4']] = update_vals

以上三种方法都能实现预期的更新效果。

内容的提问来源于stack exchange,提问作者Pedro Cruz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:45:40