Initial commit: Eurojackpot analysis and prediction system
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>
This commit is contained in:
commit
70e0638dee
67 files changed
+8491869
No files matched your search
@@ -0,0 +1,188 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Eurojackpot Bereichskombinationen-Analyse
|
||||
|
||||
Analysiert die Kombinationen von Zahlenbereichen in den gezogenen 5er-Kombinationen.
|
||||
Focus auf Z1-Z4 wie gewünscht.
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
from collections import Counter, defaultdict
|
||||
|
||||
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_range_combinations():
|
||||
"""Analysiert Bereichskombinationen in Eurojackpot-Ziehungen."""
|
||||
|
||||
# Daten laden
|
||||
df = pd.read_csv("/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/data/AlleEurojackpotzahlen.csv", sep=';')
|
||||
|
||||
print(f"🎲 EUROJACKPOT BEREICHSKOMBINATIONEN-ANALYSE")
|
||||
print(f"Anzahl analysierte Ziehungen: {len(df)}")
|
||||
print("="*60)
|
||||
|
||||
# Analyse für Z1-Z4 (wie gewünscht)
|
||||
z_columns_z1_z4 = ['Z1', 'Z2', 'Z3', 'Z4']
|
||||
|
||||
# Alle Kombinationen sammeln
|
||||
combinations_z1_z4 = []
|
||||
range_patterns_z1_z4 = []
|
||||
|
||||
for _, row in df.iterrows():
|
||||
# Bereiche für Z1-Z4 bestimmen
|
||||
ranges = [get_range_for_number(row[col]) for col in z_columns_z1_z4]
|
||||
range_pattern = '|'.join(sorted(ranges)) # Sortiert für einheitliche Muster
|
||||
|
||||
combinations_z1_z4.append(tuple(ranges))
|
||||
range_patterns_z1_z4.append(range_pattern)
|
||||
|
||||
# Auch vollständige Z1-Z5 Analyse
|
||||
z_columns_all = ['Z1', 'Z2', 'Z3', 'Z4', 'Z5']
|
||||
combinations_all = []
|
||||
range_patterns_all = []
|
||||
|
||||
for _, row in df.iterrows():
|
||||
ranges = [get_range_for_number(row[col]) for col in z_columns_all]
|
||||
range_pattern = '|'.join(sorted(ranges))
|
||||
|
||||
combinations_all.append(tuple(ranges))
|
||||
range_patterns_all.append(range_pattern)
|
||||
|
||||
# Häufigkeitsanalyse
|
||||
print("\n📊 ANALYSE Z1-Z4 (4 Zahlen):")
|
||||
print("="*40)
|
||||
|
||||
pattern_counts_z1_z4 = Counter(range_patterns_z1_z4)
|
||||
|
||||
print(f"Häufigste Bereichskombinationen (Z1-Z4):")
|
||||
for i, (pattern, count) in enumerate(pattern_counts_z1_z4.most_common(15), 1):
|
||||
percentage = (count / len(df)) * 100
|
||||
print(f"{i:2}. {pattern:30} {count:3}x ({percentage:4.1f}%)")
|
||||
|
||||
print(f"\n📊 VERGLEICH: ANALYSE Z1-Z5 (alle 5 Zahlen):")
|
||||
print("="*40)
|
||||
|
||||
pattern_counts_all = Counter(range_patterns_all)
|
||||
|
||||
print(f"Häufigste Bereichskombinationen (Z1-Z5):")
|
||||
for i, (pattern, count) in enumerate(pattern_counts_all.most_common(15), 1):
|
||||
percentage = (count / len(df)) * 100
|
||||
print(f"{i:2}. {pattern:35} {count:3}x ({percentage:4.1f}%)")
|
||||
|
||||
# Analyse der Bereichsverteilung in Kombinationen
|
||||
print(f"\n🎯 BEREICHSVERTEILUNG IN KOMBINATIONEN:")
|
||||
print("="*50)
|
||||
|
||||
# Wie oft kommt jeder Bereich in Z1-Z4 vor?
|
||||
range_in_combination_counts = defaultdict(int)
|
||||
|
||||
for combination in combinations_z1_z4:
|
||||
for range_name in set(combination): # set() um Duplikate zu vermeiden
|
||||
range_in_combination_counts[range_name] += 1
|
||||
|
||||
print("Häufigkeit der Bereiche in Z1-Z4 Kombinationen:")
|
||||
for range_name in ['A(1-10)', 'B(11-20)', 'C(21-30)', 'D(31-40)', 'E(41-50)']:
|
||||
count = range_in_combination_counts[range_name]
|
||||
percentage = (count / len(df)) * 100
|
||||
print(f"{range_name}: {count:3} Kombinationen ({percentage:4.1f}%)")
|
||||
|
||||
# Analyse: Wie viele verschiedene Bereiche pro Kombination?
|
||||
print(f"\n📈 BEREICHSVIELFALT PRO KOMBINATION (Z1-Z4):")
|
||||
print("="*45)
|
||||
|
||||
diversity_counts = defaultdict(int)
|
||||
|
||||
for combination in combinations_z1_z4:
|
||||
unique_ranges = len(set(combination))
|
||||
diversity_counts[unique_ranges] += 1
|
||||
|
||||
for num_ranges in sorted(diversity_counts.keys()):
|
||||
count = diversity_counts[num_ranges]
|
||||
percentage = (count / len(df)) * 100
|
||||
print(f"{num_ranges} verschiedene Bereiche: {count:3} Kombinationen ({percentage:4.1f}%)")
|
||||
|
||||
# Spezielle Muster
|
||||
print(f"\n🔍 SPEZIELLE MUSTER (Z1-Z4):")
|
||||
print("="*35)
|
||||
|
||||
# Alle aus dem gleichen Bereich
|
||||
same_range_count = sum(1 for combo in combinations_z1_z4 if len(set(combo)) == 1)
|
||||
print(f"Alle 4 Zahlen aus gleichem Bereich: {same_range_count} ({(same_range_count/len(df)*100):.1f}%)")
|
||||
|
||||
# Alle aus verschiedenen Bereichen (4 verschiedene)
|
||||
all_different_count = sum(1 for combo in combinations_z1_z4 if len(set(combo)) == 4)
|
||||
print(f"Alle 4 Zahlen aus verschiedenen Bereichen: {all_different_count} ({(all_different_count/len(df)*100):.1f}%)")
|
||||
|
||||
# Benachbarte Bereiche-Analyse
|
||||
print(f"\n🏠 BENACHBARTE BEREICHE-ANALYSE (Z1-Z4):")
|
||||
print("="*40)
|
||||
|
||||
adjacent_patterns = {
|
||||
'A+B': 0, # 1-10 + 11-20
|
||||
'B+C': 0, # 11-20 + 21-30
|
||||
'C+D': 0, # 21-30 + 31-40
|
||||
'D+E': 0, # 31-40 + 41-50
|
||||
}
|
||||
|
||||
for combination in combinations_z1_z4:
|
||||
ranges_set = set(combination)
|
||||
if 'A(1-10)' in ranges_set and 'B(11-20)' in ranges_set:
|
||||
adjacent_patterns['A+B'] += 1
|
||||
if 'B(11-20)' in ranges_set and 'C(21-30)' in ranges_set:
|
||||
adjacent_patterns['B+C'] += 1
|
||||
if 'C(21-30)' in ranges_set and 'D(31-40)' in ranges_set:
|
||||
adjacent_patterns['C+D'] += 1
|
||||
if 'D(31-40)' in ranges_set and 'E(41-50)' in ranges_set:
|
||||
adjacent_patterns['D+E'] += 1
|
||||
|
||||
for pattern, count in adjacent_patterns.items():
|
||||
percentage = (count / len(df)) * 100
|
||||
print(f"Benachbarte Bereiche {pattern}: {count:3} Kombinationen ({percentage:4.1f}%)")
|
||||
|
||||
# Export der Ergebnisse
|
||||
print(f"\n💾 EXPORT DER ERGEBNISSE:")
|
||||
print("="*30)
|
||||
|
||||
# DataFrame für Z1-Z4 Kombinationen erstellen
|
||||
results_data = []
|
||||
for i, row in df.iterrows():
|
||||
ranges_z1_z4 = [get_range_for_number(row[col]) for col in z_columns_z1_z4]
|
||||
pattern = '|'.join(sorted(ranges_z1_z4))
|
||||
diversity = len(set(ranges_z1_z4))
|
||||
|
||||
results_data.append({
|
||||
'datum': row['datum'],
|
||||
'Z1': row['Z1'],
|
||||
'Z2': row['Z2'],
|
||||
'Z3': row['Z3'],
|
||||
'Z4': row['Z4'],
|
||||
'Z1_bereich': ranges_z1_z4[0],
|
||||
'Z2_bereich': ranges_z1_z4[1],
|
||||
'Z3_bereich': ranges_z1_z4[2],
|
||||
'Z4_bereich': ranges_z1_z4[3],
|
||||
'bereichsmuster': pattern,
|
||||
'anzahl_bereiche': diversity
|
||||
})
|
||||
|
||||
results_df = pd.DataFrame(results_data)
|
||||
output_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/bereichskombinationen_z1_z4.csv"
|
||||
results_df.to_csv(output_file, sep=';', index=False)
|
||||
print(f"✅ Detailergebnisse gespeichert: bereichskombinationen_z1_z4.csv")
|
||||
|
||||
return pattern_counts_z1_z4, pattern_counts_all
|
||||
|
||||
if __name__ == "__main__":
|
||||
analyze_range_combinations()
|
||||
@@ -0,0 +1,217 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Eurojackpot Bereichsanalyse
|
||||
|
||||
Analysiert, in welchen Zahlenbereichen am häufigsten Zahlen gezogen wurden.
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
import seaborn as sns
|
||||
import numpy as np
|
||||
from collections import Counter
|
||||
|
||||
def load_drawn_numbers(filepath):
|
||||
"""Lädt die gezogenen Eurojackpot-Zahlen."""
|
||||
try:
|
||||
df = pd.read_csv(filepath, sep=';')
|
||||
print(f"Gezogene Zahlen geladen: {len(df)} Ziehungen")
|
||||
print(f"Spalten: {list(df.columns)}")
|
||||
return df
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Laden: {e}")
|
||||
return None
|
||||
|
||||
def analyze_number_ranges(df):
|
||||
"""Analysiert die Häufigkeit von Zahlen in verschiedenen Bereichen."""
|
||||
|
||||
# Alle gezogenen Zahlen sammeln (Z1-Z5)
|
||||
all_numbers = []
|
||||
for col in ['Z1', 'Z2', 'Z3', 'Z4', 'Z5']:
|
||||
all_numbers.extend(df[col].tolist())
|
||||
|
||||
print(f"Gesamtanzahl gezogene Zahlen: {len(all_numbers)}")
|
||||
|
||||
# Häufigkeit jeder Zahl
|
||||
number_counts = Counter(all_numbers)
|
||||
|
||||
# Bereiche definieren
|
||||
ranges = {
|
||||
'1-10': (1, 10),
|
||||
'11-20': (11, 20),
|
||||
'21-30': (21, 30),
|
||||
'31-40': (31, 40),
|
||||
'41-50': (41, 50)
|
||||
}
|
||||
|
||||
# Analyse pro Bereich
|
||||
range_analysis = {}
|
||||
|
||||
for range_name, (start, end) in ranges.items():
|
||||
numbers_in_range = [num for num in all_numbers if start <= num <= end]
|
||||
|
||||
range_analysis[range_name] = {
|
||||
'anzahl_ziehungen': len(numbers_in_range),
|
||||
'prozent': (len(numbers_in_range) / len(all_numbers)) * 100,
|
||||
'haeufigste_zahl': max(number_counts.items(),
|
||||
key=lambda x: x[1] if start <= x[0] <= end else 0),
|
||||
'durchschnitt': np.mean(numbers_in_range) if numbers_in_range else 0,
|
||||
'zahlen_im_bereich': sorted(set(numbers_in_range))
|
||||
}
|
||||
|
||||
return range_analysis, number_counts
|
||||
|
||||
def create_visualizations(range_analysis, number_counts, output_dir):
|
||||
"""Erstellt Visualisierungen der Analyse."""
|
||||
|
||||
# 1. Balkendiagramm: Häufigkeit pro Bereich
|
||||
plt.figure(figsize=(12, 8))
|
||||
|
||||
ranges = list(range_analysis.keys())
|
||||
counts = [range_analysis[r]['anzahl_ziehungen'] for r in ranges]
|
||||
percentages = [range_analysis[r]['prozent'] for r in ranges]
|
||||
|
||||
plt.subplot(2, 2, 1)
|
||||
bars = plt.bar(ranges, counts, color=['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FECA57'])
|
||||
plt.title('Anzahl gezogener Zahlen pro Bereich', fontsize=14, fontweight='bold')
|
||||
plt.ylabel('Anzahl Ziehungen')
|
||||
plt.xticks(rotation=45)
|
||||
|
||||
# Prozente auf Balken anzeigen
|
||||
for bar, pct in zip(bars, percentages):
|
||||
plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 5,
|
||||
f'{pct:.1f}%', ha='center', va='bottom', fontweight='bold')
|
||||
|
||||
# 2. Heatmap: Häufigkeit einzelner Zahlen
|
||||
plt.subplot(2, 2, 2)
|
||||
numbers = list(range(1, 51))
|
||||
frequencies = [number_counts.get(num, 0) for num in numbers]
|
||||
|
||||
# Als 5x10 Matrix darstellen
|
||||
freq_matrix = np.array(frequencies).reshape(5, 10)
|
||||
|
||||
sns.heatmap(freq_matrix, annot=True, fmt='d', cmap='YlOrRd',
|
||||
xticklabels=list(range(1, 11)),
|
||||
yticklabels=[f'{i*10+1}-{(i+1)*10}' for i in range(5)])
|
||||
plt.title('Häufigkeit einzelner Zahlen', fontsize=14, fontweight='bold')
|
||||
|
||||
# 3. Liniendiagramm: Häufigkeit aller Zahlen
|
||||
plt.subplot(2, 2, 3)
|
||||
plt.plot(numbers, frequencies, marker='o', linewidth=2, markersize=4)
|
||||
plt.title('Häufigkeitsverteilung aller Zahlen (1-50)', fontsize=14, fontweight='bold')
|
||||
plt.xlabel('Zahl')
|
||||
plt.ylabel('Häufigkeit')
|
||||
plt.grid(True, alpha=0.3)
|
||||
|
||||
# Bereiche farblich markieren
|
||||
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FECA57']
|
||||
for i, (range_name, color) in enumerate(zip(range_analysis.keys(), colors)):
|
||||
start = i * 10 + 1
|
||||
end = (i + 1) * 10
|
||||
plt.axvspan(start, end, alpha=0.2, color=color, label=range_name)
|
||||
|
||||
plt.legend()
|
||||
|
||||
# 4. Pie Chart: Prozentuale Verteilung
|
||||
plt.subplot(2, 2, 4)
|
||||
plt.pie(percentages, labels=ranges, autopct='%1.1f%%',
|
||||
colors=['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FECA57'],
|
||||
startangle=90)
|
||||
plt.title('Prozentuale Verteilung nach Bereichen', fontsize=14, fontweight='bold')
|
||||
|
||||
plt.tight_layout()
|
||||
plt.savefig(f'{output_dir}/eurojackpot_bereichsanalyse.png', dpi=300, bbox_inches='tight')
|
||||
plt.show()
|
||||
|
||||
def print_detailed_analysis(range_analysis, number_counts):
|
||||
"""Gibt detaillierte Analyseergebnisse aus."""
|
||||
|
||||
print("\n" + "="*60)
|
||||
print("🎯 EUROJACKPOT BEREICHSANALYSE")
|
||||
print("="*60)
|
||||
|
||||
total_numbers = sum(analysis['anzahl_ziehungen'] for analysis in range_analysis.values())
|
||||
|
||||
for range_name, analysis in range_analysis.items():
|
||||
print(f"\n📊 BEREICH {range_name}:")
|
||||
print(f" Anzahl Ziehungen: {analysis['anzahl_ziehungen']:,}")
|
||||
print(f" Prozentanteil: {analysis['prozent']:.2f}%")
|
||||
print(f" Durchschnittswert: {analysis['durchschnitt']:.1f}")
|
||||
|
||||
# Top 3 Zahlen in diesem Bereich
|
||||
start, end = map(int, range_name.split('-'))
|
||||
range_numbers = [(num, count) for num, count in number_counts.items()
|
||||
if start <= num <= end]
|
||||
range_numbers.sort(key=lambda x: x[1], reverse=True)
|
||||
|
||||
print(f" Top 3 Zahlen: ", end="")
|
||||
for i, (num, count) in enumerate(range_numbers[:3]):
|
||||
print(f"{num} ({count}x)", end="")
|
||||
if i < 2 and i < len(range_numbers) - 1:
|
||||
print(", ", end="")
|
||||
print()
|
||||
|
||||
# Allgemeine Statistiken
|
||||
print(f"\n📈 ALLGEMEINE STATISTIKEN:")
|
||||
print(f" Gesamte gezogene Zahlen: {total_numbers:,}")
|
||||
print(f" Durchschnitt pro Bereich: {total_numbers/5:.1f}")
|
||||
|
||||
# Häufigste und seltenste Zahlen insgesamt
|
||||
most_common = number_counts.most_common(5)
|
||||
least_common = number_counts.most_common()[-5:]
|
||||
|
||||
print(f"\n🔥 HÄUFIGSTE ZAHLEN GESAMT:")
|
||||
for i, (num, count) in enumerate(most_common, 1):
|
||||
print(f" {i}. Zahl {num}: {count} mal gezogen")
|
||||
|
||||
print(f"\n❄️ SELTENSTE ZAHLEN GESAMT:")
|
||||
for i, (num, count) in enumerate(reversed(least_common), 1):
|
||||
print(f" {i}. Zahl {num}: {count} mal gezogen")
|
||||
|
||||
# Empfehlungen
|
||||
print(f"\n💡 ERKENNTNISSE:")
|
||||
best_range = max(range_analysis.keys(), key=lambda x: range_analysis[x]['prozent'])
|
||||
worst_range = min(range_analysis.keys(), key=lambda x: range_analysis[x]['prozent'])
|
||||
|
||||
print(f" • Bester Bereich: {best_range} ({range_analysis[best_range]['prozent']:.1f}%)")
|
||||
print(f" • Schwächster Bereich: {worst_range} ({range_analysis[worst_range]['prozent']:.1f}%)")
|
||||
print(f" • Unterschied: {range_analysis[best_range]['prozent'] - range_analysis[worst_range]['prozent']:.1f} Prozentpunkte")
|
||||
|
||||
def main():
|
||||
"""Hauptfunktion."""
|
||||
|
||||
# Pfade
|
||||
input_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/data/AlleEurojackpotzahlen.csv"
|
||||
output_dir = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot"
|
||||
|
||||
# Daten laden
|
||||
print("🔄 Lade Eurojackpot-Daten...")
|
||||
df = load_drawn_numbers(input_file)
|
||||
|
||||
if df is None:
|
||||
print("❌ Fehler beim Laden der Daten!")
|
||||
return
|
||||
|
||||
# Analyse durchführen
|
||||
print("\n🔍 Führe Bereichsanalyse durch...")
|
||||
range_analysis, number_counts = analyze_number_ranges(df)
|
||||
|
||||
# Ergebnisse ausgeben
|
||||
print_detailed_analysis(range_analysis, number_counts)
|
||||
|
||||
# Visualisierungen erstellen
|
||||
print(f"\n📊 Erstelle Visualisierungen...")
|
||||
try:
|
||||
create_visualizations(range_analysis, number_counts, output_dir)
|
||||
print(f"✅ Diagramm gespeichert: {output_dir}/eurojackpot_bereichsanalyse.png")
|
||||
except Exception as e:
|
||||
print(f"⚠️ Visualisierung konnte nicht erstellt werden: {e}")
|
||||
print("💡 Installieren Sie matplotlib und seaborn: pip install matplotlib seaborn")
|
||||
|
||||
# CSV-Export der Analyse
|
||||
results_df = pd.DataFrame.from_dict(range_analysis, orient='index')
|
||||
results_df.to_csv(f'{output_dir}/bereichsanalyse_ergebnisse.csv', sep=';')
|
||||
print(f"✅ Ergebnisse gespeichert: {output_dir}/bereichsanalyse_ergebnisse.csv")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,208 @@
|
||||
#!/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()
|
||||
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Einfache Eurojackpot Bereichsanalyse
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
from collections import Counter
|
||||
|
||||
def analyze_ranges():
|
||||
"""Analysiert Zahlenbereiche in Eurojackpot-Daten."""
|
||||
|
||||
# Daten laden
|
||||
df = pd.read_csv("/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/data/AlleEurojackpotzahlen.csv", sep=';')
|
||||
|
||||
print(f"Anzahl Ziehungen: {len(df)}")
|
||||
|
||||
# Alle Zahlen sammeln
|
||||
all_numbers = []
|
||||
for col in ['Z1', 'Z2', 'Z3', 'Z4', 'Z5']:
|
||||
all_numbers.extend(df[col].tolist())
|
||||
|
||||
# Bereiche definieren
|
||||
ranges = {
|
||||
'1-10': list(range(1, 11)),
|
||||
'11-20': list(range(11, 21)),
|
||||
'21-30': list(range(21, 31)),
|
||||
'31-40': list(range(31, 41)),
|
||||
'41-50': list(range(41, 51))
|
||||
}
|
||||
|
||||
print(f"\nGesamt gezogene Zahlen: {len(all_numbers)}")
|
||||
print("="*50)
|
||||
|
||||
# Analyse pro Bereich
|
||||
for range_name, range_numbers in ranges.items():
|
||||
count = sum(1 for num in all_numbers if num in range_numbers)
|
||||
percentage = (count / len(all_numbers)) * 100
|
||||
|
||||
print(f"{range_name:6}: {count:4} Zahlen ({percentage:5.1f}%)")
|
||||
|
||||
print("="*50)
|
||||
|
||||
# Häufigste Zahlen
|
||||
number_counts = Counter(all_numbers)
|
||||
print("\nHäufigste 10 Zahlen:")
|
||||
for num, count in number_counts.most_common(10):
|
||||
print(f"Zahl {num:2}: {count:3} mal")
|
||||
|
||||
print("\nSeltenste 10 Zahlen:")
|
||||
for num, count in number_counts.most_common()[-10:]:
|
||||
print(f"Zahl {num:2}: {count:3} mal")
|
||||
|
||||
if __name__ == "__main__":
|
||||
analyze_ranges()
|
||||
@@ -0,0 +1,270 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Eurojackpot Treffer-Analyse (umschlüsselte Werte)
|
||||
|
||||
Analysiert, wo die größten Treffer-Wahrscheinlichkeiten bei den umschlüsselten Werten liegen.
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
from collections import Counter, defaultdict
|
||||
import numpy as np
|
||||
|
||||
def analyze_hit_probabilities():
|
||||
"""Analysiert die Treffer-Wahrscheinlichkeiten der umschlüsselten Werte."""
|
||||
|
||||
# Umschlüsselte Daten laden
|
||||
df = pd.read_csv("/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/AlleEurojackpotzahlen_umschluesselt.csv", sep=';')
|
||||
|
||||
print("🎯 TREFFER-ANALYSE UMSCHLÜSSELTE WERTE (1-10)")
|
||||
print("="*60)
|
||||
print(f"Analysierte Ziehungen: {len(df)}")
|
||||
|
||||
# 1. Einzelne Gruppen-Wahrscheinlichkeiten pro Position
|
||||
print(f"\n🏆 HÖCHSTE TREFFER-WAHRSCHEINLICHKEITEN PRO POSITION:")
|
||||
print("="*55)
|
||||
|
||||
positions = ['z1', 'z2', 'z3', 'z4', 'z5']
|
||||
position_stats = {}
|
||||
|
||||
for pos in positions:
|
||||
group_counts = Counter(df[pos])
|
||||
total = len(df)
|
||||
|
||||
# Beste Gruppe für diese Position
|
||||
best_group = max(group_counts, key=group_counts.get)
|
||||
best_count = group_counts[best_group]
|
||||
best_probability = (best_count / total) * 100
|
||||
|
||||
position_stats[pos] = {
|
||||
'best_group': best_group,
|
||||
'probability': best_probability,
|
||||
'count': best_count,
|
||||
'all_groups': group_counts
|
||||
}
|
||||
|
||||
print(f"\n{pos.upper()}: Gruppe {best_group} führt mit {best_probability:.1f}% ({best_count}/{total})")
|
||||
|
||||
# Top 3 für diese Position
|
||||
top_3 = group_counts.most_common(3)
|
||||
print(f" Top 3: ", end="")
|
||||
for i, (group, count) in enumerate(top_3):
|
||||
prob = (count / total) * 100
|
||||
print(f"{i+1}.Gruppe {group}({prob:.1f}%)", end="")
|
||||
if i < 2:
|
||||
print(" > ", end="")
|
||||
print()
|
||||
|
||||
# 2. Beste Gesamtkombination
|
||||
print(f"\n🔥 OPTIMAL-KOMBINATION (höchste Einzelwahrscheinlichkeiten):")
|
||||
print("="*60)
|
||||
|
||||
optimal_combination = []
|
||||
total_probability = 1.0
|
||||
|
||||
for pos in positions:
|
||||
best_group = position_stats[pos]['best_group']
|
||||
probability = position_stats[pos]['probability'] / 100
|
||||
optimal_combination.append(best_group)
|
||||
total_probability *= probability
|
||||
|
||||
print(f"{pos}: Gruppe {best_group} ({position_stats[pos]['probability']:.1f}%)")
|
||||
|
||||
optimal_string = '-'.join(map(str, optimal_combination))
|
||||
print(f"\nOptimal-Kombination: {optimal_string}")
|
||||
print(f"Theoretische Wahrscheinlichkeit: {total_probability*100:.6f}%")
|
||||
print(f"Das entspricht etwa 1 in {1/total_probability:,.0f} Ziehungen")
|
||||
|
||||
# 3. Tatsächlich aufgetretene häufigste Kombinationen
|
||||
print(f"\n📊 REAL AUFGETRETENE HÄUFIGSTE KOMBINATIONEN:")
|
||||
print("="*50)
|
||||
|
||||
combination_counts = Counter(df['kombination_umschluesselt'])
|
||||
|
||||
print(f"Top 20 real aufgetretene Kombinationen:")
|
||||
for i, (combination, count) in enumerate(combination_counts.most_common(20), 1):
|
||||
probability = (count / len(df)) * 100
|
||||
print(f"{i:2}. {combination:15} {count}x ({probability:.2f}%)")
|
||||
|
||||
# 4. Bereichs-Kombinationen mit höchster Wahrscheinlichkeit
|
||||
print(f"\n🎲 BEREICHS-KOMBINATIONEN MIT HÖCHSTER WAHRSCHEINLICHKEIT:")
|
||||
print("="*60)
|
||||
|
||||
# Niedrig (1-3), Mittel (4-7), Hoch (8-10) Kombinationen
|
||||
range_combinations = defaultdict(int)
|
||||
|
||||
for _, row in df.iterrows():
|
||||
ranges = []
|
||||
for pos in positions:
|
||||
val = row[pos]
|
||||
if 1 <= val <= 3:
|
||||
ranges.append('N') # Niedrig
|
||||
elif 4 <= val <= 7:
|
||||
ranges.append('M') # Mittel
|
||||
else:
|
||||
ranges.append('H') # Hoch
|
||||
|
||||
range_pattern = ''.join(ranges)
|
||||
range_combinations[range_pattern] += 1
|
||||
|
||||
print(f"Häufigste Bereichsmuster (N=Niedrig1-3, M=Mittel4-7, H=Hoch8-10):")
|
||||
sorted_patterns = sorted(range_combinations.items(), key=lambda x: x[1], reverse=True)
|
||||
|
||||
for i, (pattern, count) in enumerate(sorted_patterns[:15], 1):
|
||||
probability = (count / len(df)) * 100
|
||||
pattern_readable = pattern.replace('N', 'Niedrig').replace('M', 'Mittel').replace('H', 'Hoch')
|
||||
print(f"{i:2}. {pattern:5} ({pattern_readable:25}) {count:3}x ({probability:5.1f}%)")
|
||||
|
||||
# 5. Positions-spezifische Empfehlungen
|
||||
print(f"\n💡 POSITIONS-SPEZIFISCHE EMPFEHLUNGEN:")
|
||||
print("="*45)
|
||||
|
||||
recommendations = {}
|
||||
|
||||
for pos in positions:
|
||||
group_counts = position_stats[pos]['all_groups']
|
||||
total = len(df)
|
||||
|
||||
# Top 3 Gruppen für maximale Abdeckung
|
||||
top_groups = [group for group, count in group_counts.most_common(3)]
|
||||
top_coverage = sum(group_counts[group] for group in top_groups)
|
||||
coverage_percentage = (top_coverage / total) * 100
|
||||
|
||||
recommendations[pos] = {
|
||||
'top_groups': top_groups,
|
||||
'coverage': coverage_percentage
|
||||
}
|
||||
|
||||
print(f"\n{pos.upper()}: Empfohlene Gruppen {top_groups}")
|
||||
print(f" Abdeckung: {coverage_percentage:.1f}% aller Ziehungen")
|
||||
|
||||
# Wahrscheinlichkeitsverteilung
|
||||
print(f" Verteilung: ", end="")
|
||||
for group in top_groups:
|
||||
prob = (group_counts[group] / total) * 100
|
||||
print(f"Gruppe {group}({prob:.1f}%)", end="")
|
||||
if group != top_groups[-1]:
|
||||
print(", ", end="")
|
||||
print()
|
||||
|
||||
# 6. Strategische Kombinationen
|
||||
print(f"\n🎯 STRATEGISCHE KOMBINATIONEN FÜR MAXIMALE TREFFER:")
|
||||
print("="*55)
|
||||
|
||||
# Berechne verschiedene Strategien
|
||||
strategies = {
|
||||
'Konservativ': {
|
||||
'z1': [1, 2], # Top 2 der Position z1
|
||||
'z2': [3, 4], # Top 2 der Position z2
|
||||
'z3': [5, 6], # Top 2 der Position z3
|
||||
'z4': [7, 8], # Top 2 der Position z4
|
||||
'z5': [9, 10] # Top 2 der Position z5
|
||||
},
|
||||
'Ausgewogen': {
|
||||
'z1': [1, 2, 3], # Top 3 jeder Position
|
||||
'z2': [3, 4, 5],
|
||||
'z3': [4, 5, 6, 7],
|
||||
'z4': [6, 7, 8],
|
||||
'z5': [8, 9, 10]
|
||||
},
|
||||
'Optimal': {} # Wird basierend auf tatsächlichen Daten gefüllt
|
||||
}
|
||||
|
||||
# Optimal-Strategie basierend auf echten Top-3 pro Position
|
||||
for pos in positions:
|
||||
top_3_groups = recommendations[pos]['top_groups']
|
||||
strategies['Optimal'][pos] = top_3_groups
|
||||
|
||||
for strategy_name, strategy in strategies.items():
|
||||
if strategy: # Nur wenn Strategie gefüllt ist
|
||||
print(f"\n{strategy_name}-Strategie:")
|
||||
total_combinations = 1
|
||||
coverage_per_position = []
|
||||
|
||||
for pos in positions:
|
||||
recommended_groups = strategy[pos]
|
||||
pos_stats = position_stats[pos]['all_groups']
|
||||
total_pos = len(df)
|
||||
|
||||
# Abdeckung dieser Gruppen
|
||||
coverage = sum(pos_stats.get(group, 0) for group in recommended_groups)
|
||||
coverage_pct = (coverage / total_pos) * 100
|
||||
coverage_per_position.append(coverage_pct)
|
||||
|
||||
total_combinations *= len(recommended_groups)
|
||||
|
||||
print(f" {pos}: Gruppen {recommended_groups} ({coverage_pct:.1f}% Abdeckung)")
|
||||
|
||||
avg_coverage = np.mean(coverage_per_position)
|
||||
print(f" Durchschnittliche Abdeckung: {avg_coverage:.1f}%")
|
||||
print(f" Mögliche Kombinationen: {total_combinations:,}")
|
||||
|
||||
# 7. Heiße und kalte Zahlen
|
||||
print(f"\n🔥❄️ HEISSE UND KALTE GRUPPEN:")
|
||||
print("="*35)
|
||||
|
||||
# Alle Gruppen über alle Positionen sammeln
|
||||
all_groups = []
|
||||
for pos in positions:
|
||||
all_groups.extend(df[pos].tolist())
|
||||
|
||||
group_total_counts = Counter(all_groups)
|
||||
total_appearances = len(all_groups)
|
||||
expected_per_group = total_appearances / 10 # 10 Gruppen
|
||||
|
||||
print(f"Erwartete Häufigkeit pro Gruppe: {expected_per_group:.1f}")
|
||||
print(f"\nHeisse Gruppen (über Erwartung):")
|
||||
hot_groups = []
|
||||
for group in range(1, 11):
|
||||
actual = group_total_counts.get(group, 0)
|
||||
deviation = actual - expected_per_group
|
||||
if deviation > 0:
|
||||
hot_groups.append((group, actual, deviation))
|
||||
|
||||
hot_groups.sort(key=lambda x: x[2], reverse=True)
|
||||
for group, count, deviation in hot_groups:
|
||||
percentage = (count / total_appearances) * 100
|
||||
print(f" Gruppe {group}: {count} (+{deviation:.1f}, {percentage:.1f}%)")
|
||||
|
||||
print(f"\nKalte Gruppen (unter Erwartung):")
|
||||
cold_groups = []
|
||||
for group in range(1, 11):
|
||||
actual = group_total_counts.get(group, 0)
|
||||
deviation = actual - expected_per_group
|
||||
if deviation < 0:
|
||||
cold_groups.append((group, actual, deviation))
|
||||
|
||||
cold_groups.sort(key=lambda x: x[2])
|
||||
for group, count, deviation in cold_groups:
|
||||
percentage = (count / total_appearances) * 100
|
||||
print(f" Gruppe {group}: {count} ({deviation:.1f}, {percentage:.1f}%)")
|
||||
|
||||
# 8. Export der Empfehlungen
|
||||
print(f"\n💾 EMPFEHLUNGEN EXPORT:")
|
||||
print("="*25)
|
||||
|
||||
# Erstelle Empfehlungs-DataFrame
|
||||
recommendation_data = []
|
||||
|
||||
# Für jede Position die besten Empfehlungen
|
||||
for pos in positions:
|
||||
pos_recommendations = recommendations[pos]
|
||||
for group in pos_recommendations['top_groups']:
|
||||
prob = (position_stats[pos]['all_groups'][group] / len(df)) * 100
|
||||
recommendation_data.append({
|
||||
'position': pos,
|
||||
'gruppe': group,
|
||||
'wahrscheinlichkeit_prozent': prob,
|
||||
'anzahl_auftreten': position_stats[pos]['all_groups'][group],
|
||||
'empfehlung_rang': pos_recommendations['top_groups'].index(group) + 1
|
||||
})
|
||||
|
||||
rec_df = pd.DataFrame(recommendation_data)
|
||||
output_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/treffer_empfehlungen_umschluesselt.csv"
|
||||
rec_df.to_csv(output_file, sep=';', index=False)
|
||||
|
||||
print(f"✅ Empfehlungen gespeichert: treffer_empfehlungen_umschluesselt.csv")
|
||||
|
||||
return position_stats, recommendations
|
||||
|
||||
if __name__ == "__main__":
|
||||
analyze_hit_probabilities()
|
||||
Reference in new issue
Block a user