文章目录

前言

一、随机漫步

二、设置随机漫步的样式

1. 给点着色

2.重新绘制起点和终点

3. 隐藏坐标轴

4. 增加点数

三、使用Plotly模拟掷骰子

1. 生成数据并进行统计

2. 绘制直方图

3. 同时掷两个骰子

四、练习

总结



前言

今天接上次的学习内容,主要包括随机漫步和使用PLOTLY模拟掷骰子。

上次文章链接:

https://blog.csdn.net/mzy20010420/article/details/126047773?spm=1001.2014.3001.5502https://blog.csdn.net/mzy20010420/article/details/126047773?spm=1001.2014.3001.5502


一、随机漫步

随机漫步是这样行走得到的路径:每次行走都是完全随机的、没有明确的方向,结果是由一系列随即策略决定的。

示例:随机生成5000个点,每一步的步长是(0, 1, 2, 3, 4, 5, 6, 7)中的任意一个,方向是x, y方向。

代码:

from random import choice
import matplotlib.pyplot as plt

class RandomWalk:
    def __init__(self, num_point = 5000):
        #初始化随机漫步
        self.num_point = num_point
        
        #随机漫步始于(0,0)
        self.x_value = [0]
        self.y_value = [0]
        
    def fill_walk(self):
        #计算各点
       while len(self.x_value) < self.num_point:
           x_direction = choice([1, -1])
           x_distance = choice([0, 1, 2, 3, 4, 5, 6, 7])
           x_step = x_direction * x_distance
           
           y_direction = choice([1, -1])
           y_distance = choice([0, 1, 2, 3, 4, 5, 6, 7])
           y_step = y_direction * y_distance
           
           if x_step == 0 and y_step == 0:
               continue
           
           x = self.x_value[-1] + x_step
           y = self.y_value[-1] + y_step
           
           self.x_value.append(x)
           self.y_value.append(y)

#画图
rw = RandomWalk()
rw.fill_walk()
plt.style.use('classic')
fig, ax = plt.subplots()
ax.scatter(rw.x_value, rw.y_value, s = 5)
plt.show()

结果:

 注意:

每次随机漫步都会生成不同的结果。当将程序多运行几次后,会得到不同的结果,如下图所示:

              

二、设置随机漫步的样式

1. 给点着色

使用颜色映射来指出漫步中各点的先后顺序,并删除每个点的黑色轮廓,让其颜色更为明显。

from random import choice
import matplotlib.pyplot as plt

class RandomWalk:
    def __init__(self, num_point = 5000):
        #初始化随机漫步
        self.num_point = num_point
        
        #随机漫步始于(0,0)
        self.x_value = [0]
        self.y_value = [0]
        
    def fill_walk(self):
        #计算各点
       while len(self.x_value) < self.num_point:
           x_direction = choice([1, -1])
           x_distance = choice([0, 1, 2, 3, 4, 5, 6, 7])
           x_step = x_direction * x_distance
           
           y_direction = choice([1, -1])
           y_distance = choice([0, 1, 2, 3, 4, 5, 6, 7])
           y_step = y_direction * y_distance
           
           if x_step == 0 and y_step == 0:
               continue
           
           x = self.x_value[-1] + x_step
           y = self.y_value[-1] + y_step
           
           self.x_value.append(x)
           self.y_value.append(y)

#画图
rw = RandomWalk()
rw.fill_walk()
plt.style.use('classic')
fig, ax = plt.subplots()
point_numbers = range(rw.num_point) #使用range()生成了一个数字列表,其中包含的数与漫步包含的点数量相同
ax.scatter(rw.x_value, rw.y_value, c= point_numbers, cmap = plt.cm.Blues, edgecolors = 'none', s = 5)
plt.show()

结果:

注意:

(1)使用range()生成了一个数字列表,其中包含的数与漫步包含的点数量相同,将列表存在point_numbers中。

也可将其改为range(5000)

#画图
rw = RandomWalk()
rw.fill_walk()
plt.style.use('classic')
fig, ax = plt.subplots()
point_numbers = range(5000) #使用range()生成了一个数字列表,其中包含的数与漫步包含的点数量相同
ax.scatter(rw.x_value, rw.y_value, c= point_numbers, cmap = plt.cm.Blues, edgecolors = 'none', s = 5)
plt.show()

 会产生相同的效果。

