Python分析一下双色球,中大奖指日可待!

简介: Python分析一下双色球,中大奖指日可待!

一、需求简介


之前偶然见到一位网友提出了关于双色球数据的分析需求,感觉颇有趣味,便着手操作了一番。如下为某双色球发布站的页面,可以看到每期会产生红/蓝两种颜色的数字,其中红球为 33 选 6,蓝球为 16 选 1,一共是从 49 个球中选 7 个。假如想对某一色号球下注,比如红1 球,要先分析一下该球以往的产出情况。


12.png


可以从以下 3 个方面来分析,以史明鉴,看看最新一期是否值得选取该球:


1、遗漏情况


统计遗漏 n 期后命中的次数,如上图:遗漏 1 期后中的次数有 2 次,遗漏 2 期后中的次数有 1 次,遗漏 5 期后中的次数有 2 次,遗漏 7 期后中的次数有 1 次。


13.png


2、连续重号情况


如图,连续重号 3 期的有 1 次。


14.png


3、重号前的遗漏情况


如图,重号前遗漏 2 期的有 1 次。



15.png


二、源数据


节选源数据如下,数据是以 html 表格形式储存的,<td> 标签中 class="yl01" 表示未命中,class="chartBall01" 表示命中红球,class="chartBall02" 表示命中蓝球(文末获取近 100 期数据样本)。


<tr>
    <td class="c_fbf5e3 bd_rt_a">2021090</td>
    <td class="yl01" style="font-size:xx-small">1</td>
    <td class="yl01" style="font-size:xx-small">1</td>
    <td class="yl01" style="font-size:xx-small">8</td>
    <td class="yl01" style="font-size:xx-small">2</td>
    <td class="chartBall01">05</td>
    <td class="chartBall01">06</td>
    <td class="yl01" style="font-size:xx-small">1</td>
    <td class="yl01" style="font-size:xx-small">4</td>
    <td class="yl01" style="font-size:xx-small">6</td>
    <td class="yl01" style="font-size:xx-small">4</td>
    <td class="yl01" style="font-size:xx-small">5</td>
    <td class="chartBall01">12</td>
    <td class="yl01" style="font-size:xx-small">1</td>
    <td class="chartBall01">14</td>
    <td class="yl01" style="font-size:xx-small">2</td>
    <td class="yl01" style="font-size:xx-small">2</td>
    <td class="yl01" style="font-size:xx-small">13</td>
    <td class="yl01" style="font-size:xx-small">9</td>
    <td class="yl01" style="font-size:xx-small">2</td>
    <td class="yl01" style="font-size:xx-small">5</td>
    <td class="yl01" style="font-size:xx-small">6</td>
    <td class="yl01" style="font-size:xx-small">9</td>
    <td class="yl01" style="font-size:xx-small">1</td>
    <td class="yl01" style="font-size:xx-small">1</td>
    <td class="yl01" style="font-size:xx-small">7</td>
    <td class="yl01" style="font-size:xx-small">2</td>
    <td class="chartBall01">27</td>
    <td class="chartBall01">28</td>
    <td class="yl01" style="font-size:xx-small">4</td>
    <td class="yl01" style="font-size:xx-small">13</td>
    <td class="yl01" style="font-size:xx-small">12</td>
    <td class="yl01" style="font-size:xx-small">8</td>
    <td class="yl01" style="font-size:xx-small">7</td>
    <td class="v_line"></td>
    <td class="yl01" style="font-size:xx-small">4</td>
    <td class="yl01" style="font-size:xx-small">5</td>
    <td class="yl01" style="font-size:xx-small">42</td>
    <td class="yl01" style="font-size:xx-small">3</td>
    <td class="yl01" style="font-size:xx-small">8</td>
    <td class="yl01" style="font-size:xx-small">2</td>
    <td class="yl01" style="font-size:xx-small">16</td>
    <td class="chartBall02">08</td>
    <td class="yl01" style="font-size:xx-small">10</td>
    <td class="yl01" style="font-size:xx-small">13</td>
    <td class="yl01" style="font-size:xx-small">54</td>
    <td class="yl01" style="font-size:xx-small">1</td>
    <td class="yl01" style="font-size:xx-small">11</td>
    <td class="yl01" style="font-size:xx-small">31</td>
    <td class="yl01" style="font-size:xx-small">18</td>
    <td class="yl01" style="font-size:xx-small">25</td>
