Hoe denkt u herhalen door middel van verschillende waarden van een kolom in een grote Pyspark dataframe? .distinct (). collect () werpt een grote taak waarschuwing

stemmen
0

Ik probeer te herhalen door alle van de verschillende waarden in kolom van een grote Pyspark dataframe. Wanneer ik probeer om het te doen met behulp van .distinct (). Collect () het roept een task te groot waarschuwing ook al zijn er slechts twee verschillende waarden. Hier ziet u enkele voorbeelden van code:

import pandas as pd
import numpy as np
from pyspark.sql import SparkSession
import pyarrow as pa

spark = SparkSession.builder.appName('Basics').getOrCreate()
spark.conf.set(spark.sql.execution.arrow.enabled, 'true')
length = 200000
table_data = pd.DataFrame({'a': np.random.randint(2,size = length), 'b': np.random.randint(2,size = length),'c': np.random.randint(2,size = length)})

data = spark.createDataFrame(table_data)

for x in data.select(a).distinct().collect():
    data = data.filter(a == '+str(x[0])+')

Deze code maakt deze waarschuwing die verwijst naar de regel voor x in data.select ( a ) afzonderlijke () collect ()..:

20/01/13 20:39:01 WARN TaskSetManager: Stage 0 contains a task of very large size (154 KB). The maximum recommended task size is 100 KB.

Hoe kun je doorlopen verschillende waarden in een kolom van een grote Pyspark dataframe zonder in problemen met het geheugen?

De vraag is gesteld op 13/01/2020 om 23:54
bron van user
In andere talen...                            


2 antwoorden

stemmen
0

Zoals je al weet, .collect()is geen best practice. Want het is een handeling die alle gegevens van executeurs over te dragen aan de bestuurder. Dus, in een grote dataframe met veel verschillende waarden, het verzamelen zal niet werken op alle. Uw probleem wortel is dat u al uw gedistribueerde gegevens van de executeurs JVM in de driver PVM te brengen.

In een hoog niveau, kon rond het werk voor uw probleem uit te wisselen geheugen met schijf.

U kunt uw dataframe met verschillende waarden te schrijven in een csv en dan lees het lijn weer door lijn met Python of Panda's *:

data.select("a").distinct().coalesce(1).write.csv("temp.csv")
# Specifically, it's a directory with one csv.

Met deze oplossing zal u geen enkel probleem met geheugen.

* Er zijn een heleboel oplossingen over hoe een groot CSV met Python of Panda's te lezen.

antwoordde op 15/01/2020 om 00:37
bron van user

stemmen
0

De waarschuwing:

20/01/13 20:39:01 WAARSCHUWEN TaskSetManager: Stadium 0 bevat een taak van zeer groot formaat (154 KB). De maximale aanbevolen taak grootte is 100 KB.

Verwijst naar de taak grootte die Spark sturen naar uitvoerders. Daarom denk ik dat dit heeft niets te maken met het geheugen, maar met de omvang van de taak en de gegevens die u mee te sturen. In uw geval de gegevens wordt geproduceerd via:

pd.DataFrame({'a': np.random.randint(2,size = length), 'b': np.random.randint(2,size = length),'c': np.random.randint(2,size = length)})

Nu is het probleem dat de grootte van die dataframe groter is dan de omvang van de toegestane taak grootte die is 100KB. U kunt de grootte van de op te halen table_datamet:

table_data.info(memory_usage='deep')

Dit moet geven u ongeveer 4.6MB = 4710.4KB. In uw geval de taak grootte is 154KB waaruit we kunnen concluderen dat de dataset 4710/154 ~ 30 partities (gelieve te bevestigen, indien mogelijk met data.rdd.getNumPartitions()).

De oplossing zou kunnen zijn verdeling op een hogere waarde om een ​​kleinere taak size <= 100 kB dat wil zeggen bij: 4710/50 = 94.2KB. Uw laatste vraag moet kijken als volgende:

data.repartition(50).select("a").distinct().collect()

Wat nu gebeurd is, is dat we deelden de eerste dataset tot 50 partities die resulteert in een veel kleinere grootte gegevens voor elke taak (~ 94KB zoals we hierboven zagen).

antwoordde op 29/01/2020 om 19:10
bron van user

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more