import numpy as np import json import matplotlib.pyplot as plt from collections import defaultdict # 设置Matplotlib的默认字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 'SimHei' 是一种支持中文的字体 plt.rcParams['axes.unicode_minus'] = False # 正确显示负号 # 假设数据文件名为 'betting_data.txt',每行为一个时间戳和JSON数据 file_path = '开奖记录.log' index = 0 total_payout_by_bet_odd = 0 total_payout_by_settle = 0 result_option = [] bet_101 = 0 bet_102 = 0 options_pay_out = {} wrong_data_key = [] cacheRoundInfo = [] class RoundInfo: def __init__(self, key, _result_option, _options_pay_out, _total_payout_by_bet_odd, _total_payout_by_settle): self.key = key self.result_option = _result_option self.options_pay_out = _options_pay_out self.total_payout_by_bet_odd = _total_payout_by_bet_odd self.total_payout_by_settle = _total_payout_by_settle # json解析 RoundInfo class RoundInfoDecoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, RoundInfo): return f"{obj.key} odd结果:{obj.total_payout_by_bet_odd} 开奖结果:{obj.total_payout_by_settle} 一致数据可以保存用于分析" # Let the base class default method raise the TypeError return json.JSONEncoder.default(self, obj) def process_settle(key, data): global total_payout_by_settle, total_payout_by_bet_odd, result_option player_settle = data["playerSettle"] for player in player_settle: total_payout_by_settle += player["totalWinAmount"] other_players = data["otherPlayers"] total_payout_by_settle += other_players["totalWinAmount"] # 开奖结果 for result in data["optionResult"]: if result["result"] == 1: result_option_ = result["option"] result_option.append(result_option_) total_payout_by_bet_odd += options_pay_out[result_option_] def compare_obb_and_settle(key, data): global total_payout_by_settle, total_payout_by_bet_odd diff_value = (total_payout_by_settle - total_payout_by_bet_odd) / 100 diff_value = round(diff_value, 2) if diff_value != 0: print( f"{key} odd结果:{total_payout_by_bet_odd} 开奖结果:{total_payout_by_settle} 差值:{diff_value}¥ 数值不同不予计入,待删除") wrong_data_key.append(key) else: # print(f"{key} odd结果:{total_payout_by_bet_odd} 开奖结果:{total_payout_by_settle} 差值:{diff_value}¥") pass def save_and_clear(key): global bet_101, bet_102, total_payout_by_bet_odd, total_payout_by_settle, result_option if total_payout_by_settle == total_payout_by_bet_odd: # print(f"{key} odd结果:{total_payout_by_bet_odd} 开奖结果:{total_payout_by_settle} 一致数据可以保存用于分析") cacheRoundInfo.append( RoundInfo(key, result_option.copy(), options_pay_out.copy(), total_payout_by_bet_odd, total_payout_by_settle)) bet_101 = 0 bet_102 = 0 total_payout_by_bet_odd = 0 total_payout_by_settle = 0 options_pay_out.clear() result_option.clear() # 分析和绘图函数 def analyze_group_positions(round_info_list, group1, group2): # 存储每个中奖选项组合在排序后赔付列表中的位置 combination_positions = [] # 存储每个中奖选项在排序后赔付列表中的位置 positions_group1 = [] positions_group2 = [] for info in round_info_list: # 分别处理两组 group1_payouts = {k: info.options_pay_out[k] for k in group1 if k in info.options_pay_out} group2_payouts = {k: info.options_pay_out[k] for k in group2 if k in info.options_pay_out} # 排序 sorted_group1 = sorted(group1_payouts.items(), key=lambda x: x[1]) sorted_group2 = sorted(group2_payouts.items(), key=lambda x: x[1]) sorted_keys_group1 = [item[0] for item in sorted_group1] sorted_keys_group2 = [item[0] for item in sorted_group2] # 定位中奖选项 for res in info.result_option: if res in sorted_keys_group1: positions_group1.append(sorted_keys_group1.index(res) + 1) if res in sorted_keys_group2: positions_group2.append(sorted_keys_group2.index(res) + 1) # 创建所有可能的组合并计算赔付总额 combinations_payouts = {} for key1, payout1 in group1_payouts.items(): for key2, payout2 in group2_payouts.items(): combinations_payouts[(key1, key2)] = payout1 + payout2 # 对组合赔付总额进行排序 sorted_combinations = sorted(combinations_payouts.items(), key=lambda x: x[1]) sorted_combination_keys = [item[0] for item in sorted_combinations] # 获取实际开奖结果的组合位置 winning_combination = tuple(info.result_option) if winning_combination in sorted_combination_keys: position = sorted_combination_keys.index(winning_combination) + 1 combination_positions.append(position) # 绘制两个组的结果 plt.figure(figsize=(12, 6)) plt.subplot(1, 3, 1) # plt.hist(positions_group1, bins=len(group1), alpha=0.75, edgecolor='black', align='left', rwidth=0.5) plt.hist(positions_group1, bins=np.arange(1, len(group1) + 2) - 0.5, alpha=0.75, edgecolor='black') plt.xlabel('Position in Payout Sorting (Group 1)') plt.ylabel('Frequency') plt.title('Frequency of Winning Options in Group 1') plt.xticks(np.arange(1, len(group1) + 1)) plt.subplot(1, 3, 2) # plt.hist(positions_group2, bins=len(group2), alpha=0.75, edgecolor='black', align='left', rwidth=0.5) plt.hist(positions_group2, bins=np.arange(1, len(group2) + 2) - 0.5, alpha=0.75, edgecolor='black') plt.xlabel('Position in Payout Sorting (Group 2)') plt.ylabel('Frequency') plt.title('Frequency of Winning Options in Group 2') plt.xticks(np.arange(1, len(group2) + 1)) # 统计各个位置的频率 position_counts = defaultdict(int) for pos in combination_positions: position_counts[pos] += 1 # 统计各个位置的频率 total_positions = len(combination_positions) # 绘制频率图 positions, frequencies = zip(*sorted(position_counts.items())) plt.subplot(1, 3, 3) plt.bar(positions, frequencies, color='skyblue') plt.xlabel('Position in Combined Payout Sorting') plt.ylabel('频率') plt.title('奖金排名中获胜组合位置的频率') plt.xticks(positions) # 绘制频率图 frequencies_percentage = [f / total_positions * 100 for f in frequencies] bars = plt.bar(positions, frequencies_percentage, color='skyblue') # 在柱状图上添加百分比标签 for bar, freq in zip(bars, frequencies_percentage): yval = bar.get_height() plt.text(bar.get_x() + bar.get_width() / 2, yval, f'{freq:.2f}%', ha='center', va='bottom', fontsize=8) plt.tight_layout() plt.show() def parse_data_from_file(_file_path): clean_data(_file_path) delete_wrong_data(_file_path) # print(json.dumps(cacheRoundInfo, cls=RoundInfoDecoder)) # 定义两组选项 group1 = [101, 102, 103] group2 = [301, 302, 303, 304, 305] # 调用函数 analyze_group_positions(cacheRoundInfo, group1, group2) def delete_wrong_data(_file_path): print("错误数据key:", wrong_data_key) if not wrong_data_key: return # 删除文件的某一行以及上一行 with open(_file_path, "r", encoding="utf-8") as f: lines = f.readlines() with open(_file_path, "w", encoding="utf-8") as f_w: for line in lines: # line 不包含任意一个错误数据key if not any([i in line for i in wrong_data_key]): f_w.write(line) def clean_data(_file_path): global index with open(_file_path, 'r', encoding='utf-8') as file: for line in file: # print(line) line_strip = line.strip() line_strip = line_strip.replace("'", '"') line_strip = line_strip.replace("False", "false") line_strip = line_strip.replace("True", "true") timestamp = line_strip[:19] json_data = line_strip[20:] key = timestamp data = json.loads(json_data) if index % 2 == 0: process_obb(key, data) else: process_settle(key, data) compare_obb_and_settle(key, data) save_and_clear(key) index += 1 def process_obb(key, data): global total_payout_by_bet_odd, bet_101, bet_102 for item in data.values(): option_ = item["option"] odds_ = item["odds"] bet_ = item["total_bet"] odds__bet_ = odds_ * bet_ options_pay_out[option_] = round(odds__bet_, 2) if option_ == 101: bet_101 = bet_ elif option_ == 102: bet_102 = bet_ elif option_ == 103: options_pay_out[option_] = bet_101 + bet_102 # 开始解析文件 if __name__ == '__main__': parse_data_from_file(file_path)