我有一个OHLC价格的数据集,我从CSV解析成熊猫数据帧和重采样到15个分钟吧:
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 500047 entries, 1998-05-04 04:45:00 to 2012-08-07 00:15:00
Freq: 15T
Data columns:
Close 363152 non-null values
High 363152 non-null values
Low 363152 non-null values
Open 363152 non-null values
dtypes: float64(4)
Run Code Online (Sandbox Code Playgroud)
我想添加各种计算列,从简单的列开始,例如期间范围(HL),然后是布尔值,以指示我将定义的价格模式的出现 - 例如锤子蜡烛模式,其样本定义:
def closed_in_top_half_of_range(h,l,c):
return c > l + (h-l)/2
def lower_wick(o,l,c):
return min(o,c)-l
def real_body(o,c):
return abs(c-o)
def lower_wick_at_least_twice_real_body(o,l,c):
return lower_wick(o,l,c) >= 2 * real_body(o,c)
def is_hammer(row):
return lower_wick_at_least_twice_real_body(row["Open"],row["Low"],row["Close"]) \
and closed_in_top_half_of_range(row["High"],row["Low"],row["Close"])
Run Code Online (Sandbox Code Playgroud)
基本问题:如何将函数映射到列,特别是我想引用多个其他列或整行或其他什么?
这篇文章涉及从单个源列添加两个计算列,这些列很接近但不完全相同.
稍微高级一点:对于参考多个条形(T)确定的价格模式,我如何从函数定义中引用不同的行(例如T-1,T-2等)?
Bre*_*arn 71
对于您想要执行的每个列,确切的代码会有所不同,但您可能希望使用map
和apply
函数.在某些情况下,您可以直接使用现有列进行计算,因为列是Pandas Series对象,它们也可以作为Numpy数组使用,它可以自动按元素方式进行常规数学运算.
>>> d
A B C
0 11 13 5
1 6 7 4
2 8 3 6
3 4 8 7
4 0 1 7
>>> (d.A + d.B) / d.C
0 4.800000
1 3.250000
2 1.833333
3 1.714286
4 0.142857
>>> d.A > d.C
0 True
1 True
2 True
3 False
4 False
Run Code Online (Sandbox Code Playgroud)
如果您需要在一行中使用max和min等操作,则可以使用apply
with axis=1
将您喜欢的任何函数应用于每一行.这是一个计算的例子min(A, B)-C
,它看起来就像你的"较低的灯芯":
>>> d.apply(lambda row: min([row['A'], row['B']])-row['C'], axis=1)
0 6
1 2
2 -3
3 -3
4 -7
Run Code Online (Sandbox Code Playgroud)
希望这能让您了解如何继续.
编辑:要将行与相邻行进行比较,最简单的方法是对要比较的列进行切片,从开始/结束开始,然后比较生成的切片.例如,这将告诉您列A中的元素小于C列中下一行元素的哪些行:
d['A'][:-1] < d['C'][1:]
Run Code Online (Sandbox Code Playgroud)
这是另一种方式,告诉你哪些行的A小于前一行的C:
d['A'][1:] < d['C'][:-1]
Run Code Online (Sandbox Code Playgroud)
在['A"][:-1]
A列的最后一个元素上做['C'][1:]
切片,并在C列的第一个元素上做切片,所以当你将这两个元素排成一行并进行比较时,你要将A中的每个元素与下一行中的C进行比较.
And*_*den 45
你可以is_hammer
在row["Open"]
如下等方面拥有
def is_hammer(rOpen,rLow,rClose,rHigh):
return lower_wick_at_least_twice_real_body(rOpen,rLow,rClose) \
and closed_in_top_half_of_range(rHigh,rLow,rClose)
Run Code Online (Sandbox Code Playgroud)
然后你可以使用map:
df["isHammer"] = map(is_hammer, df["Open"], df["Low"], df["Close"], df["High"])
Run Code Online (Sandbox Code Playgroud)
对于问题的第二部分,您还可以使用shift
,例如:
df['t-1'] = df['t'].shift(1)
Run Code Online (Sandbox Code Playgroud)
t-1
然后将包含以上t行中来自t的值。
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.shift.html