web-dev-qa-db-fra.com

Dask: Comment pourrais-je paralléliser mon code avec un dask retardé?

C'est ma première aventure dans le traitement parallèle et j'ai étudié Dask mais j'ai du mal à le coder.

J'ai regardé leurs exemples et leur documentation et je pense que dask.delayed fonctionnera mieux. J'ai tenté d'envelopper mes fonctions avec le retardé (nom_fonction) ou d'ajouter un décorateur @delayed, mais je n'arrive pas à le faire fonctionner correctement. J'ai préféré Dask aux autres méthodes car il est fait en python et pour sa simplicité (supposée). Je sais que dask ne fonctionne pas sur la boucle for, mais ils disent qu'il peut fonctionner à l'intérieur d'une boucle .

Mon code passe des fichiers via une fonction qui contient des entrées vers d'autres fonctions et ressemble à ceci:

from dask import delayed
filenames = ['1.csv', '2.csv', '3.csv', etc. etc. ]
for count, name in enumerate(filenames)"
    name = name.split('.')[0]
    ....

puis faites un pré-traitement ex:

    preprocess1, preprocess2 = delayed(read_files_and_do_some_stuff)(name)

puis j'appelle un constructeur et passe les pre_results aux appels de fonction:

    fc = FunctionCalls()
    Daily = delayed(fc.function_runs)(filename=name, stringinput='Daily',
                             input_data=pre_result1, model1=pre_result2)

Ce que je fais ici, c'est que je passe le fichier dans la boucle for, fais un peu de prétraitement puis passe le fichier en deux modèles.

Réflexions ou conseils sur la façon de paralléliser cela? J'ai commencé à avoir des erreurs étranges et je ne savais pas comment réparer le code. Le code fonctionne tel quel. J'utilise un tas de pandas dataframes, séries et tableaux numpy, et je préférerais ne pas revenir en arrière et tout changer pour travailler avec dask.dataframes etc.

Le code dans mon commentaire peut être difficile à lire. Ici, c'est d'une manière plus formatée.

Dans le code ci-dessous, lorsque je tape print (mean_squared_error), je reçois simplement: Delayed ('mean_squared_error-3009ec00-7ff5-4865-8338-1fec3f9ed138')

from dask import delayed
import pandas as pd
from sklearn.metrics import mean_squared_error as mse
filenames = ['file1.csv']

for count, name in enumerate(filenames):
    file1 = pd.read_csv(name)
    df = pd.DataFrame(file1)
    prediction = df['Close'][:-1]
    observed = df['Close'][1:]
    mean_squared_error = delayed(mse)(observed, prediction)
20
Monty

Vous devez appeler dask.compute pour éventuellement calculer le résultat. Voir documentation dask.delayed .

Code séquentiel

import pandas as pd
from sklearn.metrics import mean_squared_error as mse
filenames = [...]

results = []
for count, name in enumerate(filenames):
    file1 = pd.read_csv(name)
    df = pd.DataFrame(file1)  # isn't this already a dataframe?
    prediction = df['Close'][:-1]
    observed = df['Close'][1:]
    mean_squared_error = mse(observed, prediction)  
    results.append(mean_squared_error)

Code parallèle

import dask
import pandas as pd
from sklearn.metrics import mean_squared_error as mse
filenames = [...]

delayed_results = []
for count, name in enumerate(filenames):
    df = dask.delayed(pd.read_csv)(name)
    prediction = df['Close'][:-1]
    observed = df['Close'][1:]
    mean_squared_error = dask.delayed(mse)(observed, prediction)
    delayed_results.append(mean_squared_error)

results = dask.compute(*delayed_results)
28
MRocklin

Une solution beaucoup plus claire, OMI, que la réponse acceptée est cet extrait.

from dask import compute, delayed
import pandas as pd
from sklearn.metrics import mean_squared_error as mse
filenames = [...]

def compute_mse(file_name):
    df = pd.read_csv(file_name)
    prediction = df['Close'][:-1]
    observed = df['Close'][1:]
    return mse(observed, prediction)

delayed_results = [delayed(compute_mse)(file_name) for file_name in filenames]
mean_squared_errors = compute(*delayed_results, scheduler="processes")
4
Vitalis