[python] Adding calculated column(s) to a dataframe in pandas

The first four functions you list will work on vectors as well, with the exception that lower_wick needs to be adapted. Something like this,

def lower_wick_vec(o, l, c):
    min_oc = numpy.where(o > c, c, o)
    return min_oc - l

where o, l and c are vectors. You could do it this way instead which just takes the df as input and avoid using numpy, although it will be much slower:

def lower_wick_df(df):
    min_oc = df[['Open', 'Close']].min(axis=1)
    return min_oc - l

The other three will work on columns or vectors just as they are. Then you can finish off with

def is_hammer(df):
    lw = lower_wick_at_least_twice_real_body(df["Open"], df["Low"], df["Close"]) 
    cl = closed_in_top_half_of_range(df["High"], df["Low"], df["Close"])
    return cl & lw

Bit operators can perform set logic on boolean vectors, & for and, | for or etc. This is enough to completely vectorize the sample calculations you gave and should be relatively fast. You could probably speed up even more by temporarily working with the numpy arrays underlying the data while performing these calculations.

For the second part, I would recommend introducing a column indicating the pattern for each row and writing a family of functions which deal with each pattern. Then groupby the pattern and apply the appropriate function to each group.