python - 如何根据每个区间的特定条件将数据标记为异常
问题描述
我尝试在很多地方搜索这个问题,但找不到合适的工具。
我有一个简单的时间序列数据,
print(anom)
0 0
1 0
2 0
3 0
4 0
..
52777 1
52778 1
52779 0
52780 1
对于 = 1 且跨越的任何数据序列(例如 1000 个时间实例)。我想将这些标记为异常(真)。否则他们应该被忽略(作为假)。
如何使用 pandas 或 numpy 实现这一目标?
我还想绘制那些异常,例如红色,我们如何实现呢?
解决方案
目前尚不清楚您期望哪种输出。但是,让我们考虑以下与您的数据集相似的数据集:
s = pd.Series(np.random.choice([0,1], size=100, p=[0.7, 0.3]), name='anom')
0 1
1 0
2 0
3 0
4 0
..
95 0
96 1
97 1
98 0
99 1
Name: anom, Length: 100, dtype: int64
看起来像:
基于连续值过滤
首先我们计算1s的长度
length = s.groupby(((s-s.shift().fillna(0)).eq(1).cumsum()*s)).transform(len)*s
这通过识别伸展的第一个元素来工作(s-s.shift().fillna(0)).eq(1)
(一个元素和先例之间的差异只有在 1 前面有 0 的情况下才为 1,请参见下面的图 #2)。然后,它使增加的组(图#3)对每个 1 的延伸和 0 的连续延伸进行分组。通过乘以s
,只有 1 保留在组中(图 #4)。现在我们可以对每个拉伸的数据进行分组并计算每个长度(图#5)。0 将是一组的一部分,所以最后,我们通过再次乘以s
(图 #6)来删除零。
这是连续步骤的可视化表示,其中(…)
表示每个图中的上一步:
s_valid = s.loc[length<10]
s_anom = s.drop(s_valid.index)
ax = s_valid.plot(marker='o', ls='')
s_anom.plot(marker='o', ls='', ax=ax, color='r')
ax = s.plot()
s_anom.plot(marker='o', ls='', ax=ax, color='r')
以 7 为阈值的其他示例:
原始答案
您可以轻松转换为bool
以获取异常
>>> s.astype(bool)
0 True
1 False
2 False
3 False
4 False
...
95 False
96 True
97 True
98 False
99 True
Name: anom, Length: 100, dtype: bool
关于情节,取决于你期望你能做什么:
s_valid = s.loc[~s.astype(bool)]
s_anom = s.loc[s.astype(bool)]
ax = s_valid.plot(marker='o', ls='')
s_anom.plot(marker='o', ls='', ax=ax, color='r')
输出:
s_anom = s.loc[s.astype(bool)]
ax = s.plot()
s_anom.plot(marker='o', ls='', ax=ax, color='r')
推荐阅读
- python - 减去每个索引行值(即 '
我有一个 df,它有多个时间戳列(列标题本身是日期/时间)并且有一个时间行索引(每行每 2 分钟)。例如:
timestamp 2021-08-20 08:00:00 2021-08-27 08:00:00 2021-10-
- python - python:重复扩展数据框
- arrays - 从子数组中提取值并使用 jq 与上值组合到 csv
- javascript - 值被 setState 改变了,但是 React 表单提交的是 ORIGINAL 值
- python - 在 zx 平面中绘制垂直 3D 曲面图未显示
- python - convert clob to varchar python
- tensorflow - 为什么 TensorFlow 不使用标志 CU_STREAM_NON_BLOCKING 创建 CUDA 流?
- android - 收到通知时如何控制应用图标徽章的计数?
- java - 在 java 中获取张量的形状(我正在使用 org.pytorch 库)
- google-apps-script - Google 表格脚本修改 - 从第 4 行开始插入复选框