7

ベッティング システムで Python と Pandas を使用して、古典的なマーチンゲールを実装したいと考えています。

この DataFrame が次のように定義されているとしましょう

df = pd.DataFrame(np.random.randint(0,2,100)*2-1, columns=['TossResults'])

そのため、トスの結果が含まれています (-1=負け 1=勝ち)

古典的なマーチンゲールを使用して賭け金 (毎回賭ける金額) を変更したいと考えています。

最初の賭け金は 1 です。

賭け金を失うと、以前の賭け金の 2 倍になります (乗数 = 2)。

私が勝った場合、賭け金はステーク_イニシャルになります

機能を実行しました

def stake_martingale_classical(stake_previous, result_previous, multiplier, stake_initial):
    if (result_previous==-1): # lose
        stake = stake_previous*multiplier
    elif (result_previous==1):
        stake = stake_initial
    else:
        raise(Exception('Error result_previous must be equal to 1 (win) or -1 (lose)'))
    return(stake)

しかし、パンダを使用して効率的に実装する方法がわかりません。私はこれを試しました:

initial_stake = 1
df['Stake'] = None
df['Stake'][0] = initial_stake
df['TossResultsPrevious'] = self.df['TossResults'].shift(1) # shifting-lagging
df['StakePrevious'] = self.df['Stake'].shift(1) # shifting-lagging

しかし今、この (マルチパラメータ) 関数を 0 軸に沿って適用する必要があります。

進め方がわからない!

関数を見pandas.DataFrame.applymapたことがありますが、1パラメーター関数のみのようです。

多分私は間違っていて、shift関数を使用するのは良い考えではありません

4

2 に答える 2

6

1わずかな解釈の変更の 1 つは、負けを としてマークし、勝ちをとしてマークする必要があることです0

最初のステップは、負けたラン ( steps+ edges) のエッジを見つけることです。次に、ステップのサイズの差を取り、それらの値を元のデータに戻す必要があります。のを取ると、連敗の現在の長さがわかりますcumsumtoss2あなたの賭けは2 ** cumsum(toss2)です。

バージョンはnumpyバージョンよりも高速ですpandasが、係数はN( の場合は ~8、 の場合はN=100~2 N > 10000) によって異なります。


パンダ

使用pandas.Series:

import pandas as pd
toss = np.random.randint(0,2,100)

toss = pd.Series(toss)

steps = (toss.cumsum() * toss).diff() # mask out the cumsum where we won [0 1 2 3 0 0 4 5 6 ... ]
edges = steps < 0 # find where the cumsum steps down -> where we won
dsteps = steps[edges].diff() # find the length of each losing streak
dsteps[steps[edges].index[0]] = steps[edges][:1] # fix length of the first run which in now NaN
toss2 = toss.copy() # get a copy of the toss series
toss2[edges] = dsteps # insert the length of the losing streaks into the copy of the toss results
bets = 2 ** (toss2).cumsum() # compute the wagers

res = pd.DataFrame({'toss': toss,
                    'toss2': toss2,
                    'runs': toss2.cumsum(),
                    'next_bet': bets})

でこぼこ

これは純粋なnumpyバージョンです (私の母国語はそうでした)。配列を整列させるには少し細かい作業がありますが、それpandasはあなたのために行います

toss = np.random.randint(0,2,100)

steps = np.diff(np.cumsum(toss) * toss)
edges = steps < 0
edges_shift = np.append(False, edges[:-1])
init_step = steps[edges][0]
toss2 = np.array(toss)
toss2[edges_shift] = np.append(init_step, np.diff(steps[edges]))
bets = 2 ** np.cumsum(toss2)

fmt_dict = {1:'l', 0:'w'}
for t, b in zip(toss, bets):
    print fmt_dict[t] + '-> {0:d}'.format(b)

パンダ出力

In [65]: res
Out[65]: 
    next_bet  runs  toss  toss2
