python Dask DataFrame, поддержка (тривиально распараллеливаемой) строки применяется?

Я недавно нашел ДАСК модуль, который стремится быть простой в использовании модуль параллельной обработки python. Большой пункт продажи для меня заключается в том, что он работает с пандами.

после прочтения немного на ее Man-странице, Я не могу найти способ сделать это тривиально распараллеливаемых задач:

ts.apply(func) # for pandas series
df.apply(func, axis = 1) # for pandas DF row apply

на данный момент, чтобы достичь этого в даске, АФАИК,

ddf.assign(A=lambda df: df.apply(func, axis=1)).compute() # dask DataFrame

который является уродливым синтаксисом и на самом деле медленнее, чем outright

df.apply(func, axis = 1) # for pandas DF row apply

любой предложение?

Edit: спасибо @MRocklin за функцию карты. Кажется, это медленнее, чем обычные панды. Связано ли это с проблемой выпуска pandas GIL или я делаю это неправильно?

import dask.dataframe as dd
s = pd.Series([10000]*120)
ds = dd.from_pandas(s, npartitions = 3)

def slow_func(k):
    A = np.random.normal(size = k) # k = 10000
    s = 0
    for a in A:
        if a > 0:
            s += 1
        else:
            s -= 1
    return s

s.apply(slow_func) # 0.43 sec
ds.map(slow_func).compute() # 2.04 sec

2 ответов


map_partitions

вы можете применить свою функцию ко всем разделам вашего фрейма данных с помощью


а в dask.dataframe.применить ответственность делегатов к map_partitions:

@insert_meta_param_description(pad=12)
def apply(self, func, convert_dtype=True, meta=no_default, args=(), **kwds):
    """ Parallel version of pandas.Series.apply
    ...
    """
    if meta is no_default:
        msg = ("`meta` is not specified, inferred from partial data. "
               "Please provide `meta` if the result is unexpected.\n"
               "  Before: .apply(func)\n"
               "  After:  .apply(func, meta={'x': 'f8', 'y': 'f8'}) for dataframe result\n"
               "  or:     .apply(func, meta=('x', 'f8'))            for series result")
        warnings.warn(msg)

        meta = _emulate(M.apply, self._meta_nonempty, func,
                        convert_dtype=convert_dtype,
                        args=args, **kwds)

    return map_partitions(M.apply, self, func,
                          convert_dtype, args, meta=meta, **kwds)