我有这个代码,它在每个独特的变量组合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计算的情况下分配给新变量?
答案 0 :(得分:3)
因此,如果您想并行化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 ...