Pandas数据分析实战:用快乐8历史数据,手把手教你做号码出现频率统计
Pandas数据分析实战:快乐8历史号码频率统计与可视化技巧
每次看到彩票开奖结果,你是否好奇哪些数字更常出现?作为数据分析师,我们可以用Python的Pandas库来揭示这些隐藏的规律。本文将带你从零开始,用快乐8历史数据构建完整的分析流程,不仅统计号码出现频率,还会教你如何用直观的图表呈现结果。
1. 数据准备与初步探索
快乐8每期开出20个号码,统计这些数字的出现频率能帮我们了解历史趋势。假设我们已经有了一个包含多期开奖数据的Excel文件(data/kl8.xlsx),现在开始分析工作。
首先加载必要的库并读取数据:
import pandas as pd import matplotlib.pyplot as plt # 读取原始数据 file_path = "data/kl8.xlsx" df = pd.read_excel(file_path, sheet_name='data') print(df.head())检查数据质量是首要步骤:
# 检查缺失值 print(df.isnull().sum()) # 检查数据类型 print(df.dtypes)常见数据问题处理技巧:
- 日期格式不一致 → 使用
pd.to_datetime()统一格式 - 号码列包含非数字字符 → 用
str.extract()提取纯数字 - 存在异常值(如号码>80)→ 用条件筛选定位问题数据
2. 号码频率统计的核心方法
2.1 单列基础统计
对单个号码位置(如red1)进行统计:
red1_counts = df['red1'].value_counts().sort_index() print(red1_counts.head())2.2 多列合并统计
更有效的方法是统计所有20个号码位置的整体出现频率:
# 收集所有号码列名 red_columns = [f'red{i}' for i in range(1, 21)] # 合并所有号码到一个Series all_numbers = pd.concat([df[col] for col in red_columns]) total_counts = all_numbers.value_counts().sort_index()2.3 统计结果保存
将统计结果保存到新的Excel工作表:
with pd.ExcelWriter(file_path, engine='openpyxl', mode='a') as writer: total_counts.to_excel(writer, sheet_name='frequency', header=['出现次数'])3. 高级统计分析与可视化
3.1 频率分布直方图
plt.figure(figsize=(12, 6)) total_counts.plot(kind='bar', width=0.8) plt.title('快乐8号码出现频率分布') plt.xlabel('号码') plt.ylabel('出现次数') plt.grid(axis='y') plt.show()3.2 热力图分析
分析号码在不同位置的出现情况:
position_matrix = pd.DataFrame() for col in red_columns: pos_counts = df[col].value_counts() position_matrix = position_matrix.join(pos_counts.rename(col), how='outer') plt.figure(figsize=(15, 8)) plt.imshow(position_matrix.fillna(0), cmap='YlOrRd') plt.colorbar() plt.xticks(range(20), red_columns) plt.yticks(range(1, 81)) plt.title('号码在不同位置的出现热力图') plt.show()3.3 冷热号码分析
定义冷热号码的标准:
| 类型 | 判断标准 | 数量 |
|---|---|---|
| 热号 | 出现次数 > 平均值+标准差 | 约15-20个 |
| 温号 | 平均值±标准差范围内 | 约40-50个 |
| 冷号 | 出现次数 < 平均值-标准差 | 约15-20个 |
计算代码:
mean_count = total_counts.mean() std_count = total_counts.std() hot_numbers = total_counts[total_counts > mean_count + std_count] cold_numbers = total_counts[total_counts < mean_count - std_count]4. 实战技巧与性能优化
4.1 大数据量处理技巧
当数据量较大时(如10万期以上),可以采用这些优化方法:
# 分块读取 chunk_size = 10000 counts_list = [] for chunk in pd.read_excel(file_path, chunksize=chunk_size): chunk_counts = pd.concat([chunk[col] for col in red_columns]).value_counts() counts_list.append(chunk_counts) # 合并分块结果 final_counts = pd.concat(counts_list).groupby(level=0).sum()4.2 使用Categorical类型优化
# 将号码转换为分类类型 all_numbers = all_numbers.astype('category') print(all_numbers.memory_usage(deep=True)) # 比较内存使用4.3 并行计算加速
对于超大数据集,可以使用Dask或modin.pandas:
# 使用modin加速 import modin.pandas as mpd mdf = mpd.read_excel(file_path) all_numbers = pd.concat([mdf[col] for col in red_columns])5. 扩展分析思路
5.1 号码组合分析
统计常见号码对的出现频率:
from itertools import combinations pair_counts = pd.Series(dtype=int) for _, row in df.iterrows(): numbers = sorted([row[col] for col in red_columns]) for pair in combinations(numbers, 2): pair_counts[pair] = pair_counts.get(pair, 0) + 1 top_pairs = pair_counts.sort_values(ascending=False).head(10)5.2 时间趋势分析
分析号码热度随时间的变化:
df['date'] = pd.to_datetime(df['date']) df['year'] = df['date'].dt.year yearly_counts = df.groupby('year').apply( lambda x: pd.concat([x[col] for col in red_columns]).value_counts() )5.3 间隔分析
计算号码两次出现之间的间隔期数:
number = 5 # 分析特定号码 appear_dates = df[pd.concat([df[col] == number for col in red_columns], axis=1).any(axis=1)]['date'] intervals = appear_dates.sort_values().diff().dt.days.dropna()