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

Pandas按条件拆分列赋值失败:COL1/COL2全为NaN问题求助

Pandas 按条件拆分列赋值失效问题解决

问题场景

需要对DataFrame中Class列以TEST开头的行,将Values列按/拆分后分别存入新增的COL1和COL2列,其余行保持NaN。但执行代码后COL1和COL2全为NaN;直接操作筛选出的子集也无法修改原DataFrame:

示例代码

import pandas as pd

sample_data = {
    'Class': ['TEST', 'NOT TEST', 'TEST 123', 'SOMETHING ELSE', 'TEST'],
    'Values': ['1.3 / 4.5', '1.5', '0.7 / 5.2', '123', '1.5 / 4.0']
}

df = pd.DataFrame(sample_data)
mask = df['Class'].str.startswith('TEST')
# 期望的操作
df.loc[mask, ['COL1', 'COL2']] = df.loc[mask, 'Values'].str.split(' / ', expand=True)

df.head()  # COL1、COL2全为NaN

子集操作无效的情况

df_subset = df[mask]
df_subset[['COL1', 'COL2']] = df_subset['Values'].str.split(' / ', expand=True)
df.head()  # 原DataFrame无变化,但df_subset已正确赋值

失效原因分析

  1. 直接赋值全NaN的原因:
    str.split(expand=True)返回的临时DataFrame列名为0和1,而目标列是COL1和COL2,Pandas赋值时会严格对齐列名,因列名不匹配导致赋值失败,最终COL1和COL2保持初始全NaN状态。

  2. 子集操作无效的原因:
    df[mask]属于布尔索引,返回的是原DataFrame的副本而非视图,对副本的修改不会同步到原DataFrame中,这也是Pandas常见SettingWithCopyWarning的触发场景。

解决方案

方案1:对齐列名后赋值

先将拆分结果的列名修改为目标列名,再通过loc赋值:

import pandas as pd

sample_data = {
    'Class': ['TEST', 'NOT TEST', 'TEST 123', 'SOMETHING ELSE', 'TEST'],
    'Values': ['1.3 / 4.5', '1.5', '0.7 / 5.2', '123', '1.5 / 4.0']
}

df = pd.DataFrame(sample_data)
mask = df['Class'].str.startswith('TEST')

# 拆分并修改列名
split_df = df.loc[mask, 'Values'].str.split(' / ', expand=True).rename(columns={0: 'COL1', 1: 'COL2'})
# 赋值到原DataFrame
df.loc[mask, ['COL1', 'COL2']] = split_df

print(df.head())

方案2:直接使用值数组赋值

跳过列名对齐,直接提取拆分结果的数值数组进行赋值:

import pandas as pd

sample_data = {
    'Class': ['TEST', 'NOT TEST', 'TEST 123', 'SOMETHING ELSE', 'TEST'],
    'Values': ['1.3 / 4.5', '1.5', '0.7 / 5.2', '123', '1.5 / 4.0']
}

df = pd.DataFrame(sample_data)
mask = df['Class'].str.startswith('TEST')

# 初始化COL1、COL2为NaN
df[['COL1', 'COL2']] = pd.NA
# 提取拆分结果的数值数组赋值
df.loc[mask, ['COL1', 'COL2']] = df.loc[mask, 'Values'].str.split(' / ', expand=True).values

print(df.head())

方案3:避免操作副本,直接修改原DataFrame

通过loc直接定位原DataFrame的行进行修改,而非赋值给新变量:

import pandas as pd

sample_data = {
    'Class': ['TEST', 'NOT TEST', 'TEST 123', 'SOMETHING ELSE', 'TEST'],
    'Values': ['1.3 / 4.5', '1.5', '0.7 / 5.2', '123', '1.5 / 4.0']
}

df = pd.DataFrame(sample_data)
mask = df['Class'].str.startswith('TEST')

# 直接通过loc修改原DataFrame的子集
df.loc[mask, ['COL1', 'COL2']] = df.loc[mask, 'Values'].str.split(' / ', expand=True).values

print(df.head())

内容的提问来源于stack exchange,提问作者Russell Hirsch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 02:58:26