2017-01-15 9 views
-1

私は関数とサブ関数を持っており、それぞれにはいくつかのランダムな配列が生成されています。結果を再現可能にするために、私はシードを使用します。しかし、私は奇妙なケースを参照してください。サブ関数によるPythonシード

サブ関数にシードがある場合、メイン関数の乱数もサブ関数のシードから影響を受けます。そして、主機能から副機能への影響はありません。 たとえば、次のコードを考えます。このコードの場合

import random 
from random import randint 
import numpy as np 


def randgene(): 

    a=np.random.randint(0,5,size=5) 
    print "a in function", a 
    np.random.seed(seed=15) 
    b=np.random.randint(0,5,size=5) 
    print "b in function", b 

    d=np.random.choice(50, size=5, replace = False) 
    print "d in function", d 
    # np.random.seed(seed=None) 

def main(): 

    print "d-without seed", np.random.choice(50, size=5, replace = False) 
    print "a-without seed", np.random.randint(0,5,size=5) 
    print "b-without seed", np.random.randint(0,5,size=5) 
    f = randgene()  
    print "d-without seed", np.random.choice(50, size=5, replace = False) 
    print "a-without seed", np.random.randint(0,5,size=5) 
    print "b-without seed", np.random.randint(0,5,size=5) 
    f = randgene() 
    print "d-without seed", np.random.choice(50, size=5, replace = False) 
    print "a-without seed", np.random.randint(0,5,size=5) 
    print "b-without seed", np.random.randint(0,5,size=5) 

    np.random.seed(seed=10) 

    print "d-with seed", np.random.choice(50, size=5, replace = False) 
    print "a-with seed", np.random.randint(0,5,size=5) 
    print "b-with seed", np.random.randint(0,5,size=5) 

    f = randgene() 

    print "d-with seed", np.random.choice(50, size=5, replace = False) 
    print "a-with seed", np.random.randint(0,5,size=5) 

    f = randgene() 

    print "d-with seed", np.random.choice(50, size=5, replace = False) 
    print "a-with seed", np.random.randint(0,5,size=5) 

if __name__ == '__main__': 
    main() 

私はこの結果を得る:あなたは、私はサブ関数を呼び出した時はいつでもd-with seed [ 8 21 32 39 11], a-with seed [3 0 3 3 0] は、メイン機能で繰り返し見

d-without seed [14 29 9 42 18] 
a-without seed [3 0 0 3 4] 
b-without seed [3 2 0 2 1] 
a in function [2 3 1 2 3] 
b in function [0 4 0 4 3] 
d in function [41 16 22 24 14] 
d-without seed [ 8 21 32 39 11] 
a-without seed [3 0 3 3 0] 
b-without seed [1 2 2 1 4] 
a in function [4 4 0 2 2] 
b in function [0 4 0 4 3] 
d in function [41 16 22 24 14] 
d-without seed [ 8 21 32 39 11] 
a-without seed [3 0 3 3 0] 
b-without seed [1 2 2 1 4] 
d-with seed [37 23 44 42 47] 
a-with seed [2 0 0 4 4] 
b-with seed [0 0 2 4 2] 
a in function [0 0 2 3 0] 
b in function [0 4 0 4 3] 
d in function [41 16 22 24 14] 
d-with seed [ 8 21 32 39 11] 
a-with seed [3 0 3 3 0] 
a in function [1 2 2 1 4] 
b in function [0 4 0 4 3] 
d in function [41 16 22 24 14] 
d-with seed [ 8 21 32 39 11] 
a-with seed [3 0 3 3 0] 

します。どうやら何の繰り返しを持っていない