0          1     0     0      0
1          2     1     1      1
2          4     2     1      1
3          8     3     1      1
4         16     4     1      1
5          1     0     0     -4
6          1     0     0      0
7          2     1     1      1
8          4     2     1      1
9          1     0     0     -2
10         1     0     0      0
11         2     1     1      1
12         4     2     1      1
13         1     0     0     -2
14         1     0     0      0
15         2     1     1      1
16         1     0     0     -1
17         1     0     0      0
18         2     1     1      1
19         1     0     0     -1
20         1     0     0      0
21         1     0     0      0
22         2     1     1      1
23         1     0     0     -1
24         2     1     1      1
25         1     0     0     -1
26         1     0     0      0
27         1     0     0      0
28         2     1     1      1
29         4     2     1      1
30         1     0     0     -2
31         2     1     1      1
32         4     2     1      1
33         1     0     0     -2
34         1     0     0      0
35         1     0     0      0
36         1     0     0      0
37         2     1     1      1
38         4     2     1      1
39         1     0     0     -2
40         2     1     1      1
41         4     2     1      1
42         8     3     1      1
43         1     0     0     -3
44         1     0     0      0
45         1     0     0      0
46         1     0     0      0
47         2     1     1      1
48         1     0     0     -1
49         2     1     1      1
50         1     0     0     -1
51         1     0     0      0
52         1     0     0      0
53         1     0     0      0
54         1     0     0      0
55         2     1     1      1
56         1     0     0     -1
57         1     0     0      0
58         1     0     0      0
59         1     0     0      0
60         1     0     0      0
61         2     1     1      1
62         1     0     0     -1
63         2     1     1      1
64         4     2     1      1
65         8     3     1      1
66        16     4     1      1
67        32     5     1      1
68         1     0     0     -5
69         2     1     1      1
70         1     0     0     -1
71         2     1     1      1
72         4     2     1      1
73         1     0     0     -2
74         2     1     1      1
75         1     0     0     -1
76         1     0     0      0
77         2     1     1      1
78         4     2     1      1
79         1     0     0     -2
80         1     0     0      0
81         2     1     1      1
82         1     0     0     -1
83         1     0     0      0
84         1     0     0      0
85         1     0     0      0
86         2     1     1      1
87         4     2     1      1
88         8     3     1      1
89        16     4     1      1
90        32     5     1      1
91        64     6     1      1
92         1     0     0     -6
93         1     0     0      0
94         1     0     0      0
95         1     0     0      0
96         2     1     1      1
97         1     0     0     -1
98         1     0     0      0
99         1     0     0      0

派手な出力

(panadas の結果とは異なるシード)

(result -> next bet):
w->  1
l->  2
w->  1
w->  1
l->  2
w->  1
l->  2
w->  1
l->  2
l->  4
w->  1
l->  2
w->  1
l->  2
l->  4
w->  1
w->  1
w->  1
l->  2
l->  4
l->  8
w->  1
l->  2
l->  4
w->  1
l->  2
l->  4
w->  1
w->  1
l->  2
w->  1
w->  1
w->  1
w->  1
l->  2
l->  4
w->  1
w->  1
l->  2
l->  4
l->  8
w->  1
w->  1
l->  2
l->  4
w->  1
w->  1
w->  1
w->  1
w->  1
w->  1
l->  2
w->  1
l->  2
w->  1
l->  2
w->  1
w->  1
w->  1
w->  1
w->  1
w->  1
l->  2
l->  4
l->  8
l->  16
w->  1
l->  2
l->  4
w->  1
w->  1
w->  1
w->  1
l->  2
w->  1
w->  1
l->  2
w->  1
w->  1
w->  1
l->  2
w->  1
w->  1
w->  1
w->  1
w->  1
w->  1
l->  2
l->  4
l->  8
w->  1
w->  1
l->  2
l->  4
l->  8
w->  1
l->  2
l->  4
w->  1
l->  2
于 2013-02-09T06:14:46.163 に答える
2

Pandasは、ベクトル化された操作を使用できる場合に最大の効率を得ることができますが、この問題には反復が必要だと思います。パンダを使用したソリューション:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randint(0,2,100)*2-1, columns=['TossResults'])
initial_stake = 1
df['Stake'] = initial_stake

for i in xrange(1,df.shape[0]):
    if df.TossResults[i-1] == -1:
        df.Stake[i] = 2 * df.Stake[i-1]
于 2013-02-07T17:50:55.210 に答える