使用右侧的第 N 个下划线作为分隔符将一列拆分为两列

Use the Nth underscore from the right as the separator to split a column into two columns

提问人:ah bon 提问时间:11/14/2023 最后编辑:ah bon 更新时间:11/15/2023 访问量:40

问:

假设我有一个数据帧,如下所示: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'value_typemodel_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        UT_ES
8    9     fitted_lower_value        UT_ES
9   10     fitted_upper_value        UT_ES
10  11        predicted_value        UT_ES
11  12  predicted_lower_value        UT_ES
12  13  predicted_upper_value        UT_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)

python-3.x pandas 数据帧 拆分

评论


答:

2赞 mozway 11/14/2023 #1

由于第二个块中“只有”一个下划线,因此最简单的方法是为该特定情况创建一个正则表达式:

out = (df['value_type_and_model_name']
       .str.extract(r'(?P<value_type>.*)_(?P<model_name>[^_]*_[^_]*)$')
       .fillna({'value_type': df['value_type_and_model_name']})
      )

正则表达式演示(摘录)

输出:

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

如果你真的想拆分

df['value_type_and_model_name'].str.split('_(?=[^_]*_[^_]*$)', expand=True)

正则表达式演示(拆分)

如果需要,可以分配给原始数据帧:

s = df.pop('value_type_and_model_name')
df[['value_type', 'model_name']] = (s.str.extract(r'(.*)_([^_]*_[^_]*)$')
                                     .fillna({0: s})
                                   )

输出:

    id             value_type        model
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

评论

0赞 ah bon 11/14/2023
非常感谢,除了在列中似乎变成了s。actual_valuevalue_typeNaN
1赞 mozway 11/14/2023
@ahbon这是因为,从技术上讲,没有什么可以拆分/提取的,但您可以使用原始列。让我更新fillna
1赞 mozway 11/14/2023
我添加了一个变体,它实际上还不错split