在许多情况下,是否有一个好的方法可以在dask数据帧上进行条件选择?

时间:2019-06-27 13:40:56

标签: python dask

我正在从Pandas切换到Dask,并希望在数据帧上进行条件选择。我想提供条件列表,最好以布尔数组/系列的形式提供,然后将获得一个应用了所有这些条件的数据框。

在Pandas中,我只是做了np.all([BoolSeries1,BoolSeries2,...])并将结果应用于数据框。

import dask.array as da
import dask.dataframe as dd
import numpy as np
import pandas as pd

df  = pd.DataFrame({'A' : np.random.rand(1000) , 'B': np.random.rand(1000), 'C' : np.random.rand(1000) })
ddf = dd.from_pandas(df, npartitions=10)

cuts = [(ddf['A'] > 0.4), (ddf['B'] < 0.4)]
bool_ar = da.all(da.asarray([cut.compute() for cut in cuts]),axis=0).compute()
ddf = ddf.loc[bool_ar.to_dask_dataframe()]['C']

这可行,但是速度很慢,因为我必须打两次.compute()

我觉得必须有一些更好的方法来解决这个问题,先转换为数组然后再转换为数据框感觉真的很笨。

2 个答案:

答案 0 :(得分:0)

您不想过早致电.compute。这使事物脱离了Dask空间,回到numpy / pandas中,这使得很难再次对齐事物,而且效率低下,相反,我认为您正在寻找&运算符

df  = pd.DataFrame({'A' : np.random.rand(1000) , 'B': np.random.rand(1000), 'C' : np.random.rand(1000) })
ddf = dd.from_pandas(df, npartitions=10)

df2 = df[(ddf['A'] > 0.4) & (ddf['B'] < 0.4)]

每次在dask数据框和dask数组或dask和numpy / pandas之间切换时,都会引入更多的复杂性。如果可以的话,最好保留在一个系统中。事情会更简单。

您可以使用for循环将此条件扩展到任意数量的条件。

conditions = [...]

cond = conditions[0]

for c in conditions[:1]:
    cond = cond & c

答案 1 :(得分:0)

好的,我想我已经解决了。

import dask.array as da
import dask.dataframe as dd
import numpy as np
import pandas as pd
import operator
from functools import reduce

df  = pd.DataFrame({'A' : np.random.rand(1000) , 'B': np.random.rand(1000), 'C' : np.random.rand(1000) })
ddf = dd.from_pandas(df, npartitions=10)

cuts = [(ddf['A'] > 0.4), (ddf['B'] < 0.4)]

bool_arr = reduce(operator.and_, cuts)
ddf = ddf.loc[bool_arr]['C']

使用reduce和操作符模块中的and_解决了我的问题。谢谢大家的帮助!