d-without seed [17 20 23 36 28] 
a-without seed [3 1 1 2 0] 
b-without seed [3 2 1 1 3] 
a in function [1 2 2 0 4] 
b in function [4 4 0 4 2] 
d in function [ 9 46 19 7 47] 
d-without seed [39 42 10 17 4] 
a-without seed [2 3 0 2 4] 
b-without seed [1 4 1 3 2] 
a in function [1 1 3 3 2] 
b in function [1 3 4 4 3] 
d in function [ 0 2 45 5 19] 
d-without seed [24 20 47 3 29] 
a-without seed [3 0 3 3 3] 
b-without seed [1 0 0 2 3] 
d-with seed [37 23 44 42 47] 
a-with seed [2 0 0 4 4] 
b-with seed [0 0 2 4 2] 
a in function [0 0 2 3 0] 
b in function [4 4 0 1 1] 
d in function [ 6 11 35 4 7] 
d-with seed [19 47 43 38 15] 
a-with seed [0 4 2 1 2] 
a in function [1 2 1 3 2] 
b in function [3 4 4 0 2] 
d in function [38 31 17 43 2] 
d-with seed [ 7 15 39 2 49] 
a-with seed [3 4 1 4 0] 

:私はサブ機能でラインnp.random.seed(seed=15)コメント場合 はしかし、私はこの結果を得ます。したがって、メイン関数のシードはサブ関数には影響しません。 np.random.seed(seed=15)np.random.seed(seed=None)の両方をコメント化しておくと、同様の結果になります。 何か起こっていることを誰かに説明してもらえますか?事前に

おかげで、 アフシン・

+1

シードは、すべての乱数がどんなにところ、それが設定されている_after_生成に影響します。 – DyZ

+0

@DYZありがとう、私はそれを得た。 –

答えて

1

ローカルランダムステートの場合は、numpy.random.seedで設定したグローバルステートではなく、numpy.random.RandomStateを使用します。

例:

import numpy as np 

seed1 = 1 
seed2 = 42 

rs1 = np.random.RandomState(seed1) 
rs2 = np.random.RandomState(seed2) 
rs3 = np.random.RandomState(seed1) # same seed value used for rs1 

a = rs1.randint(0, 5, size=5) 
b = rs1.randint(0, 5, size=5) 

c = rs2.randint(0, 5, size=5) 

e = rs3.randint(0, 5, size=5) 
f = rs3.randint(0, 5, size=5) 


eq = np.testing.assert_array_equal 

try: 
    eq(a, b, err_msg='OK, a should be != b') 
except AssertionError: 
    pass 

try: 
    eq(a, c, err_msg='OK, a should be != c') 
except AssertionError: 
    pass 

eq(a, e, err_msg='ERROR') # a and e are equal due to same seed 
eq(b, f, err_msg='ERROR') # b and f are equal due to same seed 

print('OK') 
1

は、乱数ジェネレータのシードは、そのグローバルな状態を設定するために使用されます。その状態は、そのポイントの後に生成されたすべての番号(および生成された各番号によって状態が変更される)に使用されます。あなたはあなたの関数は、それが常に使用、独自の種を持っているしたい場合は

def print_and_increment(): # this is like generating a random number 
    global x 
    print("x was {}. Incrementing...".format(x)) 
    x += 1 
    print("x is now", x) 

def func(): 
    global x 
    print("func before seed") 
    print_and_increment() 

    x = 10 # this is equivalent to calling seed() 

    print("func after seed") 
    print_and_increment() 

x = 0 # seed 
print("top") 
print_and_increment() 

func() 

print("middle") 
print_and_increment() 

func() 

print("bottom") 
print_and_increment() 

、それは外の使用乱数生成器の状態を変更しないようにするために:あなたは、グローバル変数を使用して、この1にあなたの例を比較することができますnumpy.random.get_statenumpy.random.set_stateを使用できます。

def randgene(): 

    prev_state = np.random.get_state() 

    a=np.random.randint(0,5,size=5) 
    print "a in function", a 
    np.random.seed(seed=15) 
    b=np.random.randint(0,5,size=5) 
    print "b in function", b 

    d=np.random.choice(50, size=5, replace = False) 
    print "d in function", d 
    # np.random.seed(seed=None) 

    np.random.set_state(prev_state) 

今、あなたの関数は、乱数生成器の外部コードの使用には影響を与えません。

はこのような何かを試してみてください。

関連する問題