</tr>
<tr>
    <td class="c_fbf5e3 bd_rt_a">2021091</td>
    <td class="yl01" style="font-size:xx-small">2</td>
    <td class="yl01" style="font-size:xx-small">2</td>
    <td class="yl01" style="font-size:xx-small">9</td>
    <td class="chartBall01">04</td>
    <td class="yl01" style="font-size:xx-small">1</td>
    <td class="chartBall01">06</td>
    <td class="yl01" style="font-size:xx-small">2</td>
    <td class="yl01" style="font-size:xx-small">5</td>
    <td class="yl01" style="font-size:xx-small">7</td>
    <td class="yl01" style="font-size:xx-small">5</td>
    <td class="yl01" style="font-size:xx-small">6</td>
    <td class="yl01" style="font-size:xx-small">1</td>
    <td class="yl01" style="font-size:xx-small">2</td>
    <td class="yl01" style="font-size:xx-small">1</td>
    <td class="yl01" style="font-size:xx-small">3</td>
    <td class="chartBall01">16</td>
    <td class="yl01" style="font-size:xx-small">14</td>
    <td class="yl01" style="font-size:xx-small">10</td>
    <td class="yl01" style="font-size:xx-small">3</td>
    <td class="yl01" style="font-size:xx-small">6</td>
    <td class="yl01" style="font-size:xx-small">7</td>
    <td class="yl01" style="font-size:xx-small">10</td>
    <td class="yl01" style="font-size:xx-small">2</td>
    <td class="chartBall01">24</td>
    <td class="yl01" style="font-size:xx-small">8</td>
    <td class="chartBall01">26</td>
    <td class="yl01" style="font-size:xx-small">1</td>
    <td class="yl01" style="font-size:xx-small">1</td>
    <td class="yl01" style="font-size:xx-small">5</td>
    <td class="yl01" style="font-size:xx-small">14</td>
    <td class="yl01" style="font-size:xx-small">13</td>
    <td class="yl01" style="font-size:xx-small">9</td>
    <td class="chartBall01">33</td>
    <td class="v_line"></td>
    <td class="yl01" style="font-size:xx-small">5</td>
    <td class="yl01" style="font-size:xx-small">6</td>
    <td class="yl01" style="font-size:xx-small">43</td>
    <td class="yl01" style="font-size:xx-small">4</td>
    <td class="yl01" style="font-size:xx-small">9</td>
    <td class="yl01" style="font-size:xx-small">3</td>
    <td class="yl01" style="font-size:xx-small">17</td>
    <td class="yl01" style="font-size:xx-small">1</td>
    <td class="yl01" style="font-size:xx-small">11</td>
    <td class="yl01" style="font-size:xx-small">14</td>
    <td class="yl01" style="font-size:xx-small">55</td>
    <td class="yl01" style="font-size:xx-small">2</td>
    <td class="yl01" style="font-size:xx-small">12</td>
    <td class="yl01" style="font-size:xx-small">32</td>
    <td class="yl01" style="font-size:xx-small">19</td>
    <td class="chartBall02">16</td>
</tr>


三、解析实现


1、数据结构


为了便于表示球的命中与颜色、数值,我们可以按以下规则映射:


微信图片_20220617142527.png


那么先用美丽汤把需要的内容捞出来,把所有 <td> 标签中表示名字与色号的内容取出,按上述规则映射表示。


soup = BeautifulSoup(res_table, "html.parser")
item_lst = []
for td in soup.find_all('td'):
  cls = td['class'][0]
  num = td.string
  if cls in ['yl01', 'chartBall01', 'chartBall02']:
      item_lst.append('-'.join([cls, num]))
print(item_lst[:10])


输出前 10 个预览如下:


['yl01-3', 'yl01-5', 'chartBall01-03', 'yl01-5', 'yl01-1', 'yl01-5', 'chartBall01-07', 'yl01-9', 'yl01-6', 'yl01-6']


但这仅仅是一个超长列表,在此基础上处理起来还找不到头绪,至少要转变成和网页上结构一致的矩阵才好理解吧,那么可以想到利用 numpy 矩阵。先是用 np.array 将普通列表转为 numpy 数组,再利用 reshape 将一维数组转为二维数组,即 100 期 X 49 个球的矩阵。


array = np.array(item_lst).reshape(100, 49)


如图,numpy 矩阵的每一行与原页面结构对应。


