This repository contains a comprehensive Eurojackpot lottery analysis and prediction system including: - Historical data analysis and processing - ML-based prediction models - Automated weekly tip generation - Position and range analysis tools - Notification system for results 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
209 lines
7.9 KiB
Python
209 lines
7.9 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Eurojackpot Positionsanalyse
|
|
|
|
Analysiert, welche Bereiche an welchen Positionen (Z1, Z2, Z3, Z4, Z5) am häufigsten stehen.
|
|
"""
|
|
|
|
import pandas as pd
|
|
from collections import defaultdict
|
|
import numpy as np
|
|
|
|
def get_range_for_number(number):
|
|
"""Bestimmt den Bereich für eine gegebene Zahl."""
|
|
if 1 <= number <= 10:
|
|
return 'A(1-10)'
|
|
elif 11 <= number <= 20:
|
|
return 'B(11-20)'
|
|
elif 21 <= number <= 30:
|
|
return 'C(21-30)'
|
|
elif 31 <= number <= 40:
|
|
return 'D(31-40)'
|
|
elif 41 <= number <= 50:
|
|
return 'E(41-50)'
|
|
else:
|
|
return 'Unknown'
|
|
|
|
def analyze_positions():
|
|
"""Führt eine detaillierte Positionsanalyse durch."""
|
|
|
|
# Daten laden
|
|
df = pd.read_csv("/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/data/AlleEurojackpotzahlen.csv", sep=';')
|
|
|
|
print(f"🎯 EUROJACKPOT POSITIONSANALYSE")
|
|
print(f"Anzahl analysierte Ziehungen: {len(df)}")
|
|
print("="*60)
|
|
|
|
# Positionen definieren
|
|
positions = ['Z1', 'Z2', 'Z3', 'Z4', 'Z5']
|
|
ranges = ['A(1-10)', 'B(11-20)', 'C(21-30)', 'D(31-40)', 'E(41-50)']
|
|
|
|
# Matrix für Positions-Bereich-Kombinationen
|
|
position_range_matrix = defaultdict(lambda: defaultdict(int))
|
|
|
|
# Daten sammeln
|
|
for _, row in df.iterrows():
|
|
for pos in positions:
|
|
range_name = get_range_for_number(row[pos])
|
|
position_range_matrix[pos][range_name] += 1
|
|
|
|
# 1. Übersichtstabelle erstellen
|
|
print(f"\n📊 POSITIONS-BEREICH-MATRIX:")
|
|
print("="*60)
|
|
print(f"{'Position':<8} {'A(1-10)':<12} {'B(11-20)':<12} {'C(21-30)':<12} {'D(31-40)':<12} {'E(41-50)':<12}")
|
|
print("-" * 60)
|
|
|
|
for pos in positions:
|
|
line = f"{pos:<8} "
|
|
for range_name in ranges:
|
|
count = position_range_matrix[pos][range_name]
|
|
percentage = (count / len(df)) * 100
|
|
line += f"{count:3}({percentage:4.1f}%) "
|
|
print(line)
|
|
|
|
# 2. Beste Bereiche pro Position
|
|
print(f"\n🏆 BESTE BEREICHE PRO POSITION:")
|
|
print("="*40)
|
|
|
|
for pos in positions:
|
|
best_range = max(ranges, key=lambda r: position_range_matrix[pos][r])
|
|
best_count = position_range_matrix[pos][best_range]
|
|
best_percentage = (best_count / len(df)) * 100
|
|
|
|
# Alle Bereiche für diese Position sortiert
|
|
sorted_ranges = sorted(ranges, key=lambda r: position_range_matrix[pos][r], reverse=True)
|
|
|
|
print(f"\n{pos}: {best_range} führt mit {best_count} ({best_percentage:.1f}%)")
|
|
print(f" Ranking: ", end="")
|
|
for i, range_name in enumerate(sorted_ranges, 1):
|
|
count = position_range_matrix[pos][range_name]
|
|
percentage = (count / len(df)) * 100
|
|
print(f"{i}.{range_name}({percentage:.1f}%)", end="")
|
|
if i < len(sorted_ranges):
|
|
print(" > ", end="")
|
|
print()
|
|
|
|
# 3. Beste Positionen pro Bereich
|
|
print(f"\n🎯 BESTE POSITIONEN PRO BEREICH:")
|
|
print("="*40)
|
|
|
|
for range_name in ranges:
|
|
best_position = max(positions, key=lambda p: position_range_matrix[p][range_name])
|
|
best_count = position_range_matrix[best_position][range_name]
|
|
best_percentage = (best_count / len(df)) * 100
|
|
|
|
# Alle Positionen für diesen Bereich sortiert
|
|
sorted_positions = sorted(positions, key=lambda p: position_range_matrix[p][range_name], reverse=True)
|
|
|
|
print(f"\n{range_name}: Position {best_position} führt mit {best_count} ({best_percentage:.1f}%)")
|
|
print(f" Ranking: ", end="")
|
|
for i, pos in enumerate(sorted_positions, 1):
|
|
count = position_range_matrix[pos][range_name]
|
|
percentage = (count / len(df)) * 100
|
|
print(f"{i}.{pos}({percentage:.1f}%)", end="")
|
|
if i < len(sorted_positions):
|
|
print(" > ", end="")
|
|
print()
|
|
|
|
# 4. Spezielle Analysen
|
|
print(f"\n📈 SPEZIELLE POSITIONSANALYSEN:")
|
|
print("="*45)
|
|
|
|
# Niedrige vs. hohe Bereiche pro Position
|
|
for pos in positions:
|
|
low_ranges = position_range_matrix[pos]['A(1-10)'] + position_range_matrix[pos]['B(11-20)']
|
|
high_ranges = position_range_matrix[pos]['D(31-40)'] + position_range_matrix[pos]['E(41-50)']
|
|
middle_range = position_range_matrix[pos]['C(21-30)']
|
|
|
|
low_pct = (low_ranges / len(df)) * 100
|
|
high_pct = (high_ranges / len(df)) * 100
|
|
middle_pct = (middle_range / len(df)) * 100
|
|
|
|
print(f"{pos}: Niedrig(A+B)={low_pct:4.1f}% | Mitte(C)={middle_pct:4.1f}% | Hoch(D+E)={high_pct:4.1f}%")
|
|
|
|
# 5. Gleichverteilungs-Analyse
|
|
print(f"\n⚖️ GLEICHVERTEILUNGS-ANALYSE:")
|
|
print("="*35)
|
|
|
|
expected_per_range = len(df) / 5 # Erwartete Gleichverteilung
|
|
|
|
print(f"Erwartete Gleichverteilung pro Bereich und Position: {expected_per_range:.1f}")
|
|
print(f"\nAbweichungen von der Gleichverteilung:")
|
|
|
|
for pos in positions:
|
|
print(f"\n{pos}:")
|
|
for range_name in ranges:
|
|
actual = position_range_matrix[pos][range_name]
|
|
deviation = actual - expected_per_range
|
|
deviation_pct = (deviation / expected_per_range) * 100
|
|
|
|
symbol = "📈" if deviation > 0 else "📉" if deviation < 0 else "⚖️"
|
|
print(f" {range_name}: {actual:3} ({deviation:+4.1f}, {deviation_pct:+5.1f}%) {symbol}")
|
|
|
|
# 6. Heatmap-Daten für Export
|
|
print(f"\n💾 DATENEXPORT:")
|
|
print("="*20)
|
|
|
|
# Erstelle eine Matrix für bessere Visualisierung
|
|
matrix_data = []
|
|
for pos in positions:
|
|
row_data = {'Position': pos}
|
|
for range_name in ranges:
|
|
count = position_range_matrix[pos][range_name]
|
|
percentage = (count / len(df)) * 100
|
|
row_data[range_name] = count
|
|
row_data[f"{range_name}_Prozent"] = percentage
|
|
matrix_data.append(row_data)
|
|
|
|
matrix_df = pd.DataFrame(matrix_data)
|
|
|
|
# Zusätzliche Statistiken hinzufügen
|
|
stats_data = []
|
|
for _, row in df.iterrows():
|
|
row_data = {'datum': row['datum']}
|
|
for pos in positions:
|
|
row_data[f"{pos}_Zahl"] = row[pos]
|
|
row_data[f"{pos}_Bereich"] = get_range_for_number(row[pos])
|
|
stats_data.append(row_data)
|
|
|
|
stats_df = pd.DataFrame(stats_data)
|
|
|
|
# Export
|
|
matrix_output = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/positions_matrix.csv"
|
|
stats_output = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/positions_details.csv"
|
|
|
|
matrix_df.to_csv(matrix_output, sep=';', index=False)
|
|
stats_df.to_csv(stats_output, sep=';', index=False)
|
|
|
|
print(f"✅ Positionsmatrix gespeichert: positions_matrix.csv")
|
|
print(f"✅ Detaildaten gespeichert: positions_details.csv")
|
|
|
|
# 7. Strategische Empfehlungen
|
|
print(f"\n💡 STRATEGISCHE EMPFEHLUNGEN:")
|
|
print("="*35)
|
|
|
|
# Finde die besten Kombinationen pro Position
|
|
recommendations = {}
|
|
for pos in positions:
|
|
best_range = max(ranges, key=lambda r: position_range_matrix[pos][r])
|
|
recommendations[pos] = best_range
|
|
|
|
print(f"Optimale Bereichsauswahl pro Position:")
|
|
for pos, best_range in recommendations.items():
|
|
count = position_range_matrix[pos][best_range]
|
|
percentage = (count / len(df)) * 100
|
|
print(f" {pos}: {best_range} ({percentage:.1f}%)")
|
|
|
|
# Berechne theoretische Erfolgswahrscheinlichkeit
|
|
theoretical_success = 1.0
|
|
for pos, best_range in recommendations.items():
|
|
prob = position_range_matrix[pos][best_range] / len(df)
|
|
theoretical_success *= prob
|
|
|
|
print(f"\nTheoretische Erfolgswahrscheinlichkeit dieser Kombination: {theoretical_success*100:.4f}%")
|
|
|
|
return position_range_matrix, matrix_df
|
|
|
|
if __name__ == "__main__":
|
|
analyze_positions()
|