已根据评论为清楚起见编辑了此问题
目标:根据组标记数据框列中可变数量的卡住/重复值。
所需的解决方案:所需的解决方案应满足以下条件:
- 速度和简洁很重要
- 解决方案应接受阈值的输入变量数量,以标记每个区域的卡住/重复值。 例如: {"Zone1": 4 , "Zone2":2} -> 表示在 Zone1 中,逻辑需要有 4 个连续的重复值来标记,而在 Zone2 中,至少有 2 个或更多重复值应该触发标记
- 请尽可能添加注释以使其更易于理解
- 最好使用 Pandas 和/或 Numpy
- 在具有 87600 个值的测试数据帧上为您的解决方案计时(生成一个具有 87,600 个值的数据帧)
输入数据/问题公式:
import pandas as pd
import numpy as np
from random import randint
# Generate some random data
ts_index = pd.date_range("1/1/2019", periods=24, freq="1H")
v1 = [randint(1, 100) for i in range(24)]
v2 = [2] * 24
v3 = [2, 2, 2, 2, 4, 4, 0, 2, 2, 1, 9, 2, 4, 1, 2, 2, 0, 2, 1, 8, 1, 7, 3, 5]
test_df = pd.DataFrame({"v1": v1, "v2": v2, "v3": v3}, index=ts_index)
print(test_df)
最佳答案
首先我们得到列的绝对差异,然后是 cumsum()
。
假设如果一个值不变,差异的累积和将保持不变,我们可以使用 pandas .shift()
。
我们必须将 zone1 中的每个值与上面的 4 行进行比较。 zone2 类似。
import pandas as pd
import numpy as np
import datetime
# Generate some random data
ts_index = pd.date_range("1/1/2019", periods=24, freq="1H")
v1 = [random.randint(1, 100) for i in range(24)]
v2 = [2] * 24
v3 = [2, 2, 2, 2, 4, 4, 0, 2, 2, 1, 9, 2, 4, 1, 2, 2, 0, 2, 1, 8, 1, 7, 3, 5]
df = pd.DataFrame({"v1": v1, "v2": v2, "v3": v3}, index=ts_index)
df1 = df.diff().fillna(0)
# Add hour and time of day to create flag
df['Hour'] = df.index.hour
df['Flag'] = np.where((df['Hour'] <= 8) | (df['Hour'] >= 18), 'Zone1', 'Zone2')
df1['Flag'] = np.where((df['Hour'] <= 8) | (df['Hour'] >= 18), 'Zone1', 'Zone2')
df1[["v1", "v2","v3"]] = np.abs(df1[["v1", "v2","v3"]])
df1[["v1", "v2","v3"]] = df1.groupby("Flag")["v1", "v2","v3"].cumsum()
columns = ["v1","v2","v3"]
z1_p = 3
z2_p = 1
for col in columns:
df["Flag_"+col] = (np.array(df1[col].shift(z1_p) == df1[col]) & np.array(df1["Flag"] == "Zone1")) | \
(np.array(df1[col].shift(z2_p) == df1[col]) & np.array(df1["Flag"] == "Zone2"))
for element in df[df["Flag_"+col] == True].index:
if df.loc[element]["Flag"] == "Zone1":
for i in range(1,4):
a = a.append(pd.Index([element - datetime.timedelta(hours=i)]))
else:
a = a.append(pd.Index([element - datetime.timedelta(hours=1)]))
df.at[a,"Flag_"+col] = True
df
输出:
v1 v2 v3 Hour Flag Flag_v1 Flag_v2 Flag_v3
2019-01-01 00:00:00 31 2 2 0 Zone1 False True True
2019-01-01 01:00:00 93 2 2 1 Zone1 False True True
2019-01-01 02:00:00 48 2 2 2 Zone1 False True True
2019-01-01 03:00:00 56 2 2 3 Zone1 False True True
2019-01-01 04:00:00 9 2 4 4 Zone1 False True False
2019-01-01 05:00:00 75 2 4 5 Zone1 False True False
2019-01-01 06:00:00 29 2 0 6 Zone1 False True False
2019-01-01 07:00:00 61 2 2 7 Zone1 False True False
2019-01-01 08:00:00 64 2 2 8 Zone1 False True False
2019-01-01 09:00:00 82 2 1 9 Zone2 False True False
2019-01-01 10:00:00 13 2 9 10 Zone2 False True False
2019-01-01 11:00:00 97 2 2 11 Zone2 False True False
2019-01-01 12:00:00 74 2 4 12 Zone2 False True False
2019-01-01 13:00:00 26 2 1 13 Zone2 False True False
2019-01-01 14:00:00 77 2 2 14 Zone2 False True True
2019-01-01 15:00:00 39 2 2 15 Zone2 False True True
2019-01-01 16:00:00 79 2 0 16 Zone2 False True False
2019-01-01 17:00:00 35 2 2 17 Zone2 False True False
2019-01-01 18:00:00 65 2 1 18 Zone1 False True False
2019-01-01 19:00:00 74 2 8 19 Zone1 False True False
2019-01-01 20:00:00 72 2 1 20 Zone1 False True False
2019-01-01 21:00:00 23 2 7 21 Zone1 False True False
2019-01-01 22:00:00 28 2 3 22 Zone1 False True False
2019-01-01 23:00:00 59 2 5 23 Zone1 False True False
关于python - 如何检查 Pandas 数据框中的卡住数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63238009/