python - 从信号交叉点在 pandas 中创建 bool 标志

标签 python pandas function

我想创建一个带有函数的标志并将其应用于 pandas 数据框中的一列。 该函数的目的是当信号向上穿过 -1 时将值设置为 1,并在信号向下穿过 1 时将值重置为 0。 这是我的代码示例: 我只是无法让该功能正常工作

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
 
x = np.arange(0, 10, 0.01)
x2 = np.arange(0, 20, 0.02)
sin1 = np.sin(x)
sin2 = np.sin(x2)
x2 /= 2
sin3 = sin1 + sin2
 
 
df = pd.DataFrame(sin3)
#name signal column
df.columns = ['signal']
df.signal.plot()
 
 
def my_flag(x):
   
    #cross over -1
    ok1 = (x.iloc[-1] > -1)*1
    ok2 = (x.iloc[-2] < -1)*1
   
    activate = (ok1*ok2) > 0.5
    if activate:
        flag_activate = 1
    # OFF
    #cross under 1
    ok3 = (x.iloc[-1] <1)*1
    ok4 = (x.iloc[-2] > 1)*1
   
    inactivate = (ok3*ok4) > 0.5
    if inactivate:       
        flag_activate = 0
    # # add to df
   
    return flag_activate
 
df['the_flag'] = df['signal'].apply(my_flag)
 
#I have set the flag to 0 for plotting purposes for demo,
# should be replaced when my_flag function works
df['the_flag'] = 0
fig, (ax1,ax2) = plt.subplots(2)
ax1.plot(df['signal'])
ax1.set_title('signal')
y1 = -1
y2 = 1
ax1.axhline(y1,color='r') 

我制作了一张“卡通图片”,展示了我希望正弦信号的标志的样子: enter image description here

最佳答案

我们可以首先检测-1+1交叉,同时考虑它们应该分别向上交叉和向下交叉。这可以通过将信号向左和向右移动 1 并与 -/+ 1 进行比较并考虑交叉行为来完成:

neg_1_crossings = np.where((sin3[:-1] < -1) & (sin3[1:] > -1))[0]

pos_1_crossings = np.where((sin3[:-1] > +1) & (sin3[1:] < +1))[0]

对于 -1 交叉:第一个掩码强制前一个值小于-1,第二个掩码强制下一个 值大于 -1。与 +1 类似,只是运算符翻转了。

现在我们有:

>>> neg_1_crossings
array([592], dtype=int64)

>>> pos_1_crossings
array([157, 785], dtype=int64)

我会在这里运行 for 循环来获取标志:

flag = np.zeros_like(sin3)

for neg_cross in neg_1_crossings:
    # a `neg_cross` raises the flag
    flag[neg_cross:] = 1
    
    for pos_cross in pos_1_crossings:
        if pos_cross > neg_cross:
            # once we hit a `pos_cross` later on, restrict the flag's ON
            # periods to be between the `neg_cross` and this `pos_cross`
            flag[pos_cross:] = 0
            
            # we are done with this `neg_cross`
            break

这给出了

signal+flag

总体:

def get_flag(col):
    """
    `col` is a pd.Series
    """
    # signal in numpy domain; also its shifted versions
    signal = col.to_numpy()
    sig_shifted_left = signal[1:]
    sig_shifted_right = signal[:-1]

    # detect crossings
    neg_1_crossings = np.where((sig_shifted_right < -1) & (sig_shifted_left > -1))[0]
    pos_1_crossings = np.where((sig_shifted_right > +1) & (sig_shifted_left < +1))[0]

    # form the `flag` signal
    flag = np.zeros_like(signal)

    for neg_cross in neg_1_crossings:
        # a `neg_cross` raises the flag
        flag[neg_cross:] = 1
        
        for pos_cross in pos_1_crossings:
            if pos_cross > neg_cross:
                # once we hit a `pos_cross` later on, restrict the flag's ON
                # periods to be between the `neg_cross` and this `pos_cross`
                flag[pos_cross:] = 0
                
                # we are done with this `neg_cross`
                break
     return flag

关于python - 从信号交叉点在 pandas 中创建 bool 标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67157966/

相关文章:

python - Pandas max() 和 min() 工作,但 Mean() 给出 "No numeric types"错误

python - 将所有数字相加的递归函数

python - 没有标题的 Pandas 数据框删除列

python - "TypeError: Object of type bytes is not JSON serializable"

python - pandas 当前行 * 上一行 + 上一行

python - 在元素中找不到标签值

JavaScript !function(){}

c++ - 添加函数数组并随机选择其中一个

python - 即使使用 requests.history,从重定向 2 次的 URL 下载 pdf 文件也会失败

python多处理谷歌计算引擎