Einführung
Der Shop unterscheidet jetzt ein aufgerufenes Sitzungs-/Produktpaar von wiederholten Ereignissen. Als Nächstes fragt er, welche Produkte einen hohen Anteil aufgerufener Sitzungen ohne gültiges Warenkorbereignis haben und wie viel Evidenz jeden Vergleich trägt.
Sie erstellen eine vollständige Tabelle mit Aufrufsitzungsnenner, Anzahl abgeschlossener und unvollständiger Sitzungen sowie unvollständigem Anteil. Behalten Sie Produkte ohne gültige Warenkorbereignisse und sämtliche Gleichstände. Das Ergebnis ist ein Beobachtungshinweis für weitere Untersuchungen, kein Beweis, dass ein Produkt oder eine Seite einen Besuch beendet hat.
Dieses unabhängige Lab liefert das fertige Verlaufsmodul des vorherigen Guided Labs und frische Rohdateien. Sie sollten dessen Regeln für frühesten Aufruf, Sitzung/Produkt und Zeit sowie Spark-Gruppierung und Parquet kennen. Verwenden Sie Terminal. Der Stapel ist endlich und abgeschlossen; Kennungen und sekundengenaue UTC-Zeiten sind gültig, wiederholte Ereignis-IDs exakte Kopien. Die Autorenschätzung beträgt 35–45 Minuten. Streaming, Schätzungen eindeutiger Personen und kausale Schlussfolgerungen gehören nicht dazu.
Den vollständigen Produktvergleich erstellen
Aggregieren Sie eine Zeile je aufgerufenem Verlauf zu einer Zeile je Produkt. Beginnen Sie in Terminal. Ändern Sie von den gelieferten Programmen ausschließlich analysis.py. Bewahren Sie Rohdateien sowie run_analysis.py, read_result.py und support.py unverändert; abgeleitete Ergebnisse gehören unter output/:
cd /home/labex/project
cat data/batch.csv
cat analysis.py
Dieses Modul enthält read_events, build_views und build_journeys, unabhängig aus dem vorherigen Lab vorbereitet. Ein Modul enthält wiederverwendbare Funktionen. Der Treiber übergibt aktuelle SparkSession und Eingabepfad und dann den zurückgegebenen Verlaufs-DataFrame an Ihre neue Funktion build_report(journeys). Aus einer früheren VM oder Shell-Sitzung wird nichts benötigt.
Zur Erinnerung: Identische vollständige Ereigniskopien werden entfernt; jedes aufgerufene (session_id, product_id) verwendet seinen frühesten Aufruf; ein Warenkorbereignis gilt nur mit denselben beiden Schlüsseln zur Aufrufzeit oder danach. Mehrere gültige Warenkorbereignisse ergeben weiterhin einen abgeschlossenen Verlauf. Der Treiber verwendet local[2], UTC-Formatierung und dasselbe Python für Treiber und Worker. Er schreibt Ausgaben erst nach Rückkehr Ihrer Funktionen.
Berechnen Sie für ein Produkt mit drei aufgerufenen und zwei abgeschlossenen Paaren von Hand: drei Aufrufsitzungen, zwei Warenkorbsitzungen, eine Sitzung ohne Warenkorb und den Anteil 1/3. Ohne diesen Nenner könnte ein einzelner Besuch so überzeugend wirken wie eine große Stichprobe.
count("*") zählt jetzt Verlaufszeilen, keine Rohereignisse. Das Umwandeln des booleschen completed in long bildet wahr auf 1 und falsch auf 0 ab. Sparks sum addiert die Werte. Die Differenz zur Anzahl abgeschlossener Sitzungen liefert die unvollständige Anzahl; Division durch die positive Aufrufsitzungszahl ergibt einen Anteil zwischen null und eins. Jede Gruppe hat hier mindestens einen Aufruf. Ein Produkt nur mit Warenkorbereignissen hat weder Gruppe noch Nenner; wir erfinden keinen Anteil mit Nenner null.
Nur die Produktaggregation schreiben
Behalten Sie die gelieferten read_events, build_views und build_journeys: Sie sind die abgeschlossene Arbeit aus dem vorherigen Lab. Tippen Sie sie nicht erneut ab. F ist ihr vorhandener Alias für Spark-Funktionen. Öffnen Sie dasselbe Modul mit nano:
nano analysis.py
Bewegen Sie sich mit den Pfeiltasten ans Ende von build_journeys und lassen Sie dann eine Leerzeile. Wie geübt sucht Ctrl+W nach einem Funktionsnamen; jede neue Deklaration beginnt am linken Rand, ihr Rumpf verwendet vier Leerzeichen. Sie schreiben die vollständige Funktion build_report, statt eine vorbereitete Antwortvorlage auszufüllen.
Gruppieren Sie zuerst den Verlaufs-DataFrame nach Produkt. Leiten Sie in derselben Aggregation zwei Anzahlen ab: alle Zeilen für den Aufrufnenner und dann die Summe des in eine Ganzzahl umgewandelten booleschen Abschlusswerts. Behalten Sie die vom Treiber verwendeten Feldnamen:
def build_report(journeys):
counts = journeys.groupBy("product_id").agg(
F.count("*").alias("view_sessions"),
F.sum(F.col("completed").cast("long")).alias("cart_sessions"),
)
Setzen Sie Ihre Funktion fort. withColumn leitet eine benannte Spalte aus den gruppierten Anzahlen ab. Ziehen Sie die abgeschlossene Anzahl von der aufgerufenen ab und teilen Sie anschließend durch denselben positiven Aufrufnenner. Filtern Sie nicht zuerst nach abgeschlossenen Verläufen: Das würde Produkte ohne gültige Warenkorbereignisse entfernen. Wählen Sie nicht nur ein Maximum: Alle Produkte mit gleichem Wert gehören in den Bericht.
return counts.withColumn(
"no_cart_sessions", F.col("view_sessions") - F.col("cart_sessions")
).withColumn(
"no_cart_ratio", F.col("no_cart_sessions") / F.col("view_sessions")
)
Speichern Sie mit Ctrl+O, bestätigen Sie analysis.py mit Enter und beenden Sie mit Ctrl+X. Öffnen Sie erneut, um Ihre gespeicherte Funktion zu prüfen und sicherzustellen, dass die früheren Funktionen erhalten sind:
nano analysis.py
Suchen Sie build_report mit Ctrl+W. Ersetzen Sie bei einem Fehler mit Pfeiltasten und Backspace/Delete nur die betroffene Zeile; fügen Sie keine zweite Definition hinzu. Behalten Sie die Einrückung der Fortsetzungszeilen und die schließenden Klammern. Speichern Sie Änderungen, beenden Sie den Editor und lesen Sie die Datei:
cat analysis.py
Meldet der nächste Lauf SyntaxError oder IndentationError, suchen Sie die genannte Zeile in nano, prüfen Sie die umgebende Funktion, Klammern und Einrückung mit vier Leerzeichen, speichern Sie und starten Sie erneut. Erfolgreich berechnete, aber falsche Anzahlen oder Anteile erfordern stattdessen eine Prüfung von Gruppierung, Typumwandlung und Nenner. Setzen Sie weder die VM zurück noch schreiben Sie die funktionierenden G1-Funktionen neu, um Ihren Bericht zu reparieren.
Starten Sie die Berichtsstufe mit ausdrücklichen Eingabe- und Ausgabepfaden:
bigdata-python run_analysis.py data/batch.csv output/main --stage report
Erwarten Sie diese vollständige logische Tabelle; angezeigte Gleitkommawerte können mehr Stellen haben:
product_id view_sessions cart_sessions no_cart_sessions no_cart_ratio
card 1 0 1 1.0
pin 1 0 1 1.0
tea 3 1 2 0.6666666666666666
book 2 1 1 0.5
mug 3 2 1 0.3333333333333333
Der Treiber liest vor der Anzeige das tatsächlich gespeicherte Parquet. Die Tabelle sortiert absteigend nach no_cart_ratio, dann nach Produktkennung, um Gleichstände lesbar zu machen. Sowohl card als auch pin bleiben enthalten; ein Sortiergleichstand erlaubt nicht, eines zu verwerfen. Das Produkt poster mit ausschließlich Warenkorbereignis fehlt, weil es kein aufgerufenes Paar hatte.
Die Ergebnisse sind typisierte Datensätze unter output/main/journeys und output/main/report. Letzterer enthält eine Produktkennung als Zeichenkette, ganzzahlige Anzahlen und einen numerischen Anteil. Namen und Anzahl der Parquet-Teildateien sind Implementierungsdetails, nicht die Identität des Berichts. Gleichwertige Spark-DataFrame-/SQL-Ausdrücke sind zulässig; erhalten Sie eine Pipeline von der gelieferten Eingabe und führen Sie Transformationen in Spark aus. Sammeln Sie rohe Verläufe nicht in Python, wechseln Sie nicht zu RDD/pandas und rekonstruieren Sie sie nicht über Checkpoints.
Dateien lesen und den Snapshot neu erstellen
Lesen Sie das kleine CSV und ersetzen Sie den abgeleiteten Snapshot, ohne seine Quelle zu ändern. Arbeiten Sie in Terminal unter /home/labex/project weiter.
Der vorbereitete Treiber speichert output/main/report.csv als einzelne kleine UTF-8-CSV-Datei für einen Kollegen. Erst nach Rückkehr von build_report sammelt er ausschließlich die bereits aggregierte Produkttabelle zur Serialisierung ein. Diese abschließende Darstellung ersetzt die Spark-Transformationen nicht. Betrachten Sie die echte Datei:
cat output/main/report.csv
Die Kopfzeile enthält dieselben fünf Felder wie der Parquet-Bericht. Prüfen Sie alle fünf Produkte, die Anzahl der Warenkorbsitzungen von null bei card und pin und beide gleichen Anteile von 1.0. CSV kann als Zeilen und Felder gelesen werden; Zeilenzählen oder Vertrauen auf den Dateinamen belegt diese Beziehungen nicht.
Lesen Sie beide echten Parquet-Datensätze und das CSV mit dem gelieferten Leser. read_result.py liest den übergebenen Ausgabepfad, formatiert Zeitstempel innerhalb von Spark in UTC und vergleicht den CSV-Inhalt mit dem gespeicherten Bericht; fehlende Ergebnisse erzeugt oder ergänzt es nicht:
bigdata-python read_result.py output/main
Erwarten Sie zehn Verlaufszeilen und fünf Produktzeilen sowie CSV matches stored report. Fehlt eine Datei, führen Sie Ihre Analyse mit richtiger Eingabe und richtigem Ziel erneut aus; der Leser schlägt absichtlich fehl, statt eine Antwort zu erfinden.
sha256sum zeigt einen Inhaltsfingerabdruck je Rohdatei. Das Muster *.csv wählt die CSV-Dateien in data/. Vergleichen Sie diese Zeilen vor und nach dem Neuerstellen:
sha256sum data/*.csv
bigdata-python run_analysis.py data/batch.csv output/main --stage report
bigdata-python read_result.py output/main
sha256sum data/*.csv
Dieselbe Eingabe ergibt denselben logischen Bericht ohne doppelte Produkte oder Verläufe. Die Rohfingerabdrücke müssen unverändert bleiben. Neue Parquet-Dateinamen oder Bytes können zwischen Läufen variieren; logischer Inhalt ist der Wiederholbarkeitsvertrag. Der Writer ersetzt nur dieses bekannte abgeleitete Ziel, nicht die Rohdateien oder ein anderes Ergebnisverzeichnis.
Verwenden Sie jetzt das gespeicherte Modul mit dem normalen Beispiel und einem getrennten Ziel:
bigdata-python run_analysis.py data/normal.csv output/normal --stage report
bigdata-python read_result.py output/normal
Erwarten Sie zwei Produktzeilen, jeweils eine Aufrufsitzung, eine Warenkorbsitzung, null Sitzungen ohne Warenkorb und Anteil 0. Das Hauptergebnis bleibt erhalten. Dieselben parametrisierten Funktionen unterstützen beide Stapel.
card und pin verdienen in diesem kleinen Stapel Aufmerksamkeit, doch jedes hat nur eine beobachtete Sitzung. Ein hoher Anteil belegt weder, warum jemand aufhörte, noch eindeutige Personen oder Fortbestehen des Musters. Anzahlen und vollständige Gleichstände machen die Beobachtung prüfbar; für eine kausale Aussage wäre weitere Evidenz nötig.
Die Bewertung liest Ihre echten Live-Ergebnisse, ohne sie neu zu erstellen. Außerdem lädt sie das unveränderte Modul, ruft seine Funktionen auf einem Wegwerfstapel mit anderen Kennungen und anderer Zeilenfolge auf, beobachtet die tatsächliche Spark-Eingabeherkunft und liest temporäre Ausgaben. Sie bewertet weder eine genaue Befehlsschreibweise noch einen selbst geschriebenen Plan oder Anwendungsnamensmarker und repariert nie Ihr Live-Ergebnis. Halten Sie Funktionen frei von Schreibvorgängen; der Treiber übernimmt die Serialisierung.
Zusammenfassung
Sie haben vollständige Parquet- und CSV-Vergleiche erstellt und gelesen, Produkte ohne Warenkorbereignis sowie Gleichstände behalten und einen abgeleiteten Snapshot unter Erhalt der Rohdaten neu erstellt. Nenner und Anzahlspalten erklären jeden Anteil. Diese Muster abgeschlossener Sitzungen unterstützen weitere Beobachtungen, keine Kausalitätsbehauptung.



