首页 > 解决方案 > 如何将系列合并为 DataFrame 多索引的一列的成员

问题描述

我有一个包含 (phase, service_group, station, year, period) 的多索引的 DataFrame,其目的是在指定多索引的所有 5 个值时返回“capacity_required”。例如,在 Final 阶段、服务组 West、Milton 站、2025 年、Peak Hour 1 期间,required_capacity 为 1500。

目前有 7 个可能的时段,其中两个是“非高峰时段”和“平仓时段”。

我需要为多指数的每个实例添加一个新时期,称为 Off-Peak Shoulder,其中新值定义为 Off-Peak Hour 和 Shoulder Hour 的平均值。

到目前为止,我有以下代码:

import pandas as pd
import os

directory = '/Users/mark/PycharmProjects/psrpcl_data'
capacity_required_file = 'Capacity_Requirements.csv'
capacity_required_path = os.path.join(directory, capacity_required_file)

df_capacity_required = pd.read_csv(capacity_required_path, sep=',',
                       usecols=['phase', 'service_group', 'station', 'year', 'period', 'capacity_required'])

df_capacity_required.set_index(['phase', 'service_group', 'station', 'year'], inplace=True)
df_capacity_required.sort_index(inplace=True)

print(df_capacity_required.head(14))

上面代码的输出是:

                                                               period  capacity_required
phase service_group station                      year
Early Barrie        Allandale Waterfront Station 2025  AM Peak Period                490
                                                 2025   Off-Peak Hour                100
                                                 2025  PM Peak Period                520
                                                 2025     Peak Hour 2                250
                                                 2025     Peak Hour 5                180
                                                 2025     Peak Hour 6                180
                                                 2025   Shoulder Hour                250
                                                 2026  AM Peak Period                520
                                                 2026   Off-Peak Hour                50
                                                 2026  PM Peak Period                520
                                                 2026     Peak Hour 2                260
                                                 2026     Peak Hour 5                180
                                                 2026     Peak Hour 6                180
                                                 2026   Shoulder Hour                250

以上只是大约 30K 行的前 14 行。这向您显示了两年的周期。请注意,每年有 7 个时期。

我正在尝试创建一个名为“Off-Peak Shoulder”的新“时期”,以添加到每个(阶段、service_group、站、年份)组合中,这将是 Off-Peak 和 Shoulder 的平均值。

以下行正确计算每个指数值的一个非峰肩值:

off_peak_shoulder = df_capacity_required.loc[df_capacity_required.period == 'Off-Peak Hour', 'capacity_required'].add(
                    df_capacity_required.loc[df_capacity_required.period == 'Shoulder', 'capacity_required']).div(2)

print(off_peak_shoulder)

上面的代码提供了以下(正确的)Off-Peak Shoulder 系列作为输出:

phase    service_group          station                       year
Early    Barrie                 Allandale Waterfront Station  2025      0.0
                                                              2026      0.0
                                                              2027      0.0
                                                              2028      0.0
                                                              2029      0.0
                                                                      ...
Initial  Union Pearson Express  Pearson Station               2023    160.0
                                                              2024    160.0
                                Weston Station                2022     80.0
                                                              2023    105.0
                                                              2024    105.0

问题: 如何将 off_peak_shoulder 系列合并/加入 df_capacity_required 以使 Off-Peak Shoulder 成为“期间”下的另一个条目,如下所示?

                                                               period  capacity_required
phase service_group station                      year
Early Barrie        Allandale Waterfront Station 2025    AM Peak Period                490
                                                 2025     Off-Peak Hour                100
                                                 2025    PM Peak Period                520
                                                 2025       Peak Hour 2                250
                                                 2025       Peak Hour 5                180
                                                 2025       Peak Hour 6                180
                                                 2025     Shoulder Hour                250
                                                 2025 Off-Peak Shoulder                175
                                                 2026    AM Peak Period                520
                                                 2026     Off-Peak Hour                50
                                                 2026    PM Peak Period                520
                                                 2026       Peak Hour 2                260
                                                 2026       Peak Hour 5                180
                                                 2026       Peak Hour 6                180
                                                 2026     Shoulder Hour                250
                                                 2025 Off-Peak Shoulder                150

标签: pythondataframemergeseriesmulti-index

解决方案


我在这个问题上睡着了,醒来后找到了一个解决方案。我已经有了我需要的值列表,并为每个值设置了正确的多索引。我在想我需要一些复杂的多索引插入代码,但实际上我只需要将创建的 DataFrame 与原始 DataFrame 的形式相同,并将两者连接在一起。

这是我添加的代码。请注意,第一行与原始代码相同,只是我添加了对 reset_index 的调用。

    df_new = df_capacity_required.loc[df_capacity_required.period == 'Off-Peak Hour', 'capacity_required'].add(
        df_capacity_required.loc[df_capacity_required.period == 'Shoulder Hour', 'capacity_required']).div(2).reset_index()
    df_new['period'] = 'Off-Peak Shoulder'
    df_new.set_index(['phase', 'service_group', 'station', 'year'], inplace=True)
 
    df_capacity_required = concat([df_capacity_required, df_new])
    df_capacity_required.sort_index(inplace=True)

    print_full(df_capacity_required.head(16))

该 print 语句给出了以下所需的输出:

                                                               period  capacity_required
phase service_group station                      year
Early Barrie        Allandale Waterfront Station 2025    AM Peak Period                490
                                                 2025     Off-Peak Hour                100
                                                 2025    PM Peak Period                520
                                                 2025       Peak Hour 2                250
                                                 2025       Peak Hour 5                180
                                                 2025       Peak Hour 6                180
                                                 2025     Shoulder Hour                250
                                                 2025 Off-Peak Shoulder                175
                                                 2026    AM Peak Period                520
                                                 2026     Off-Peak Hour                50
                                                 2026    PM Peak Period                520
                                                 2026       Peak Hour 2                260
                                                 2026       Peak Hour 5                180
                                                 2026       Peak Hour 6                180
                                                 2026     Shoulder Hour                250
                                                 2026 Off-Peak Shoulder                150

但是感谢所有阅读问题的人。很高兴知道 StackOverflow 上有人愿意帮助遇到困难的人。


推荐阅读