如何打印出pandas中特定行之前的最后n分钟行?

How to print out the last n minutes of rows before a specific row in pandas?

我有一个包含事件和警告的 df,我想将每次事件发生前最后 10 分钟的数据存储在另一个名为“df1”的 df 中。我添加了一个布尔列来识别 df 中的事件,但我需要一种方法来遍历整个 df 并存储在每个事件发生前 10 分钟发生的行以及事件本身。

例如:

A                B                   Incident
warning      2018-11-01 01:37:12        F
warning      2018-11-01 01:37:41        F
warning      2018-10-31 01:37:48        F
warning      2018-10-30 01:40:31        F
warning      2018-10-29 01:43:41        F
warning      2018-10-28 01:45:51        F
incident     2018-10-27 01:47:41        T

在这种情况下,我需要存储

warning      2018-11-01 01:37:41        F
warning      2018-10-31 01:37:48        F
warning      2018-10-30 01:40:31        F
warning      2018-10-29 01:43:41        F
warning      2018-10-28 01:45:51        F
incident     2018-10-27 01:47:41        T

如果在第一次事件的最后 10 分钟内包含另一次事件,我想使用第二次事件发生之前的所有数据。即,如果在过去 10 分钟内没有发生任何事件,则附加 df A,否则将 df B 附加到 df1。

所以我认为分组记录是一个很好的起点。 我假设您需要检索在“事件”列设置为“T”的“事件”之前 10 分钟内发生的记录子集。 示例“入门”解决方案可能如下所示:

    df = pd.read_csv('your_set.csv', parse_dates=[1])
    all_rows = []
    within_accident_rows = []
    
    time = pd.Timedelta("10 min")
    
    incident_date = None
    incidents = df[df["Incident"] == 'T'].index # where incidents in dataset has occurred
    
    for idx in incidents:
        incident_date = df.iloc[idx]["B"]
        i = 1
        within_accident_rows.append(df.iloc[idx]["B"])
        while True:
            prev_row = df.iloc[idx - i]
            i += 1
            if incident_date - prev_row["B"] <= time and prev_row["Incident"] != 'T':
                within_accident_rows.append(prev_row["B"])
            else:
                all_rows.append(within_accident_rows)
                within_accident_rows = []
                break

它将分组并收集事件发生后 10 分钟内发生的所有记录(在 all_rows 中)或上次事故后的所有记录(如果上次事件也在 10 分钟内)。

另一种方法是将时间戳列设置为索引,并使用pandas'内置的datetimeindex切片到事件发生前10分钟内的select所有行,借助pd.Timedelta.

然而,需要注意的一件重要事情是,这需要对您的日期时间索引进行排序并按顺序排列。我注意到您的原始数据框的天数随着时间的增加而减少。我假设您的意思是数据在同一天,但 Excel smartfill 以不同的方式推断它。

无论如何,下面是一步一步的代码。为我们的示例设置数据:

import pandas as pd

# Create sample dataframe
df = pd.DataFrame({
    "A": [
             "warning", "warning", "warning", 
             "warning", "warning", "warning", "incident"
         ],
    "B": [
        "2018-11-01 01:37:12", 
        "2018-11-01 01:37:41", 
        "2018-11-01 01:37:48", 
        "2018-11-01 01:40:31", 
        "2018-11-01 01:43:41", 
        "2018-11-01 01:45:51", 
        "2018-11-01 01:47:41",
    ],
    "Incident": ["F", "F", "F", "F", "F", "F", "T"]
})

设置日期时间索引:

df["B"] = df["B"].apply(pd.Timestamp)
df = df.set_index("B")
df = df.sort_index()

您可以通过指定 df.loc[start:end] 在开始和结束时间内 select 行。 startend 应该是 pd.Timestamps 以便您可以使用 pd.Timedelta.

添加/减去时间段
# Select timestamps of incidents
incident_df = df[df["Incident"] == "T"]
incident_ts = list(incident_df.index)

# Loop over timesteps, select relevant rows
selected_rows = []
for ts in incident_ts:
    selected_rows.append(df.loc[ts-pd.Timedelta("10 minutes"):ts])
    
# Concat into dataframe
selected_df = pd.concat(selected_rows)

输出为:

                            A Incident
B                                     
2018-11-01 01:37:41   warning        F
2018-11-01 01:37:48   warning        F
2018-11-01 01:40:31   warning        F
2018-11-01 01:43:41   warning        F
2018-11-01 01:45:51   warning        F
2018-11-01 01:47:41  incident        T