Одним із альтернативних рішень було б використання інструменту робочого циклу. Хоча це не так синтаксично весело, як ...
var
| do this
| then do that
... він все ще дозволяє вашій змінній стікати по ланцюгу, а використання dask дає додаткову перевагу розпаралелювання, де це можливо.
Ось як я використовую dask для створення шаблону ланцюга труб:
import dask
def a(foo):
return foo + 1
def b(foo):
return foo / 2
def c(foo,bar):
return foo + bar
workflow = {'a_task':(a,1),
'b_task':(b,'a_task',),
'c_task':(c,99,'b_task'),}
dask.get(workflow,'c_task')
Попрацювавши з еліксиром, я хотів використати шаблон конвеєра в Python. Це не зовсім однаковий шаблон, але він схожий і, як я вже сказав, має додаткові переваги розпаралелювання; якщо ви скажете dask отримати завдання у вашому робочому процесі, яке не залежить від того, щоб інші виконувались першими, вони виконуватимуться паралельно.
Якщо ви хочете полегшити синтаксис, ви можете обернути його чимось, що б подбало про іменування завдань для вас. Звичайно, у цій ситуації вам знадобляться всі функції, щоб взяти конвеєр як перший аргумент, і ви втратите будь-яку користь від паралізації. Але якщо у вас все добре, ви можете зробити щось подібне:
def dask_pipe(initial_var, functions_args):
'''
call the dask_pipe with an init_var, and a list of functions
workflow, last_task = dask_pipe(initial_var, {function_1:[], function_2:[arg1, arg2]})
workflow, last_task = dask_pipe(initial_var, [function_1, function_2])
dask.get(workflow, last_task)
'''
workflow = {}
if isinstance(functions_args, list):
for ix, function in enumerate(functions_args):
if ix == 0:
workflow['task_' + str(ix)] = (function, initial_var)
else:
workflow['task_' + str(ix)] = (function, 'task_' + str(ix - 1))
return workflow, 'task_' + str(ix)
elif isinstance(functions_args, dict):
for ix, (function, args) in enumerate(functions_args.items()):
if ix == 0:
workflow['task_' + str(ix)] = (function, initial_var)
else:
workflow['task_' + str(ix)] = (function, 'task_' + str(ix - 1), *args )
return workflow, 'task_' + str(ix)
def foo(df):
return df[['a','b']]
def bar(df, s1, s2):
return df.columns.tolist() + [s1, s2]
def baz(df):
return df.columns.tolist()
import dask
import pandas as pd
df = pd.DataFrame({'a':[1,2,3],'b':[1,2,3],'c':[1,2,3]})
Тепер за допомогою цієї обгортки ви можете створити конвеєр, дотримуючись будь-якого з цих синтаксичних зразків:
подобається це:
workflow, last_task = dask_pipe(df, [foo, baz])
print(dask.get(workflow, last_task))
workflow, last_task = dask_pipe(df, {foo:[], bar:['string1', 'string2']})
print(dask.get(workflow, last_task))
crime_by_state %>% filter(State=="New York", Year==2005) ...
з кінця Як dplyr замінити мої найбільш поширені ідіоми R .