如何打印出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 行。 start
和 end
应该是 pd.Timestamp
s 以便您可以使用 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
我有一个包含事件和警告的 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 行。 start
和 end
应该是 pd.Timestamp
s 以便您可以使用 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