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

如何以右侧第2个下划线为分隔符拆分Pandas DataFrame列?

问题描述

假设手里有这样的DataFrame df:

id          value_type_and_model_name
0    1                       actual_value
1    2             fitted_value_RUT_ARIMA
2    3       fitted_lower_value_RUT_ARIMA
3    4       fitted_upper_value_RUT_ARIMA
4    5          predicted_value_RUT_ARIMA
5    6    predicted_lower_value_RUT_ARIMA
6    7    predicted_upper_value_RUT_ARIMA
7    8                fitted_value_RUT_ES
8    9          fitted_lower_value_RUT_ES
9   10          fitted_upper_value_RUT_ES
10  11             predicted_value_RUT_ES
11  12       predicted_lower_value_RUT_ES
12  13       predicted_upper_value_RUT_ES
13  14           fitted_value_RUT_SARIMAX
14  15     fitted_lower_value_RUT_SARIMAX
15  16     fitted_upper_value_RUT_SARIMAX
16  17        predicted_value_RUT_SARIMAX
17  18  predicted_lower_value_RUT_SARIMAX
18  19  predicted_upper_value_RUT_SARIMAX

现在要把value_type_and_model_name列里的内容(除了actual_value那行),以右侧第2个下划线为分隔线,拆成value_type和model_name两列,最终要得到这样的结果:

id             value_type   model_name
0    1           actual_value          NaN
1    2           fitted_value    RUT_ARIMA
2    3     fitted_lower_value    RUT_ARIMA
3    4     fitted_upper_value    RUT_ARIMA
4    5        predicted_value    RUT_ARIMA
5    6  predicted_lower_value    RUT_ARIMA
6    7  predicted_upper_value    RUT_ARIMA
7    8           fitted_value        RUT_ES
8    9     fitted_lower_value        RUT_ES
9   10     fitted_upper_value        RUT_ES
10  11        predicted_value        RUT_ES
11  12  predicted_lower_value        RUT_ES
12  13  predicted_upper_value        RUT_ES
13  14           fitted_value  RUT_SARIMAX
14  15     fitted_lower_value  RUT_SARIMAX
15  16     fitted_upper_value  RUT_SARIMAX
16  17        predicted_value  RUT_SARIMAX
17  18  predicted_lower_value  RUT_SARIMAX
18  19  predicted_upper_value  RUT_SARIMAX

试了df['value_type_and_model_name'].str.rsplit('_', n=2, expand=True)没成功,该怎么实现?

解决方案

方法1:基于你原来的rsplit修改

你之前的代码用rsplit('_', n=2)会把字符串从右侧拆2次,比如fitted_value_RUT_ARIMA会被拆成fitted_value、RUT、ARIMA三列。我们只需要把后两列用下划线拼起来,就能得到目标的model_name:

# 先拆分得到三列临时数据
temp_cols = df['value_type_and_model_name'].str.rsplit('_', n=2, expand=True)

# 给value_type列赋值:如果是actual_value就保留原内容,否则取拆分后的第一列
df['value_type'] = df['value_type_and_model_name'].where(df['value_type_and_model_name'] == 'actual_value', temp_cols[0])

# 给model_name列赋值:如果是actual_value就设为NaN,否则把拆分后的后两列拼起来
df['model_name'] = temp_cols.apply(lambda row: '_'.join(row[1:]) if row[0] != 'actual_value' else None, axis=1)

# 不需要原列的话可以删掉
df.drop('value_type_and_model_name', axis=1, inplace=True)

方法2:用正则表达式(更简洁)

直接写正则匹配规则,一次性把需要的两部分抓出来:

# 正则规则:要么匹配actual_value,要么匹配到倒数第二个下划线前的内容(value_type),以及后面的部分(model_name)
pattern = r'^(actual_value)|(.*?)_([^_]+_[^_]+)$'

# 提取匹配结果
match_result = df['value_type_and_model_name'].str.extract(pattern)

# 赋值列:actual_value的行用第一组结果,其他用第二组;model_name取第三组
df['value_type'] = match_result[0].fillna(match_result[1])
df['model_name'] = match_result[2]

# 可选删除原列
df.drop('value_type_and_model_name', axis=1, inplace=True)

方法3:两次rsplit拆分

先从右侧拆1次,把最后一个下划线后面的内容拆出来,再对剩下的部分从右侧拆1次,就能得到分隔点:

# 第一次拆分:把最后一个下划线后面的内容(比如ARIMA)和前面的部分分开
first_split = df['value_type_and_model_name'].str.rsplit('_', n=1, expand=True)

# 对非actual_value的行,把前面的部分再从右侧拆1次,得到真正的value_type和中间的部分(比如RUT)
second_split = first_split[0].str.rsplit('_', n=1, expand=True)

# 赋值value_type列
df['value_type'] = df['value_type_and_model_name'].where(df['value_type_and_model_name'] == 'actual_value', second_split[0])

# 赋值model_name列:把中间部分和第一次拆分的后半部分拼起来
df['model_name'] = first_split.apply(lambda row: f"{second_split.loc[row.name, 1]}_{row[1]}" if row[0] != 'actual_value' else None, axis=1)

# 可选删除原列
df.drop('value_type_and_model_name', axis=1, inplace=True)

内容的提问来源于stack exchange,提问作者ah bon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 11:02:04