16.png


但我们想要进行的是纵向比较分析,比较各期之间的关系,所以还需要再对矩阵进行行列转置。


array_T = array.T  # 矩阵转置,一个元素对应一列


17.png


此时,array_T 中的每一个元素即表示某一色号的近 100 期情况。如果想看红1 球,则是 array_T[0];如果想看红2 球,则是 array_T[1];如果想看蓝1 球,则是 array_T[33](因为红球总共有 33 个,故第一个蓝球列的索引为 33)。为了便于选球,我们可以写一个映射方法:


def trans_col(txt):# 翻译列索引号,如红1=0,红33=32,蓝1=33,蓝16=48
    if"红"in txt:
        col = int(txt.replace('红', '')) - 1
    else:
        col = int(txt.replace('蓝', '')) + 32
    return col

接下来就可以正式开始实现统计分析的需求啦!


2、遗漏统计


将转置矩阵和指定色号球所在列传入,获取该列后加入一个结束标记,因至少要出现 1 次未命中 +1 次命中才判定为遗漏 1 期,所以从该列的第二项数据开始判断,若其不等于前一项的值,且当前项为命中,则记录前一项的值(遗漏期数)。之后将记录列表中的表示遗漏的标记 yl01 去除,仅保留期数。


def fun_miss(array, col):# 统计该列中遗漏后命中的次数
    line = array[col].tolist()
    order_grp = []
    for i, v in enumerate(line):
        if i > 0:
            if v != line[i - 1] and'chart'in v:
                order_grp.append(line[i - 1])
    order_grp = [i.replace('yl01-', '') for i in order_grp]
    c = dict(Counter(order_grp))
    result = sorted(c.items(), key=lambda x: int(x[0]))
    for i in result:
        print(f"遗漏{i[0]}期后中的次数有{i[1]}次")
fun_miss(array_T, trans_col("红1"))  # 执行



18.png


统计排序后输出如下:

遗漏1期后中的次数有4次 遗漏2期后中的次数有2次 遗漏3期后中的次数有3次 遗漏5期后中的次数有2次 遗漏7期后中的次数有2次 遗漏8期后中的次数有1次 遗漏9期后中的次数有2次 遗漏13期后中的次数有1次


3、连续重号统计


与遗漏统计相同,传入两个参数,先确定要选取的色号列。当前项等于前一项,且当前项为命中时表示重号,连续重号时 count 计数 +1,当出现不满足重号条件时表示连续重号中断,记录连续次数,并将计数清零,待下一轮重号出现时重新计数。


def fun_repeat(array, col):# 统计该列中的重号次数
    line = array[col].tolist()
    count_grp = []
    count = 0
    for i, v in enumerate(line):
        if i > 0:
            if v == line[i-1] and'chart'in v:
                count += 1
            elif count > 0:
                count_grp.append(count)
                count = 0
    c = dict(Counter(count_grp))
    result = sorted(c.items(), key=lambda x: x[0])
    for i in result:
        print(f"连续重号{i[0]}次的有{i[1]}次")
fun_repeat(wt, trans_col("红2"))  # 执行



19.png


统计排序后输出如下:

连续重号1次的有1次 连续重号2次的有1次


4、重号前的遗漏统计


因要出现重号+遗漏才算入,所以至少从第三项数据开始判定。


def fun_return(array, col):# 统计该列中重号前的遗漏次数
    line = array[col].tolist()
    order_grp = []
    for i, v in enumerate(line):
        if i > 1:
            if v == line[i - 1] and v != line[i - 2] and'chart'in v:
                order_grp.append(line[i - 2])
    order_grp = [i.replace('yl01-', '') for i in order_grp]
    c = dict(Counter(order_grp))
    result = sorted(c.items(), key=lambda x: int(x[0]))
    for i in result:
        print(f"重号前遗漏{i[0]}期的有{i[1]}次")
fun_return(wt, trans_col("红1"))  # 执行



19.png


统计排序后输出如下:

重号前遗漏2期的有1次


四、小结


点击下方[在看],即可找志斌领取源数据和完整代码哈~

