analysis2.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. import numpy as np
  2. import json
  3. import matplotlib.pyplot as plt
  4. from collections import defaultdict
  5. # 设置Matplotlib的默认字体
  6. plt.rcParams['font.sans-serif'] = ['SimHei'] # 'SimHei' 是一种支持中文的字体
  7. plt.rcParams['axes.unicode_minus'] = False # 正确显示负号
  8. # 假设数据文件名为 'betting_data.txt',每行为一个时间戳和JSON数据
  9. file_path = '开奖记录.log'
  10. index = 0
  11. total_payout_by_bet_odd = 0
  12. total_payout_by_settle = 0
  13. result_option = []
  14. bet_101 = 0
  15. bet_102 = 0
  16. options_pay_out = {}
  17. wrong_data_key = []
  18. cacheRoundInfo = []
  19. class RoundInfo:
  20. def __init__(self, key, _result_option, _options_pay_out, _total_payout_by_bet_odd, _total_payout_by_settle):
  21. self.key = key
  22. self.result_option = _result_option
  23. self.options_pay_out = _options_pay_out
  24. self.total_payout_by_bet_odd = _total_payout_by_bet_odd
  25. self.total_payout_by_settle = _total_payout_by_settle
  26. # json解析 RoundInfo
  27. class RoundInfoDecoder(json.JSONEncoder):
  28. def default(self, obj):
  29. if isinstance(obj, RoundInfo):
  30. return f"{obj.key} odd结果:{obj.total_payout_by_bet_odd} 开奖结果:{obj.total_payout_by_settle} 一致数据可以保存用于分析"
  31. # Let the base class default method raise the TypeError
  32. return json.JSONEncoder.default(self, obj)
  33. def process_settle(key, data):
  34. global total_payout_by_settle, total_payout_by_bet_odd, result_option
  35. player_settle = data["playerSettle"]
  36. for player in player_settle:
  37. total_payout_by_settle += player["totalWinAmount"]
  38. other_players = data["otherPlayers"]
  39. total_payout_by_settle += other_players["totalWinAmount"]
  40. # 开奖结果
  41. for result in data["optionResult"]:
  42. if result["result"] == 1:
  43. result_option_ = result["option"]
  44. result_option.append(result_option_)
  45. total_payout_by_bet_odd += options_pay_out[result_option_]
  46. def compare_obb_and_settle(key, data):
  47. global total_payout_by_settle, total_payout_by_bet_odd
  48. diff_value = (total_payout_by_settle - total_payout_by_bet_odd) / 100
  49. diff_value = round(diff_value, 2)
  50. if diff_value != 0:
  51. print(
  52. f"{key} odd结果:{total_payout_by_bet_odd} 开奖结果:{total_payout_by_settle} 差值:{diff_value}¥ 数值不同不予计入,待删除")
  53. wrong_data_key.append(key)
  54. else:
  55. # print(f"{key} odd结果:{total_payout_by_bet_odd} 开奖结果:{total_payout_by_settle} 差值:{diff_value}¥")
  56. pass
  57. def save_and_clear(key):
  58. global bet_101, bet_102, total_payout_by_bet_odd, total_payout_by_settle, result_option
  59. if total_payout_by_settle == total_payout_by_bet_odd:
  60. # print(f"{key} odd结果:{total_payout_by_bet_odd} 开奖结果:{total_payout_by_settle} 一致数据可以保存用于分析")
  61. cacheRoundInfo.append(
  62. RoundInfo(key, result_option.copy(), options_pay_out.copy(), total_payout_by_bet_odd,
  63. total_payout_by_settle))
  64. bet_101 = 0
  65. bet_102 = 0
  66. total_payout_by_bet_odd = 0
  67. total_payout_by_settle = 0
  68. options_pay_out.clear()
  69. result_option.clear()
  70. # 分析和绘图函数
  71. def analyze_group_positions(round_info_list, group1, group2):
  72. # 存储每个中奖选项组合在排序后赔付列表中的位置
  73. combination_positions = []
  74. # 存储每个中奖选项在排序后赔付列表中的位置
  75. positions_group1 = []
  76. positions_group2 = []
  77. for info in round_info_list:
  78. # 分别处理两组
  79. group1_payouts = {k: info.options_pay_out[k] for k in group1 if k in info.options_pay_out}
  80. group2_payouts = {k: info.options_pay_out[k] for k in group2 if k in info.options_pay_out}
  81. # 排序
  82. sorted_group1 = sorted(group1_payouts.items(), key=lambda x: x[1])
  83. sorted_group2 = sorted(group2_payouts.items(), key=lambda x: x[1])
  84. sorted_keys_group1 = [item[0] for item in sorted_group1]
  85. sorted_keys_group2 = [item[0] for item in sorted_group2]
  86. # 定位中奖选项
  87. for res in info.result_option:
  88. if res in sorted_keys_group1:
  89. positions_group1.append(sorted_keys_group1.index(res) + 1)
  90. if res in sorted_keys_group2:
  91. positions_group2.append(sorted_keys_group2.index(res) + 1)
  92. # 创建所有可能的组合并计算赔付总额
  93. combinations_payouts = {}
  94. for key1, payout1 in group1_payouts.items():
  95. for key2, payout2 in group2_payouts.items():
  96. combinations_payouts[(key1, key2)] = payout1 + payout2
  97. # 对组合赔付总额进行排序
  98. sorted_combinations = sorted(combinations_payouts.items(), key=lambda x: x[1])
  99. sorted_combination_keys = [item[0] for item in sorted_combinations]
  100. # 获取实际开奖结果的组合位置
  101. winning_combination = tuple(info.result_option)
  102. if winning_combination in sorted_combination_keys:
  103. position = sorted_combination_keys.index(winning_combination) + 1
  104. combination_positions.append(position)
  105. # 绘制两个组的结果
  106. plt.figure(figsize=(12, 6))
  107. plt.subplot(1, 3, 1)
  108. # plt.hist(positions_group1, bins=len(group1), alpha=0.75, edgecolor='black', align='left', rwidth=0.5)
  109. plt.hist(positions_group1, bins=np.arange(1, len(group1) + 2) - 0.5, alpha=0.75, edgecolor='black')
  110. plt.xlabel('Position in Payout Sorting (Group 1)')
  111. plt.ylabel('Frequency')
  112. plt.title('Frequency of Winning Options in Group 1')
  113. plt.xticks(np.arange(1, len(group1) + 1))
  114. plt.subplot(1, 3, 2)
  115. # plt.hist(positions_group2, bins=len(group2), alpha=0.75, edgecolor='black', align='left', rwidth=0.5)
  116. plt.hist(positions_group2, bins=np.arange(1, len(group2) + 2) - 0.5, alpha=0.75, edgecolor='black')
  117. plt.xlabel('Position in Payout Sorting (Group 2)')
  118. plt.ylabel('Frequency')
  119. plt.title('Frequency of Winning Options in Group 2')
  120. plt.xticks(np.arange(1, len(group2) + 1))
  121. # 统计各个位置的频率
  122. position_counts = defaultdict(int)
  123. for pos in combination_positions:
  124. position_counts[pos] += 1
  125. # 统计各个位置的频率
  126. total_positions = len(combination_positions)
  127. # 绘制频率图
  128. positions, frequencies = zip(*sorted(position_counts.items()))
  129. plt.subplot(1, 3, 3)
  130. plt.bar(positions, frequencies, color='skyblue')
  131. plt.xlabel('Position in Combined Payout Sorting')
  132. plt.ylabel('频率')
  133. plt.title('奖金排名中获胜组合位置的频率')
  134. plt.xticks(positions)
  135. # 绘制频率图
  136. frequencies_percentage = [f / total_positions * 100 for f in frequencies]
  137. bars = plt.bar(positions, frequencies_percentage, color='skyblue')
  138. # 在柱状图上添加百分比标签
  139. for bar, freq in zip(bars, frequencies_percentage):
  140. yval = bar.get_height()
  141. plt.text(bar.get_x() + bar.get_width() / 2, yval, f'{freq:.2f}%', ha='center', va='bottom', fontsize=8)
  142. plt.tight_layout()
  143. plt.show()
  144. def parse_data_from_file(_file_path):
  145. clean_data(_file_path)
  146. delete_wrong_data(_file_path)
  147. # print(json.dumps(cacheRoundInfo, cls=RoundInfoDecoder))
  148. # 定义两组选项
  149. group1 = [101, 102, 103]
  150. group2 = [301, 302, 303, 304, 305]
  151. # 调用函数
  152. analyze_group_positions(cacheRoundInfo, group1, group2)
  153. def delete_wrong_data(_file_path):
  154. print("错误数据key:", wrong_data_key)
  155. if not wrong_data_key:
  156. return
  157. # 删除文件的某一行以及上一行
  158. with open(_file_path, "r", encoding="utf-8") as f:
  159. lines = f.readlines()
  160. with open(_file_path, "w", encoding="utf-8") as f_w:
  161. for line in lines:
  162. # line 不包含任意一个错误数据key
  163. if not any([i in line for i in wrong_data_key]):
  164. f_w.write(line)
  165. def clean_data(_file_path):
  166. global index
  167. with open(_file_path, 'r', encoding='utf-8') as file:
  168. for line in file:
  169. # print(line)
  170. line_strip = line.strip()
  171. line_strip = line_strip.replace("'", '"')
  172. line_strip = line_strip.replace("False", "false")
  173. line_strip = line_strip.replace("True", "true")
  174. timestamp = line_strip[:19]
  175. json_data = line_strip[20:]
  176. key = timestamp
  177. data = json.loads(json_data)
  178. if index % 2 == 0:
  179. process_obb(key, data)
  180. else:
  181. process_settle(key, data)
  182. compare_obb_and_settle(key, data)
  183. save_and_clear(key)
  184. index += 1
  185. def process_obb(key, data):
  186. global total_payout_by_bet_odd, bet_101, bet_102
  187. for item in data.values():
  188. option_ = item["option"]
  189. odds_ = item["odds"]
  190. bet_ = item["total_bet"]
  191. odds__bet_ = odds_ * bet_
  192. options_pay_out[option_] = round(odds__bet_, 2)
  193. if option_ == 101:
  194. bet_101 = bet_
  195. elif option_ == 102:
  196. bet_102 = bet_
  197. elif option_ == 103:
  198. options_pay_out[option_] = bet_101 + bet_102
  199. # 开始解析文件
  200. if __name__ == '__main__':
  201. parse_data_from_file(file_path)