80

CSV から Pandas データフレームに解析し、15 分バーにリサンプリングした OHLC 価格データ セットがあります。

<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)

期間範囲 (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"])

基本的な問題:関数を列にマップするにはどうすればよいですか?具体的には、複数の他の列または行全体などを参照したい場所ですか?

この投稿では、1 つのソース列から 2 つの計算列を追加する方法を扱います。これは近いですが、完全ではありません。

もう少し高度な: 複数のバー (T) を参照して決定される価格パターンの場合、関数定義内から異なる行 (T-1、T-2 など) を参照するにはどうすればよいですか?

4

4 に答える 4

77

正確なコードは、実行する列ごとに異なりますが、関数mapapply関数を使用する可能性があります。場合によっては、既存の列を直接使用して計算することができます。これは、列が 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

行内で max や min などの操作を使用する必要がある場合は、applywithを使用し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

うまくいけば、それがあなたにどのように進むべきかについてのアイデアを与えるでしょう.

編集:行を隣接する行と比較する最も簡単な方法は、比較する列をスライスし、最初/最後を残してから、結果のスライスを比較することです。たとえば、これにより、列 A の要素が列 C の次の行の要素よりも小さい行がどれかがわかります。

d['A'][:-1] < d['C'][1:]

これは逆の方法で、前の行の C より小さい A を持つ行を示します。

d['A'][1:] < d['C'][:-1]

['A"][:-1]A の最後の要素を['C'][1:]スライスし、列 C の最初の要素をスライスします。したがって、これら 2 つを並べて比較すると、A の各要素を次の行の C と比較することになります。

于 2012-09-11T20:04:56.837 に答える
48

次のようになど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)

次に、マップを使用できます:

df["isHammer"] = map(is_hammer, df["Open"], df["Low"], df["Close"], df["High"])
于 2012-09-11T20:04:39.830 に答える
5

質問の 2 番目の部分では、次のように使用することもできますshift

df['t-1'] = df['t'].shift(1)

t-1次に、1 行上の t の値が含まれます。

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.shift.html

于 2014-08-16T12:52:19.723 に答える
1

リストする最初の 4 つの関数は、ベクトルでも機能しますが、lower_wick を適応させる必要があることを除きます。このようなもの、

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

ここで、o、l、c はベクトルです。df を入力として受け取り、numpy の使用を避ける代わりに、この方法でそれを行うことができますが、はるかに遅くなります。

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

他の 3 つは、列またはベクトルに対してそのまま機能します。次に、で終了できます

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

ビット演算子は、&for and|fororなどのブール ベクトルに対してセット ロジックを実行できます。これは、指定したサンプル計算を完全にベクトル化するのに十分であり、比較的高速です。これらの計算の実行中に、データの基礎となる numpy 配列を一時的に操作することで、おそらくさらに高速化できます。

2 番目の部分では、各行のパターンを示す列を導入し、各パターンを処理する一連の関数を記述することをお勧めします。次に、パターンごとにグループ化し、各グループに適切な関数を適用します。

于 2015-03-05T15:35:00.297 に答える