代码之家  ›  专栏  ›  技术社区  ›  Karma_X

从数据帧中进行切片和提取

  •  1
  • Karma_X  · 技术社区  · 2 年前

    我有一个数据帧,如下所示:

         time  power speed state 
    
    1   14.00  29    3     1
    2   14.01  30    3     2
    3   14.02  29    3     3
    4   14.03  30    3     4
    5   14.04  29    3     5
    6   14.05  30    3     6
    7   14.06  29    3     6
    8   14.07  30    3     6
    9   14.08  29    3     6
    10  14.09  30    3     5
    11  14.10  29    3     5
    12  14.11  30    3     5
    13  14.12  29    3     5
    14  14.13  30    3     6
    15  14.14  31    4     6 
    16  14.15  32    4     6
    

    每个循环从状态5开始(行10,仅在状态6之后),并在状态6返回之前结束(即行13)。因此,循环1在第10行和第13行之间。

    这是一个大数据,有多个周期。我想提取每个周期作为一个数据帧。 我尝试了一些迭代,但没有成功。

     charge_cycles = []
    current_charge_start = None
    current_drive_start = None
    total_energy_consumed = 0
    drive_data = []
    
    for index, row in data.iterrows():
        if row['state'] == '6':
            if current_drive_start is not None:
                energy_during_drive = total_energy_consumed
                charge_cycles.append(energy_during_drive)
                drive_data.append(data.loc[current_drive_start:index])
                current_drive_start = None
                total_energy_consumed = 0
            current_charge_start = row['time']
        elif row['state'] == '5':
            if current_charge_start is not None and current_drive_start is None:
                current_drive_start = index
            if current_drive_start is not None:
                total_energy_consumed += row['power'] * (row['time'] - data.loc[current_drive_start, 'time'])
                current_drive_start = index
    
    # Print the energy consumption during driving between each charge cycle
    for i, energy in enumerate(charge_cycles, start=1):
        print(f"Charge Cycle {i}: Energy Consumed During Driving = {energy} units")
    
    # Display the DataFrames for each driving cycle
    for i, drive_df in enumerate(drive_data, start=1):
        print(f"Driving Cycle {i}:\n{drive_df}")
    

    这给了我整个数据帧的结果。有人能帮我处理这个问题的python代码吗?

    2 回复  |  直到 2 年前
        1
  •  2
  •   Andrej Kesely    2 年前

    IIUC,您可以尝试:

    df = pd.DataFrame(
        {
            "state": list(
                "6666665555555555555543555555512555666666666666666655555555412344666666666"
            )
        }
    )
    df["state"] = df["state"].astype(int)
    
    
    # remove the initial values 'till 6
    df = df.loc[df["state"].eq(6).idxmax() :]
    
    mask = df["state"].eq(6)
    for _, g in df.groupby((mask != mask.shift()).cumsum()):
        if (eq5 := g["state"].eq(5)).any():
            g = g.loc[eq5.idxmax() :]
            print(g)
            print("-" * 80)
    

    打印:

        state
    6       5
    7       5
    8       5
    9       5
    10      5
    11      5
    12      5
    13      5
    14      5
    15      5
    16      5
    17      5
    18      5
    19      5
    20      4
    21      3
    22      5
    23      5
    24      5
    25      5
    26      5
    27      5
    28      5
    29      1
    30      2
    31      5
    32      5
    33      5
    --------------------------------------------------------------------------------
        state
    50      5
    51      5
    52      5
    53      5
    54      5
    55      5
    56      5
    57      5
    58      4
    59      1
    60      2
    61      3
    62      4
    63      4
    --------------------------------------------------------------------------------
    
        2
  •  2
  •   mozway    2 年前

    您可以尝试使用布尔索引和 groupby

    如果您只想要在状态6之后开始的组,请添加一些筛选。

    m1 = df['state'].eq(5)
    m2 = df['state'].eq(6)
    m3 = m2.mask(m1).ffill()
    
    dfs = [g for k,g in df[m1&m3].groupby(m2.cumsum())]
    

    或者在两种状态6之间:

    m1 = df['state'].eq(5)
    m2 = df['state'].eq(6)
    m3 = m2.mask(m1).ffill() & m2.mask(m1).bfill()
    
    dfs = [g for k,g in df[m1&m3].groupby(m2.cumsum())]
    

    数据帧的输出列表:

    [     time  power  speed  state
    10  14.09     30      3      5
    11  14.10     29      3      5
    12  14.11     30      3      5
    13  14.12     29      3      5]
    

    用评论中的例子输出,并且只考虑分组前的6个:

    [    state
    6       5
    7       5
    8       5
    9       5
    10      5
    11      5
    12      5
    13      5
    14      5
    15      5
    16      5
    17      5
    18      5
    19      5,
         state
    50      5
    51      5
    52      5
    53      5
    54      5
    55      5
    56      5
    57      5]
    

    如果你想要所有的数字:

    
    m1 = df['state'].eq(5)
    m2 = df['state'].eq(6)
    m3 = m1.where(m1|m2).ffill()
    dfs = [g for k,g in df[m3&~m2].groupby(m2.cumsum())]
    

    输出:

    [    state
    6       5
    7       5
    8       5
    9       5
    10      5
    11      5
    12      5
    13      5
    14      5
    15      5
    16      5
    17      5
    18      5
    19      5
    20      4
    21      3
    22      5
    23      5
    24      5
    25      5
    26      5
    27      5
    28      5
    29      1
    30      2
    31      5
    32      5
    33      5,
         state
    50      5
    51      5
    52      5
    53      5
    54      5
    55      5
    56      5
    57      5
    58      4
    59      1
    60      2
    61      3
    62      4
    63      4]