Vectorized "crossing" computation #1256

Open
wesm opened this Issue May 18, 2012 · 3 comments

Projects

None yet

4 participants

Owner
wesm commented May 18, 2012

http://stackoverflow.com/questions/10475488/calculating-crossing-intercept-points-of-a-series-or-dataframe

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)

Looks like this question has come up more than once. My numpy answer to basically the same question: http://stackoverflow.com/questions/15112964/digitizing-an-analog-signal/15114952#15114952

@jreback jreback modified the milestone: 0.15.0, 0.14.0 Feb 18, 2014
ehsteve commented Jul 23, 2014

Looking forward to having this capability in pandas.

Contributor
jreback commented Jul 23, 2014

you can certainly make your own function for this
i am not sure that this is general enough to be a mainline pandas function
could be in the cookbook of course

@jreback jreback modified the milestone: Someday, 0.15.1 Jul 23, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment