Dataframe in Apache PySpark: Umfassendes Tutorial [mit Beispielen]

Veröffentlicht: 2020-02-27

Heute lernen wir den DataFrame in Apache PySpark kennen . Pyspark ist eines der führenden Data-Science-Tools im Jahr 2020. Es wird als Spalten einer verteilten Sammlung von Zeilen in Apache Spark bezeichnet. Es ist den Tabellen oder Spalten in Excel-Tabellen sehr ähnlich und auch der Tabelle der relationalen Datenbank ähnlich. PySpark DataFrame hat auch ähnliche Eigenschaften von RDD, nämlich:

Verteilt: Die Natur von DataFrame und RDD ist beide verteilt

Lazy Evaluations: Die Ausführung der Aufgabe erfolgt nicht, wenn die Aktion nicht ausgeführt wird

Art der Unveränderlichkeit: Ein weiteres ähnliches Merkmal von RDD / DataFrame ist, dass es nach seiner Erstellung nicht mehr geändert werden kann. Aber man kann die Transformation anwenden, um den RDD / DataFrame zu transformieren.

Inhaltsverzeichnis

Vorteil von DataFrames

1. Dies unterstützt viele verschiedene Sprachen, wie Java, Scala, R, Python, was im Hinblick auf die API-Unterstützung nützlich ist. Die API-Unterstützung für mehrere Sprachen hilft bei der Arbeit mit vielen Programmiersprachen.

2. Eine breite Palette von Datenquellen und -formaten wird von DataFrame unterstützt, was sehr hilfreich ist, um eine andere Datenquelle und ihr Format bequem zu verwenden.

3. Einer der besten Teile von DataFrame ist, dass es sogar Petabytes an Daten verarbeiten kann, was eine bemerkenswerte Fähigkeit ist, mit solch massiven Daten umzugehen.

4. Apache Spark versteht schnell das Schema von DataFrame mit der Beobachtung in Spark DataFrame. Unter benannten Spalten ist die Beobachtung des Spark DataFrame organisiert. Auf diese Weise wird der Plan der Abfrageausführung optimiert.

5. Riesige Mengen halbstrukturierter und strukturierter Daten können schnell verarbeitet werden, da sie für DataFrames ausgelegt sind.

Apache Spark-Setup

Apache Spark sollte auf dem Computer eingerichtet werden, bevor er zur Verwendung für DataFrame-Vorgänge gestartet werden kann. Daten können mit Unterstützung von DataFrame betrieben werden, da es verschiedene DataFrame-Operationen unterstützt. Hier werden wir einige gängige DataFrame-Operationen besprechen.

Die Erstellung von SparkContext ist der erste Schritt in der Programmierung von Apache. Für die Ausführung von Operationen in einem Cluster wird SparkContext benötigt. Wie auf einen Cluster zugegriffen wird, wird von SparkContext mitgeteilt. Es zeigt dem Spark auch den Standort an, um einen Cluster zu erhalten.

Lesen Sie: Deep-Learning-Frameworks

Dann wird die Apache-Cluster-Verbindung aufgebaut. Seine Erstellung ist bereits erledigt, wenn man Spark Shell verwendet. Die andere Möglichkeit, die Konfigurationseinstellung, kann für die Erstellung des SparkContext bereitgestellt, initialisiert und importiert werden.

Diesen Code kann man zur Erstellung verwenden:

aus pyspark import SparkContext

sc = SparkContext()

DataFrame-Erstellung aus CSV-Datei

In der Python-Shell muss eine neue Bibliothek angegeben werden, damit die CSV-Datei gelesen werden kann. Dazu besteht der erste Schritt darin, die neueste Version des Spark-CSV-Pakets herunterzuladen und das Paket im Basisverzeichnis von Spark zu extrahieren. Danach öffnen wir die Shell von PySpark und das Paket muss eingebunden werden.

$ ./bin/pyspark –Pakete com.databricks:spark-csv_2.10:1.3.0

Jetzt wird der DataFrame erstellt, nachdem die Daten aus der CSV-Datei gelesen wurden.

train = sqlContext.load(source=”com.databricks.spark.csv”, path = 'PATH/train.csv', header = True,inferSchema = True)

test = sqlContext.load(source=”com.databricks.spark.csv”, path = 'PATH/test-comb.csv', header = True,inferSchema = True)

Die Test-CSV-Dateien und Zug-CSV-Dateien befinden sich im Ordner PATH. Wenn der Header in der CSV-Datei vorhanden ist, wird er als True angezeigt. Um den Datentyp in jeder Spalte des Datenrahmens zu kennen, verwenden wir die Option inferSchema = True. Durch die Verwendung der Option inferSchema = True wird die Erkennung des Datentyps jeder Spalte des Datenrahmens automatisch vom SQL-Kontext erkannt. Alle Spalten werden als String gelesen, wenn wir inferSchema nicht auf true setzen.

Lesen Sie: Python-Bibliotheken für maschinelles Lernen

Manipulation von DataFrame

Hier werden wir nun sehen, wie man den Datenrahmen manipuliert:

  • Kennen Sie den Datentyp der Spalten

printSchema wird verwendet, um den Spaltentyp und seinen Datentyp anzuzeigen. Jetzt wird das Schema durch Anwenden von printSchema() im Baumformat gedruckt.

train.printSchema()

Ausgabe:

Wurzel

|– User_ID: Ganzzahl (nullable = true)

|– Product_ID: string (nullable = true)

|– Geschlecht: Zeichenfolge (nullable = true)

|– Alter: Zeichenfolge (nullable = true)

|– Beruf: Ganzzahl (nullable = true)

|– City_Category: Zeichenfolge (nullable = true)

|– Stay_In_Current_City_Years: Zeichenfolge (nullable = true)

|– Marital_Status: Ganzzahl (nullable = true)

|– Product_Category_1: Ganzzahl (nullable = true)

|– Product_Category_2: Ganzzahl (nullable = true)

|– Product_Category_3: Ganzzahl (nullable = true)

|– Kauf: Ganzzahl (nullable = true)

Nach dem Lesen der CSV-Datei können wir sehen, dass wir den Datentyp oder das Schema jeder Spalte im Datenrahmen genau erhalten haben.

  • Erste n-Beobachtung wird angezeigt

Um die erste n Beobachtung zu sehen, kann man die Kopfoperation verwenden. Die Kopfoperation von Pandas ist dieselbe wie die Kopfoperation von PySpark.

train.head(5)

Ausgabe:

