如何在Dask数据帧组中对值进行排序?

时间:2017-03-15 14:30:52

标签: python pandas dask

我有这个代码,它在每个独特的变量组合A'和'分组B'中生成自回归项。

for i in range(1, 5):
    df.loc[:,'var_' + str(i)] = df.sort_values(by='date']) \
                                    .groupby(['grouping A', 'grouping B']) \
                                    ['target'].sum().shift(i).ffill().bfill().values

是否可以对值进行排序,分组,移位,然后在没有Dask计算的情况下分配给新变量?

1 个答案:

答案 0 :(得分:3)

Dask.delayed

因此,如果您想并行化for循环,可以使用dask.delayed执行以下操作

ddf = dask.delayed(df)
results = []

for i in range(1, 5):
    result = ddf.sort_values(by='date']) \
                .groupby(['grouping A', 'grouping B']) \
                ['target'].sum().shift(i).ffill().bfill().values
    results.append(result)

results = dask.compute(results)

for i, result in results:
    df[...] = result  # mutate dataframe as you like

那就是我们将数据帧包装在dask.delayed中。对它的任何方法调用都是懒惰的。我们收集所有这些惰性方法调用,然后与dask.compute一起调用它们。我们不希望在此期间改变数据帧(这很奇怪),所以我们之后会这样做。

大型数据框

如果您想使用大型数据帧执行此操作,那么您可能希望使用dask.dataframe。这将不那么简单,但希望能够很好地运作。你应该注意sort_values操作。分布式排序是一个非常困难的问题并且非常昂贵。如果可能,您希望尽量减少这种情况。

import dask.dataframe as dd
df = load distributed dataframe with `dd.read_csv`, `dd.read_parquet`, etc.

df = df.set_index('date').persist()

results = []
for i in range(1, 5):
    results = ddf.groupby(['grouping A', 'grouping B']) \
                ['target'].sum().shift(i).ffill().bfill()

ddf2 = dd.concat([ddf] + results, axis=1)

我们在这里使用set_index而不是sort_values,我们确保只使用一次(它可能比此处的任何其他操作长10到100倍)。然后我们使用普通的groupby等语法。事情应该没问题(虽然我不得不承认我还没有确认ffill和bfill肯定是实现的。我假设这样。我们以前不想要在计算期间改变我们的数据(这很奇怪)所以我们之后做了一个concat。

也许更简单

在groupby-sum之后,你可能会得到一个大大减少的数据帧。使用Dask.dataframe,然后抛弃Dask并回到Pandas的舒适

ddf = load distributed dataframe with `dd.read_csv`, `dd.read_parquet`, etc.
pdf = ddf.groupby(['grouping A', 'grouping B']).target.sum().compute()
... do whatever you want with a much smaller pandas dataframe ...