Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 计算序列或数据帧的交叉(截距)点_Python_Pandas - Fatal编程技术网

Python 计算序列或数据帧的交叉(截距)点

Python 计算序列或数据帧的交叉(截距)点,python,pandas,Python,Pandas,我有索引为浮点数的周期数据,如下所示: time = [0, 0.1, 0.21, 0.31, 0.40, 0.49, 0.51, 0.6, 0.71, 0.82, 0.93] voltage = [1, -1, 1.1, -0.9, 1, -1, 0.9,-1.2, 0.95, -1.1, 1.11] df = DataFrame(data=voltage, index=time, columns=['voltage']) df.plot(marker='o') 我想创

我有索引为浮点数的周期数据,如下所示:

time =    [0, 0.1, 0.21, 0.31, 0.40, 0.49, 0.51, 0.6, 0.71, 0.82, 0.93]
voltage = [1,  -1,  1.1, -0.9,    1,   -1,  0.9,-1.2, 0.95, -1.1, 1.11]
df = DataFrame(data=voltage, index=time, columns=['voltage'])
df.plot(marker='o')
我想创建一个
交叉(df,y_val,direction='rise''fall''fall''cross')
函数,该函数返回一个包含所有 电压值等于y值的插值点。对于“上升”,仅返回斜率为正的值;对于“fall”仅返回具有负斜率的值;对于'cross',两者都返回。因此,如果y_val=0direction='cross',则将返回一个包含10个值的数组,其中包含交叉点的X值(第一个值约为0.025)

我想这可以用迭代器来完成,但我想知道是否有更好的方法来完成


谢谢。我很喜欢熊猫和熊猫社区。

为了做到这一点,我总结了以下几点。这是一个矢量化版本,比使用循环的版本快150倍

def cross(series, cross=0, direction='cross'):
    """
    Given a Series returns all the index values where the data values equal 
    the 'cross' value. 

    Direction can be 'rising' (for rising edge), 'falling' (for only falling 
    edge), or 'cross' for both edges
    """
    # Find if values are above or bellow yvalue crossing:
    above=series.values > cross
    below=np.logical_not(above)
    left_shifted_above = above[1:]
    left_shifted_below = below[1:]
    x_crossings = []
    # Find indexes on left side of crossing point
    if direction == 'rising':
        idxs = (left_shifted_above & below[0:-1]).nonzero()[0]
    elif direction == 'falling':
        idxs = (left_shifted_below & above[0:-1]).nonzero()[0]
    else:
        rising = left_shifted_above & below[0:-1]
        falling = left_shifted_below & above[0:-1]
        idxs = (rising | falling).nonzero()[0]

    # Calculate x crossings with interpolation using formula for a line:
    x1 = series.index.values[idxs]
    x2 = series.index.values[idxs+1]
    y1 = series.values[idxs]
    y2 = series.values[idxs+1]
    x_crossings = (cross-y1)*(x2-x1)/(y2-y1) + x1

    return x_crossings

# Test it out:
time = [0, 0.1, 0.21, 0.31, 0.40, 0.49, 0.51, 0.6, 0.71, 0.82, 0.93]
voltage = [1,  -1,  1.1, -0.9,    1,   -1,  0.9,-1.2, 0.95, -1.1, 1.11]
df = DataFrame(data=voltage, index=time, columns=['voltage'])
x_crossings = cross(df['voltage'])
y_crossings = np.zeros(x_crossings.shape)
plt.plot(time, voltage, '-ob', x_crossings, y_crossings, 'or')
plt.grid(True)

当这起作用时,它是相当令人满意的。有什么可以改进的吗?

顺便说一句,您可能在打印过程中偶然发现了一个错误。根据数据,我认为第一个交叉点应该在0.05左右,但标签没有对齐,因此看起来交叉点是0.025。(0.7.3)凉爽。我在此处创建了一个关于此的问题:。在未来的某个时候,我将不得不仔细研究它。有没有其他插值技术可以用于获取更高精度的交叉点?