[Row(User_ID=1000001, Product_ID=u'P00069042′, Gender=u'F', Age=u'0-17′, Occupation=10, City_Category=u'A', Stay_In_Current_City_Years=u'2′, Marital_Status= 0, Product_Category_1=3, Product_Category_2=Keine, Product_Category_3=Keine, Kauf=8370),

Zeile (User_ID=1000001, Product_ID=u'P00248942′, Gender=u'F', Age=u'0-17′, Occupation=10, City_Category=u'A', Stay_In_Current_City_Years=u'2′, Marital_Status=0 , Product_Category_1=1, Product_Category_2=6, Product_Category_3=14, Purchase=15200),

Zeile (User_ID=1000001, Product_ID=u'P00087842′, Gender=u'F', Age=u'0-17′, Occupation=10, City_Category=u'A', Stay_In_Current_City_Years=u'2′, Marital_Status=0 , Product_Category_1=12, Product_Category_2=Keine, Product_Category_3=Keine, Kauf=1422),

Row(User_ID=1000001, Product_ID=u'P00085442′, Gender=u'F', Age=u'0-17′, Occupation=10, City_Category=u'A', Stay_In_Current_City_Years=u'2′, Marital_Status=0 , Product_Category_1=12, Product_Category_2=14, Product_Category_3=Keine, Kauf=1057),

Row(User_ID=1000002, Product_ID=u'P00285442', Gender=u'M', Age=u'55+', Occupation=16, City_Category=u'C', Stay_In_Current_City_Years=u'4+', Marital_Status=0 , Product_Category_1=8, Product_Category_2=Keine, Product_Category_3=Keine, Kauf=7969)]

Jetzt verwenden wir die Show-Operation, um das Ergebnis besser zu sehen, da die Ergebnisse im Zeilenformat vorliegen. Wir können das Ergebnis auch abschneiden, indem wir das Argument truncate = True verwenden.

train.show(2,truncate= True)

Ausgabe:

+——-+———-+——+—-+———-+————-+————————–+————–+——————+ ——————+——————+——–+

|Benutzer-ID|Produkt-ID|Geschlecht| Alter|Beruf|Stadt_Kategorie|Aufenthalt_in_aktueller_Stadt_Jahre|Familienstand|Produkt_Kategorie_1|Produkt_Kategorie_2|Produkt_Kategorie_3|Kauf|

+——-+———-+——+—-+———-+————-+————————–+————–+——————+ ——————+——————+——–+

|1000001| P00069042| F|0-17| 10| A| 2| 0| 3| null| null| 8370|

|1000001| P00248942| F|0-17| 10| A| 2| 0| 1| 6| 14| 15200|

+——-+———-+——+—-+———-+————-+————————–+————–+——————+ ——————+——————+——–+

zeigt nur die oberen 2 Zeilen

  • Zählen der Zeilennummer von DataFrame

Um die Zeilennummer im Datenrahmen zu zählen, können wir die Operation der Zählung verwenden. Jetzt werden wir die Anzahl der Zeilen von Testdateien zählen und Dateien trainieren, indem wir die Zähloperation anwenden.

train.count(),test.count()

Ausgabe:

(233598, 550069)

Wir haben 233598, 550069 Zeilen in Test bzw. Training.

  • Abrufen der Spaltenanzahl und des Spaltennamens aus der Test- und Trainingsdatei

Ähnlich wie bei der Operation der Spalte in DataFrame von Pandas werden wir die Spaltenoperation verwenden, um den Namen der Spalte zu erhalten. Jetzt drucken wir zuerst die Nr. der Spalte und den Namen der Spalte aus der Testdatei und der Trainingsdatei.

len(Zug.Spalten), Zug.Spalten

Ausgang:

12 ['Benutzer_ID', 'Produkt_ID', 'Geschlecht', 'Alter', 'Beruf', 'Stadt_Kategorie', 'Aufenthalt_in_aktueller_Stadt_Jahre', 'Familienstand', 'Produkt_Kategorie_1', 'Produkt_Kategorie_2', 'Produkt_Kategorie_3', 'Kauf']

Jetzt machen wir es für die Testdatei ähnlich.

len(test.spalten), test.spalten

Ausgabe:

13 [”, 'Benutzer_ID', 'Produkt_ID', 'Geschlecht', 'Alter', 'Beruf', 'Stadt_Kategorie', 'Aufenthalt_in_aktueller_Stadt_Jahre', 'Familienstand', 'Produkt_Kategorie_1', 'Produkt_Kategorie_2', 'Produkt_Kategorie_3', 'Komb ']

Nach der obigen Ausgabe können wir sehen, dass die Trainingsdatei 12 Spalten und die Testdatei 13 Spalten enthält. Aus der obigen Ausgabe können wir überprüfen, dass wir 13 Spalten in der Testdatei und 12 in der Trainingsdatei haben. Die Spalte „Kamm“ ist die einzige einzelne Spalte in der Testdatei, und es gibt keinen „Kauf“, der in der Testdatei nicht vorhanden ist. Es gibt eine weitere Spalte in der Testdatei, von der wir sehen können, dass sie keinen Namen der Spalte hat.

  • Abrufen der zusammenfassenden Statistiken wie Anzahl, Max, Min, Standardabweichung, Mittelwert in den numerischen Spalten des DataFrame

Im DataFrame verwenden wir die Operation „describe the operation“. Wir können die Berechnung der numerischen Spalte durchführen und eine statistische Zusammenfassung erhalten, indem wir die Operation beschreiben. Alle numerischen Spalten werden im DataFrame berechnet, da bei der Berechnung der zusammenfassenden Statistik kein Spaltenname angegeben ist.

train.describe().show()

Ausgabe:

+——-+——————+—————–+——————-+——————+——————+——————+—— ————+

|Zusammenfassung| Benutzer_ID| Beruf| Familienstand|Produktkategorie_1|Produktkategorie_2|Produktkategorie_3| Kaufen|

+——-+——————+—————–+——————-+——————+——————+——————+—— ————+

| zählen| 550068| 550068| 550068| 550068| 376430| 166821| 550068|

| Mittelwert|1003028,8424013031|8,076706879876669|0,40965298835780306| 5.404270017525106| 9.842329251122386|12.668243206790512| 9263.968712959126|

| stddev|1727.5915855308265|6.522660487341778| 0,4917701263173273|3,9362113692014082| 5.086589648693526| 4.125337631575267|5023.0653938206015|

| min| 1000001| 0| 0| 1| 2| 3| 12|

| maximal| 1006040| 20| 1| 20| 18| 18| 23961|

+——-+——————+—————–+——————-+——————+——————+——————+—— ————+

In der Operation "Describe" erhalten wir dies, wenn der Name der Zeichenfolgenspalte oder der Name der kategorialen Spalte angegeben wird.

train.describe('Product_ID').show()

Ausgabe:

+——-+———-+

|Zusammenfassung|Produkt-ID|

+——-+———-+

| zählen| 550068|

| bedeuten | null|

| Standarddev| null|

| min| P00000142|

| maximal| P0099942|

+——-+———-+

Basierend auf ASCII werden die Max- und Min-Werte von berechnet. Die Describe-Operation wird verwendet, um an der Spalte vom Typ String zu arbeiten.

  • Auswahl der Spalte von DataFrame

Wir verwenden den Namen der Spalten in der Auswahloperation, um die Spalte auszuwählen. Wir werden den Namen der Spalte mit der Trennung durch Kommas erwähnen. Nun sehen wir uns an, wie die Auswahl von „Alter“ und „Benutzer_ID“ aus der Trainingsdatei erfolgt.

  • train.select('Benutzer_ID','Alter').show(5)
  • Ausgabe:
  • +——-+—-+
  • |Benutzer-ID| Alter|
  • +——-+—-+
  • |1000001|0-17|
  • |1000001|0-17|
  • |1000001|0-17|
  • |1000001|0-17|
  • |1000002| 55+|
  • +——-+—-+
  • Eindeutige Produkt-Nr. in Testdateien und Zugdateien

Um die DataFrame-Nr. von distinkten Zeilen verwenden wir die distinkte Operation. Hier werden wir nun eine unterschiedliche Operation für die Berechnung von Nr. anwenden. eines bestimmten Produkts in der Test- und Trainingsdatei.

train.select('Product_ID').distinct().count(),test.select('Product_ID').distinct().count()

Ausgabe:

(3633, 3492)

Wir haben jeweils 3492 und 3633 unterschiedliche Produkte in der Test- und Trainingsdatei. Jetzt wissen wir, dass wir in der Trainingsdatei eindeutigere Werte haben als in der Testdatei, da wir aus dem Ausgabeergebnis lernen können. Jetzt werden wir die Subtraktionsoperation verwenden, um die Product_ID-Kategorien herauszufinden, die nicht in der Trainingsdatei vorhanden sind, aber in der Testdatei vorhanden sind. Dasselbe kann man auch für alle Merkmale von kategorisch tun.

diff_cat_in_train_test=test.select('Product_ID').subtract(train.select('Product_ID'))

diff_cat_in_train_test.distinct().count()# Für eindeutige Zählung

Ausgabe:

46

Aus dem obigen Ergebnis können wir also wissen, dass es 47 verschiedene Kategorien gibt, die nicht in der Trainingsdatei, aber in der Testdatei vorhanden sind. Die Daten werden übersprungen oder aus der Testdatei gesammelt, die in der Datei des Zuges nicht vorhanden ist.

  • Berechnung der paarweisen Häufigkeit kategorialer Spalten?

Lassen Sie uns die paarweise Häufigkeit der Spalte im DataFrame berechnen, indem Sie die Operation can crosstab operation verwenden. Lassen Sie uns nun die Spalten „Geschlecht“ und „Alter“ im DataFrame des Zuges berechnen, indem wir eine Kreuztabellenoperation anwenden .

train.crossstab('Alter', 'Geschlecht').show()

Ausgabe:

+———-+—–+——+

|Alter_Geschlecht| F| M|

+———-+—–+——+

| 0-17| 5083| 10019|

| 46-50|13199| 32502|

| 18-25|24628| 75032|

| 36-45|27170| 82843|

| 55+| 5083| 16421|

| 51-55| 9894| 28607|

| 26-35|50752|168835|

+———-+—–+——+

Der eindeutige Wert von Gender ist der Spaltenname, und die unterschiedliche Menge von Age ist der Zeilenname, was im obigen Ergebnis zu sehen ist. In der Tabelle ist die Zählung des Paares null, wenn es nicht aufgetreten ist.

Wie bekomme ich DataFrame mit eindeutigen Zeilen?

Um eindeutige Zeilen zu finden und keine doppelten Zeilen einzuschließen, verwenden wir die Operation dropDuplicates . Der Datenrahmen wird ohne doppelte Zeilen abgerufen, indem die doppelten Zeilen eines Datenrahmens gelöscht werden. Bitte überprüfen Sie hier, um zu erfahren, wie die dropDuplicates-Prozedur durchgeführt wird, um alle eindeutigen Zeilen für die Spalten zu erhalten.

train.select('Alter','Geschlecht').dropDuplicates().show()

Ausgabe:

+—–+——+

| Alter|Geschlecht|

+—–+——+

|51-55| F|

|51-55| M|

|26-35| F|

|26-35| M|

|36-45| F|

|36-45| M|

|46-50| F|

|46-50| M|

| 55+| F|

| 55+| M|

|18-25| F|

| 0-17| F|

|18-25| M|

| 0-17| M|

+—–+——+

  • Wie lösche ich Zeilen mit Nullwert?

Wenn man alle Zeilen löschen möchte, die einen Nullwert haben, können wir die Operation namens dropna operation verwenden. Um eine Zeile aus dem DataFrame zu löschen, werden drei Optionen berücksichtigt.

  • Subset – es ist die Liste aller Namen der Spalten, die für die Operation des Löschens von Spalten mit Nullwerten berücksichtigt werden sollen.
  • Thresh – Dies hilft beim Löschen der Zeilen mit weniger als thresh Nicht-Null-Werten. Standardmäßig ist hier nichts angegeben.
  • Wie – Es kann auf zwei Arten verwendet werden – alle oder irgendwelche. Durch die Verwendung von any wird die Zeile gelöscht, wenn ein Wert in der Zeile null ist. Durch die Verwendung von all wird die Zeile verringert, wenn alle Werte der Zeilen null sind.

Hier werden wir nun alle diese Optionen einzeln verwenden, um die Zeilen zu löschen, die null sind, indem wir Standardoptionen wie subset, thresh, None for how, none, any verwenden.

train.dropna().count()

Ausgabe:

166821

  • Wie füllt man die Nullwerte des DataFrame mit der konstanten Nr.?

Um die Nullwerte mit Konstante Nr. zu füllen. Wir werden hier die Fillna- Operation verwenden. Es gibt zwei Parameter, die von der Fillna- Operation berücksichtigt werden müssen, um die Nullwerte zu füllen.

  • subset: Hier müssen die Spalten angegeben werden, die zum Füllen von Werten berücksichtigt werden sollen.
  • Wert: Hier können wir den Betrag angeben, der durch welchen Wert ersetzt werden soll, der in allen Spalten ein beliebiger Datentyp wie String, Float, Int sein kann.

Hier füllen wir '-1' anstelle von Nullwerten im Zug-DataFrame aus.

train.fillna(-1).show(2)

Ausgabe:

+——-+———-+——+—-+———-+————-+————————–+————–+——————+ ——————+——————+——–+

|Benutzer-ID|Produkt-ID|Geschlecht| Alter|Beruf|Stadt_Kategorie|Aufenthalt_in_aktueller_Stadt_Jahre|Familienstand|Produkt_Kategorie_1|Produkt_Kategorie_2|Produkt_Kategorie_3|Kauf|

+——-+———-+——+—-+———-+————-+————————–+————–+——————+ ——————+——————+——–+

|1000001| P00069042| F|0-17| 10| A| 2| 0| 3| -1| -1| 8370|

|1000001| P00248942| F|0-17| 10| A| 2| 0| 1| 6| 14| 15200|

+——-+———-+——+—-+———-+————-+————————–+————–+——————+ ——————+——————+——–+

zeigt nur die oberen 2 Zeilen

Fazit

PySpark gewinnt in der Welt der künstlichen Intelligenz und des maschinellen Lernens an Bedeutung. PySpark wird verwendet, um Probleme des maschinellen Lernens in der realen Welt zu lösen. Sie können RDD aus verschiedenen externen und vorhandenen Datenquellen erstellen und alle Arten von Transformationen darauf durchführen. Ich hoffe, dieser Artikel war informativ und konnte Ihnen tiefe Einblicke in PySpark-Datenrahmen geben.

Wenn Sie mehr über PySpark und andere Data-Science-Tools erfahren möchten, sehen Sie sich das PG-Diploma in Data Science von IIIT-B & upGrad an, das für Berufstätige entwickelt wurde und mehr als 10 Fallstudien und Projekte, praktische Workshops und Mentoring bietet Branchenexperten, 1-on-1 mit Branchenmentoren, mehr als 400 Stunden Lern- und Jobunterstützung bei Top-Unternehmen.

Ist PySpark effizienter als Pandas?

Ja, PySpark ist schneller als Pandas und übertrifft sogar Pandas in einem Benchmarking-Test. Grundsätzlich führt Pandas Operationen auf einer einzelnen Maschine durch, während PySpark Operationen auf mehreren Maschinen ausführt. Wenn Sie an einer Anwendung für maschinelles Lernen mit einem riesigen Datensatz arbeiten, ist PySpark die ideale Option, da es Vorgänge 100-mal schneller ausführen kann als Pandas. Aufgrund der JVM ist die Programmiersprache Scala bei der Datenanalyse und -verarbeitung zehnmal schneller als Python. Wenn Python-Programmcode zum Aufrufen von Spark-Bibliotheken verwendet wird, sind die Ergebnisse mittelmäßig.

Welche Nachteile hat die Verwendung von Apache PySpark?

Spark hat kein eigenes Dateiverwaltungssystem. Aufgrund der hohen Kosten für zusätzlichen Arbeitsspeicher, der für den Betrieb von Spark erforderlich ist, kann In-Memory-Computing unerschwinglich teuer sein. Bei der Verwendung von Apache Spark mit Hadoop stoßen Entwickler auf Schwierigkeiten mit kompakten Dateien. Daten werden in Spark stapelweise iteriert, wobei jede Iteration unabhängig geplant und verarbeitet wird. In Apache Spark werden Daten in einem vorgegebenen Zeitintervall in kleinere Batches aufgeteilt. Daher werden datensatzbasierte Fensterkriterien von Apache nicht unterstützt. Es stellt stattdessen zeitbasierte Fensterkriterien bereit.

Wie unterscheiden sich Datasets, DataFrame und RDD voneinander?

RDD ist eine geclusterte Sammlung von Datenelementen, die über mehrere Computer verteilt sind. Daten werden über RDDs dargestellt, die eine Sammlung von Java- oder Scala-Objekten sind. Ein DataFrame ist eine Sammlung von Daten, die in benannte Spalten strukturiert sind und über viele Server verteilt sind. In einer relationalen Datenbank ist es konzeptionell äquivalent zu einer Tabelle. Dataset ist eine Dataframe-API-Erweiterung, die die typsichere, objektorientierte Programmierschnittstellenfunktion der RDD-API bietet. Ein DataFrame ist eine verteilte Sammlung von Daten, ähnlich einem RDD, und ist nicht änderbar. Die Daten werden in benannte Spalten strukturiert, ähnlich einer Tabelle in einer relationalen Datenbank und nicht in einer RDD. Bei einfachen Aufgaben wie dem Gruppieren von Daten ist RDD langsamer als Dataframes und Datasets. Es verfügt über eine einfache API zum Ausführen von Aggregataufgaben. Es kann Daten schneller aggregieren als RDDs und Datasets.