(2)最终的随机漫步从浅蓝变为深蓝。

2.重新绘制起点和终点

让随机漫步的起点和终点两处更大并显示为不同颜色。

示例:起点为绿色大点,终点为红色大点

代码:

from random import choice
import matplotlib.pyplot as plt

class RandomWalk:
    def __init__(self, num_point = 5000):
        #初始化随机漫步
        self.num_point = num_point
        
        #随机漫步始于(0,0)
        self.x_value = [0]
        self.y_value = [0]
        
    def fill_walk(self):
        #计算各点
       while len(self.x_value) < self.num_point:
           x_direction = choice([1, -1])
           x_distance = choice([0, 1, 2, 3, 4, 5, 6, 7])
           x_step = x_direction * x_distance
           
           y_direction = choice([1, -1])
           y_distance = choice([0, 1, 2, 3, 4, 5, 6, 7])
           y_step = y_direction * y_distance
           
           if x_step == 0 and y_step == 0:
               continue
           
           x = self.x_value[-1] + x_step
           y = self.y_value[-1] + y_step
           
           self.x_value.append(x)
           self.y_value.append(y)

#画图
rw = RandomWalk()
rw.fill_walk()
plt.style.use('classic')
fig, ax = plt.subplots()
point_numbers = range(5000) #使用range()生成了一个数字列表,其中包含的数与漫步包含的点数量相同
ax.scatter(rw.x_value, rw.y_value, c= point_numbers, cmap = plt.cm.Blues, edgecolors = 'none', s = 5)

#突出起点和终点
ax.scatter(0, 0, c = 'green', edgecolors = 'none', s = 50)
ax.scatter(rw.x_value[-1], rw.y_value[-1], c = 'red', edgecolors = 'none', s = 50)

plt.show()

结果:

 注意:

所有格式的设置必须放在plt.show()之前,确保在其他点之上绘制起点和终点。

3. 隐藏坐标轴

示例:不要坐标轴

代码: 

from random import choice
import matplotlib.pyplot as plt

class RandomWalk:
    def __init__(self, num_point = 5000):
        #初始化随机漫步
        self.num_point = num_point
        
        #随机漫步始于(0,0)
        self.x_value = [0]
        self.y_value = [0]
        
    def fill_walk(self):
        #计算各点
       while len(self.x_value) < self.num_point:
           x_direction = choice([1, -1])
           x_distance = choice([0, 1, 2, 3, 4, 5, 6, 7])
           x_step = x_direction * x_distance
           
           y_direction = choice([1, -1])
           y_distance = choice([0, 1, 2, 3, 4, 5, 6, 7])
           y_step = y_direction * y_distance
           
           if x_step == 0 and y_step == 0:
               continue
           
           x = self.x_value[-1] + x_step
           y = self.y_value[-1] + y_step
           
           self.x_value.append(x)
           self.y_value.append(y)

#画图
rw = RandomWalk()
rw.fill_walk()
plt.style.use('classic')
fig, ax = plt.subplots()
point_numbers = range(5000) #使用range()生成了一个数字列表,其中包含的数与漫步包含的点数量相同
ax.scatter(rw.x_value, rw.y_value, c= point_numbers, cmap = plt.cm.Blues, edgecolors = 'none', s = 5)

#突出起点和终点
ax.scatter(0, 0, c = 'green', edgecolors = 'none', s = 50)
ax.scatter(rw.x_value[-1], rw.y_value[-1], c = 'red', edgecolors = 'none', s = 50)

#隐藏坐标轴
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)

plt.show()

 结果:

4. 增加点数

示例:将点数增加为50000

代码:

from random import choice
import matplotlib.pyplot as plt

class RandomWalk:
    def __init__(self, num_point = 5000):
        #初始化随机漫步
        self.num_point = num_point
        
        #随机漫步始于(0,0)
        self.x_value = [0]
        self.y_value = [0]
        
    def fill_walk(self):
        #计算各点
       while len(self.x_value) < self.num_point:
           x_direction = choice([1, -1])
           x_distance = choice([0, 1, 2, 3, 4, 5, 6, 7])
           x_step = x_direction * x_distance
           
           y_direction = choice([1, -1])
           y_distance = choice([0, 1, 2, 3, 4, 5, 6, 7])
           y_step = y_direction * y_distance
           
           if x_step == 0 and y_step == 0:
               continue
           
           x = self.x_value[-1] + x_step
           y = self.y_value[-1] + y_step
           
           self.x_value.append(x)
           self.y_value.append(y)