相关文章
|
9天前
|
缓存 Rust 算法
从混沌到秩序:Python的依赖管理工具分析
Python 的依赖管理工具一直没有标准化,主要原因包括历史发展的随意性、社区的分散性、多样化的使用场景、向后兼容性的挑战、缺乏统一治理以及生态系统的快速变化。依赖管理工具用于处理项目中的依赖关系,确保不同环境下的依赖项一致性,避免软件故障和兼容性问题。常用的 Python 依赖管理工具如 pip、venv、pip-tools、Pipenv、Poetry 等各有优缺点,选择时需根据项目需求权衡。新工具如 uv 和 Pixi 在性能和功能上有所改进,值得考虑。
62 35
|
2月前
|
机器学习/深度学习 数据采集 TensorFlow
使用Python实现智能食品消费模式分析的深度学习模型
使用Python实现智能食品消费模式分析的深度学习模型
145 70
|
17天前
|
机器学习/深度学习 数据可视化 数据挖掘
使用Python实现基于矩阵分解的长期事件(MFLEs)时间序列分析
在现代数据分析中,高维时间序列数据的处理和预测极具挑战性。基于矩阵分解的长期事件(MFLEs)分析技术应运而生,通过降维和时间序列特性结合,有效应对大规模数据。MFLE利用矩阵分解提取潜在特征,降低计算复杂度,过滤噪声,并发现主要模式。相比传统方法如ARIMA和深度学习模型如LSTM,MFLE在多变量处理、计算效率和可解释性上更具优势。通过合理应用MFLE,可在物联网、金融等领域获得良好分析效果。
34 0
使用Python实现基于矩阵分解的长期事件(MFLEs)时间序列分析
|
11天前
|
数据采集 数据可视化 数据挖掘
金融波动率的多模型建模研究:GARCH族与HAR模型的Python实现与对比分析
本文探讨了金融资产波动率建模中的三种主流方法:GARCH、GJR-GARCH和HAR模型,基于SPY的实际交易数据进行实证分析。GARCH模型捕捉波动率聚类特征,GJR-GARCH引入杠杆效应,HAR整合多时间尺度波动率信息。通过Python实现模型估计与性能比较,展示了各模型在风险管理、衍生品定价等领域的应用优势。
136 65
金融波动率的多模型建模研究:GARCH族与HAR模型的Python实现与对比分析
|
3月前
|
数据采集 缓存 定位技术
网络延迟对Python爬虫速度的影响分析
网络延迟对Python爬虫速度的影响分析
|
20天前
|
数据可视化 算法 数据挖掘
Python时间序列分析工具Aeon使用指南
**Aeon** 是一个遵循 scikit-learn API 风格的开源 Python 库,专注于时间序列处理。它提供了分类、回归、聚类、预测建模和数据预处理等功能模块,支持多种算法和自定义距离度量。Aeon 活跃开发并持续更新至2024年,与 pandas 1.4.0 版本兼容,内置可视化工具,适合数据探索和基础分析任务。尽管在高级功能和性能优化方面有提升空间,但其简洁的 API 和完整的基础功能使其成为时间序列分析的有效工具。
66 37
Python时间序列分析工具Aeon使用指南
|
15天前
|
机器学习/深度学习 运维 数据可视化
Python时间序列分析:使用TSFresh进行自动化特征提取
TSFresh 是一个专门用于时间序列数据特征自动提取的框架,支持分类、回归和异常检测等机器学习任务。它通过自动化特征工程流程,处理数百个统计特征(如均值、方差、自相关性等),并通过假设检验筛选显著特征,提升分析效率。TSFresh 支持单变量和多变量时间序列数据,能够与 scikit-learn 等库无缝集成,适用于大规模时间序列数据的特征提取与模型训练。其工作流程包括数据格式转换、特征提取和选择,并提供可视化工具帮助理解特征分布及与目标变量的关系。
55 16
Python时间序列分析:使用TSFresh进行自动化特征提取
|
2月前
|
机器学习/深度学习 数据采集 TensorFlow
使用Python实现智能食品消费习惯分析的深度学习模型
使用Python实现智能食品消费习惯分析的深度学习模型
161 68
|
14天前
|
数据采集 缓存 API
python爬取Boss直聘,分析北京招聘市场
本文介绍了如何使用Python爬虫技术从Boss直聘平台上获取深圳地区的招聘数据,并进行数据分析,以帮助求职者更好地了解市场动态和职位需求。
|
2月前
|
机器学习/深度学习 数据采集 数据挖掘
使用Python实现智能食品消费市场分析的深度学习模型
使用Python实现智能食品消费市场分析的深度学习模型
138 36

热门文章

最新文章