numpy.random.seed()用法详解
阅读原文时间:2021年04月20日阅读:1
  • 1.总体说明:
    numpy.random.seed()中每一个数字代表一种随机数生成规则,当种子数确定后,每次调用numpy.random下的随机函数时,都会根据该种子数对应的规则,依次生成随机数或随机数组;
    当第二次指定相同的种子数时,每次调用numpy.random下的随机函数,会依次生成跟上一次指定种子数再调用随机函数时,相同的随机数或随机数组,即两次随机数(组)生成结果依次一一对应;
    当不指定种子数时,每次调用numpy.random下的随机函数,numpy会随机指定一个种子数,即随机地采用该种子数所对应的规则,生成随机数或随机数组,所以生成结果每次不同。

  • 2.下面给出测试代码:

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt

    freq = 'D'
    t0 = '2020-01-01'
    data_length = 28
    num_ts = 2
    period = 14
    different_type = 'no_seed' # one of 'no_seed', 'seed_outside_loop', 'seed_before_every_random'

    if different_type == 'no_seed':
    series = []
    for k in range(num_ts):
    level = 10 * np.random.rand()
    print(level/10)
    seas_amplitude = 0.1 + 0.3np.random.rand() print((seas_amplitude - 0.1) / 0.3) time_ticks = np.array(range(data_length)) source = level + seas_amplitudenp.sin(time_ticks(2np.pi)/period)
    noise = 0.1*np.random.randn(data_length)
    print(noise/0.1)
    data = source + noise
    index = pd.date_range(t0, periods=data_length, freq='D')
    series.append(pd.Series(data=data, index=index))
    series[k].plot()
    plt.title('no_seed')
    plt.show()

    series = []
    for k in range(num_ts):
        level = 10 * np.random.rand()
        print(level/10)
        seas_amplitude = 0.1 + 0.3*np.random.rand()
        print((seas_amplitude - 0.1) / 0.3)
        time_ticks = np.array(range(data_length))
        source = level + seas_amplitude*np.sin(time_ticks*(2*np.pi)/period)
        noise = 0.1*np.random.randn(data_length)
        print(noise/0.1)
        data = source + noise
        index = pd.date_range(t0, periods=data_length, freq='D')
        series.append(pd.Series(data=data, index=index))
        series[k].plot()
        plt.title('no_seed')
        plt.show()

    elif different_type == 'seed_outside_loop':
    np.random.seed(0)
    series = []
    for k in range(num_ts):
    level = 10 * np.random.rand()
    print(level / 10)
    seas_amplitude = 0.1 + 0.3 * np.random.rand()
    print((seas_amplitude - 0.1) / 0.3)
    time_ticks = np.array(range(data_length))
    source = level + seas_amplitude * np.sin(time_ticks * (2 * np.pi) / period)
    noise = 0.1 * np.random.randn(data_length)
    print(noise / 0.1)
    data = source + noise
    index = pd.date_range(t0, periods=data_length, freq='D')
    series.append(pd.Series(data=data, index=index))
    series[k].plot()
    plt.title('seed_outside_loop')
    plt.show()

    np.random.seed(0)
    series = []
    for k in range(num_ts):
        level = 10 * np.random.rand()
        print(level / 10)
        seas_amplitude = 0.1 + 0.3 * np.random.rand()
        print((seas_amplitude - 0.1) / 0.3)
        time_ticks = np.array(range(data_length))
        source = level + seas_amplitude * np.sin(time_ticks * (2 * np.pi) / period)
        noise = 0.1 * np.random.randn(data_length)
        print(noise / 0.1)
        data = source + noise
        index = pd.date_range(t0, periods=data_length, freq='D')
        series.append(pd.Series(data=data, index=index))
        series[k].plot()
        plt.title('seed_outside_loop')
        plt.show()

    elif different_type == 'seed_before_every_random':
    series = []
    for k in range(num_ts):
    np.random.seed(0)
    level = 10 * np.random.rand()
    print(level / 10)
    np.random.seed(0)
    seas_amplitude = 0.1 + 0.3 * np.random.rand()
    print((seas_amplitude - 0.1) / 0.3)
    time_ticks = np.array(range(data_length))
    source = level + seas_amplitude * np.sin(time_ticks * (2 * np.pi) / period)
    np.random.seed(0)
    noise = 0.1 * np.random.randn(data_length)
    print(noise / 0.1)
    data = source + noise
    index = pd.date_range(t0, periods=data_length, freq='D')
    series.append(pd.Series(data=data, index=index))
    series[k].plot()
    plt.title('seed_before_every_random')
    plt.show()

    series = []
    for k in range(num_ts):
        np.random.seed(0)
        level = 10 * np.random.rand()
        print(level / 10)
        np.random.seed(0)
        seas_amplitude = 0.1 + 0.3 * np.random.rand()
        print((seas_amplitude - 0.1) / 0.3)
        time_ticks = np.array(range(data_length))
        source = level + seas_amplitude * np.sin(time_ticks * (2 * np.pi) / period)
        np.random.seed(0)
        noise = 0.1 * np.random.randn(data_length)
        print(noise / 0.1)
        data = source + noise
        index = pd.date_range(t0, periods=data_length, freq='D')
        series.append(pd.Series(data=data, index=index))
        series[k].plot()
        plt.title('seed_before_every_random')
        plt.show()

    else:
    print('different_type must be one of \'no_seed\', \'seed_outside_loop\', \'seed_before_every_random\'')

  • 3.运行结果说明:

  • 3.1.当不设置种子数seed时:


    以上两图中序列图曲线的颜色(上图)和生成曲线的随机数(组)的选框颜色(下图)一一对应,可以看到,当different_type == ‘no_seed’,即不指定种子数时,2个if每个if生成2条序列,共4条序列,组成这4条序列的随机数和随机数组均不相同,所以4条曲线均不相同。这是因为每次调用np.random生成随机数和随机数组时,numpy都会随机指定一个seed,即随机指定一种随机数生成方式,所以每次生成的随机数(组)也不相同。

  • 3.2.当循环外指定相同的种子数时:

    以上两图中序列图曲线的颜色(上图)和生成曲线的随机数(组)的选框颜色(下图)一一对应,可以看到,当different_type == ‘seed_outside_loop’,即循环外指定相同的种子数时,2个if每个if生成2条序列,共4条序列,两两重合:if内的两条序列不同,if间的两组序列依次对应相同。这是因为在指定一个seed后,调用np.random的随机函数会依该规则,依次生成随机数和随机数组;重新指定这个seed后,调用np.random的随机函数又会依该规则,重头依次生成随机数和随机数组;所以此时if内的随机数和随机数组依次不同,if间对应位置的随机数和随机数组依次相同。

  • 3.3.当每一个随机函数前都指定相同的种子数时:


    以上两图中序列图曲线的颜色(上图)和生成曲线的随机数(组)的选框颜色(下图)一一对应,可以看到,当different_type == ‘seed_before_every_random’,即每次调用np.random时都指定相同的seed时,2个if每个if生成2条序列,共4条序列,组成这4条序列的随机数和随机数组均相同,所以4条曲线重合。这是因为每次调用np.random生成随机数和随机数组时seed都相同,即都是用相同的规则生成随机数,相当于每次都是从seed=0的这个随机数池中选出第一个或第一组随机数,所以4个红色方框中的随机数(组)都相同,4条曲线均相同。

  • 4.总结
    当我们需要构造一些具有特定规律或特征的数据去测试某些函数或算法时,通常需要用到np.random下的随机数函数来生成数据;此时通常需要让某些数据重新或者不重现,或者以某种频率和次序重现,就需要灵活使用seed。