在Pandas数据框中检测符号变化

7
我有一个Pandas数据帧,它是基于日期时间索引的,长这样:
Datetime
2020-05-11 14:00:00-03:00    0.097538
2020-05-11 14:30:00-03:00   -0.083788
2020-05-11 15:00:00-03:00   -0.074128
2020-05-11 15:30:00-03:00    0.059725
2020-05-11 16:00:00-03:00    0.041369
2020-05-11 16:30:00-03:00    0.034388
2020-05-12 10:00:00-03:00    0.006814
2020-05-12 10:30:00-03:00   -0.005308
2020-05-12 11:00:00-03:00   -0.036952
2020-05-12 11:30:00-03:00   -0.070307
2020-05-12 12:00:00-03:00    0.102004
2020-05-12 12:30:00-03:00   -0.139317
2020-05-12 13:00:00-03:00   -0.167589
2020-05-12 13:30:00-03:00   -0.179942
2020-05-12 14:00:00-03:00    0.182351
2020-05-12 14:30:00-03:00   -0.160736
2020-05-12 15:00:00-03:00   -0.150033
2020-05-12 15:30:00-03:00   -0.141862
2020-05-12 16:00:00-03:00   -0.121372
2020-05-12 16:30:00-03:00   -0.095990
Name: result_col, dtype: float64
我的需求是标注变号的行,从负数到正数或从正数到负数。有什么想法吗? 编辑: 我需要在交叉上+1,在交叉下-1。
5个回答

14

让我们来试试

import numpy as np 
np.sign(data).diff().ne(0)

6
# assuming series is called 'data'
sign = data > 0
sign_change = (sign != sign.shift(1))  # or -1, depending if you want True before the sign change

更新: 我认为BEN_YO的解决方案更好。在回答时我不知道.diff


2

当有人需要仅获取数据框中更改的行时,使用@BENY或@Marat的解决方案非常好。在我的情况下,我需要获取从0到1并返回的行值发生更改的索引:

import pandas as pd
df = pd.DataFrame({'signal': [1,0,0,0,1,1,1,0,0,1,1,1,1,0,0]})

df.loc[(np.sign(df['signal']).diff().ne(0))]

结果:

    signal
0   1
1   0
4   1
7   0
9   1
13  0

我的动机是在plotly图形中绘制矩形,当信号为1时开始绘制并在0出现时完成矩形


1
你可以遍历该列,记录当前和上一个索引的值。逻辑可能类似于:
prev_value = 0
sign_changes = []
for i, value in enumerate(column, 0): # starting index of 0
    if value > 0 and prev_value < 0 or value < 0 and prev_value > 0:
        sign_changes.append([i-1, i])

0
这里有一个针对pandas的特定解决方案,使用列表推导和函数调用来加快速度。如果有完全向量化的解决方案,那将是最好的,但目前这个解决方案应该相当迅速:
def compare_sign(s):
    if len(s) == 2:
        return s.iat[1] if s.iat[0] != s.iat[1] else 0
    else:
        return 0  # this case covers the first value in the rolling window series

def cross(df, field):
    return pd.Series([compare_sign(w) for w in df[field].apply(np.sign).rolling(2)])

这个解决方案在值达到零但没有越过时返回0。例如: [-2,-1,0,-1] -> [0,0,0,-1] 要获得不同的行为,只需调整compare_sign函数即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接