#画图
rw = RandomWalk(50000)
rw.fill_walk()
plt.style.use('classic')
fig, ax = plt.subplots()
point_numbers = range(50000) #使用range()生成了一个数字列表,其中包含的数与漫步包含的点数量相同
ax.scatter(rw.x_value, rw.y_value, c= point_numbers, cmap = plt.cm.Blues, edgecolors = 'none', s = 5)

#突出起点和终点
ax.scatter(0, 0, c = 'green', edgecolors = 'none', s = 50)
ax.scatter(rw.x_value[-1], rw.y_value[-1], c = 'red', edgecolors = 'none', s = 50)

#隐藏坐标轴
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)

plt.show()

结果:

 注意:

1. 更改点数时只需要在rw = RandomWalk(50000)进行设置即可,不需要改变类中__init__()方法中对num_point = 5000的初始化条件

2. 若使用range(5000),则记得要对里面的数进行改变,所以建议使用range(num_point),这样就不需要每次都改这部分了。

三、使用Plotly模拟掷骰子

1. 生成数据并进行统计

示例:假设一个骰子六面,即num_side = 6,投掷1000次,统计每一个点数出现的次数

代码:

from random import randint

class Die:
    def __init__(self, num_side = 6):
        self.num_side = num_side
        
    def roll(self):
        #返回一个位于1和骰子面数之间的随机值
        return randint(1, self.num_side)
 
#掷骰子,生成数据   
die = Die()
results = []
for roll_num in range(1000):
    result = die.roll()
    results.append(result)

#统计出现次数
frequencies = []
for rank in range(1, die.num_side + 1):
    frequency = results.count(rank)
    frequencies.append(frequency)
    
print(frequencies)

 结果:

[150, 141, 182, 188, 154, 185]

2. 绘制直方图

示例:

from random import randint
from plotly.graph_objs import Bar, Layout
from plotly import offline

class Die:
    def __init__(self, num_side = 6):
        self.num_side = num_side
        
    def roll(self):
        #返回一个位于1和骰子面数之间的随机值
        return randint(1, self.num_side)
 
#掷骰子,生成数据   
die = Die()
results = []
for roll_num in range(1000):
    result = die.roll()
    results.append(result)

#统计出现次数
frequencies = []
for rank in range(1, die.num_side + 1):
    frequency = results.count(rank)
    frequencies.append(frequency)
    
print(frequencies)

#数据可视化
x_value = list(range(1, die.num_side + 1))
data = [Bar(x = x_value, y = frequencies)]

x_axias_config = {'title': '结果'}
y_axias_config = {'title':'结果的频率'}
my_layout = Layout(title = '掷一个骰子1000次结果', xaxis = x_axias_config, yaxis = y_axias_config)
offline.plot({'data': data, 'layout': my_layout}, filename = 'd6.html')

 结果:

 注意:

(1)Plotly不能直接接受range()的结果,因此要用list()将其转换为列表。

(2)Bar()表示用于绘制条形图的数据集。它需要一个存储x和一个存储y 的列表。Bar必须放在方括号内。

3. 同时掷两个骰子

示例:

代码:

from random import randint
from plotly.graph_objs import Bar, Layout
from plotly import offline

class Die:
    def __init__(self, num_side = 6):
        self.num_side = num_side
        
    def roll(self):
        #返回一个位于1和骰子面数之间的随机值
        return randint(1, self.num_side)
 
#掷骰子,生成数据   
die_1 = Die()
die_2 = Die()
results = []
for roll_num in range(1000):
    result = die_1.roll() + die_2.roll()
    results.append(result)

#统计出现次数
frequencies = []
for rank in range(2, die_1.num_side +die_2.num_side + 1):
    frequency = results.count(rank)
    frequencies.append(frequency)
    
print(frequencies)

