python-3.x - 在另一个条件处于活动状态时满足 Pandas 的第一个日期条件
问题描述
我有一个带有时间序列分数的数据框。我的目标是检测分数何时大于某个阈值th
,然后找到分数何时回到 0。很容易分别找到每个条件
dates_1 = score > th
dates_2 = np.sign(score[1:]) == np.sign(score.shift(1).dropna())
但是,我不知道覆盖 dates_2 的最pythonic方法是什么,以便仅在观察到“活动” date_1 的日期
也许使用辅助列“活动”设置为 1 时score > th
为真,并在满足 dates_2 的条件时将其设置为假。这样我就可以要求更改符号 AND active == True
。但是,这种方法需要迭代,我想知道我的问题是否有矢量化解决方案
关于如何改进我的方法的任何想法?
样本数据:
date score
2010-01-04 0.0
2010-01-05 -0.3667779798467592
2010-01-06 -1.9641427199568868
2010-01-07 -0.49976215445519134
2010-01-08 -0.7069108074548405
2010-01-11 -1.4624766212523337
2010-01-12 -0.9132777669357441
2010-01-13 0.16204588193577152
2010-01-14 0.958085568609925
2010-01-15 1.4683022129399834
2010-01-19 3.036016680985081
2010-01-20 2.2357911432637345
2010-01-21 2.8827438241030707
2010-01-22 -3.395977874791837
预期产出
如果 th = 0.94
date active
2010-01-04 False
2010-01-05 False
2010-01-06 False
2010-01-07 False
2010-01-08 False
2010-01-11 False
2010-01-12 False
2010-01-13 False
2010-01-14 True
2010-01-15 True
2010-01-19 True
2010-01-20 True
2010-01-21 True
2010-01-22 False
解决方案
未矢量化!
def alt_cond(s, th):
active = False
for x in s:
active = [x >= th, x > 0][int(active)]
yield active
df.assign(A=[*alt_cond(df.score, 0.94)])
date score A
0 2010-01-04 0.000000 False
1 2010-01-05 -0.366778 False
2 2010-01-06 -1.964143 False
3 2010-01-07 -0.499762 False
4 2010-01-08 -0.706911 False
5 2010-01-11 -1.462477 False
6 2010-01-12 -0.913278 False
7 2010-01-13 0.162046 False
8 2010-01-14 0.958086 True
9 2010-01-15 1.468302 True
10 2010-01-19 3.036017 True
11 2010-01-20 2.235791 True
12 2010-01-21 2.882744 True
13 2010-01-22 -3.395978 False
矢量化(排序)
我使用 Numba 来真正加快速度。仍然是一个循环,但如果可以安装,应该会非常快numba
from numba import njit
@njit
def alt_cond(s, th):
active = False
out = np.zeros(len(s), dtype=np.bool8)
for i, x in enumerate(s):
if active:
if x <= 0:
active = False
else:
if x >= th:
active = True
out[i] = active
return out
df.assign(A=alt_cond(df.score.values, .94))
回应评论
您可以拥有列名和阈值的字典并进行迭代
th = {'score': 0.94}
df.join(pd.DataFrame(
np.column_stack([[*alt_cond(df[k], v)] for k, v in th.items()]),
df.index, [f"{k}_A" for k in th]
))
date score score_A
0 2010-01-04 0.000000 False
1 2010-01-05 -0.366778 False
2 2010-01-06 -1.964143 False
3 2010-01-07 -0.499762 False
4 2010-01-08 -0.706911 False
5 2010-01-11 -1.462477 False
6 2010-01-12 -0.913278 False
7 2010-01-13 0.162046 False
8 2010-01-14 0.958086 True
9 2010-01-15 1.468302 True
10 2010-01-19 3.036017 True
11 2010-01-20 2.235791 True
12 2010-01-21 2.882744 True
13 2010-01-22 -3.395978 False
推荐阅读
- javascript - 参数 urls onBeforeRequest.addListener 有很多 url 模式导致加载页面很慢
- javascript - 如何修复javascript引用错误:提示未定义
- http - 当我发送一个包含两个值为 0 的字节的字节数组时,它停止工作
- java - 如何仅将 Java 12 中的 JRE 安装到 docker 映像中?
- xml - XSLT 执行多文件到一的转换?
- python - 防止 SQLAlchemy 自动设置 IDENTITY_INSERT
- linux-kernel - 如何知道重置 pci 设备何时完成?
- spring - spring boot + h2 + jpa项目的问题
- java - Android 应用程序只安装一次
- cassandra - 如何在bindstatement cassandra java中选择包含的字符