#数据可视化
x_value = list(range(2, die_1.num_side +die_2.num_side + 1))
data = [Bar(x = x_value, y = frequencies)]

x_axias_config = {'title': '结果'}
y_axias_config = {'title':'结果的频率'}
my_layout = Layout(title = '掷一个骰子1000次结果', xaxis = x_axias_config, yaxis = y_axias_config)
offline.plot({'data': data, 'layout': my_layout}, filename = 'd6.html')

结果:

注意:

(1)在统计出现的次数部分时,最小点数是2,不再是一开始的1

 (2)数据可视化与上面的类似,x轴也应该从2开始

四、练习

 15-6:

代码:

from random import randint
from plotly.graph_objs import Bar, Layout
from plotly import offline

class Die:
    def __init__(self, num_side = 8):
        #数据初始化
        self.num_side = num_side
        
    def throw(self):
        #返回1到点数之间的任意值
        return randint(1, self.num_side)
 
die_1 = Die()
die_2 = Die()
results = []
#将点数存储在results矩阵中
for num in range(5000):
    result = die_1.throw() + die_2.throw()
    results.append(result)

#统计次数
frequencies = []
for value in range (2, 17):
    frequency = results.count(value)
    frequencies.append(frequency)
print(frequencies)
    
#可视化结果
x_value = list(range(2, 17))
data = [Bar(x = x_value, y = frequencies)]
x_axis_config = {'title':'结果', 'dtick': 1}
y_axis_config = {'title':'频率'}
my_layout = Layout(title = '同时投掷两个8面骰子', xaxis = x_axis_config, yaxis = y_axis_config)
offline.plot({'data':data, 'layout': my_layout},filename = 'd8_d8.html')

由于做1000次实验结果不稳定,因此改为做5000次实验

结果:

15-7:

代码:

from random import randint
from plotly.graph_objs import Bar, Layout
from plotly import offline

class Die:
    def __init__(self, num_side = 8):
        #数据初始化
        self.num_side = num_side
        
    def throw(self):
        #返回1到点数之间的任意值
        return randint(1, self.num_side)
 
die_1 = Die(6)
die_2 = Die(6)
die_3 = Die(6)
results = []
#将点数存储在results矩阵中
for num in range(5000):
    result = die_1.throw() + die_2.throw() +die_3.throw()
    results.append(result)

#统计次数
frequencies = []
for value in range (3, 19):
    frequency = results.count(value)
    frequencies.append(frequency)
print(frequencies)
    
#可视化结果
x_value = list(range(3, 19))
data = [Bar(x = x_value, y = frequencies)]
x_axis_config = {'title':'结果', 'dtick': 1}
y_axis_config = {'title':'频率'}
my_layout = Layout(title = '同时投掷三个6面骰子', xaxis = x_axis_config, yaxis = y_axis_config)
offline.plot({'data':data, 'layout': my_layout},filename = 'd6_d6_d6.html')

 结果:

15-8:

代码:

from random import randint
from plotly.graph_objs import Bar, Layout
from plotly import offline

class Die:
    def __init__(self, num_side = 8):
        #数据初始化
        self.num_side = num_side
        
    def throw(self):
        #返回1到点数之间的任意值
        return randint(1, self.num_side)
 
die_1 = Die(6)
die_2 = Die(6)

results = []
#将点数存储在results矩阵中
for num in range(5000):
    result = die_1.throw() * die_2.throw()
    results.append(result)

#统计次数
frequencies = []
for value in range (1, 37):
    frequency = results.count(value)
    frequencies.append(frequency)
print(frequencies)
    
#可视化结果
x_value = list(range(1, 37))
data = [Bar(x = x_value, y = frequencies)]
x_axis_config = {'title':'结果', 'dtick': 1}
y_axis_config = {'title':'频率'}
my_layout = Layout(title = '同时投掷三个6面骰子', xaxis = x_axis_config, yaxis = y_axis_config)
offline.plot({'data':data, 'layout': my_layout},filename = 'd6_d6_d6.html')

 结果:


总结

随机漫步的意义:

个人理解的随即漫步更多的意义在于随机生成一些特定数量的点,重点在于生成数据。目前并不明白它的具体应用和意义是什么。

掷骰子的意义:

不懂!