我正在从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()
。
我觉得必须有一些更好的方法来解决这个问题,先转换为数组然后再转换为数据框感觉真的很笨。
答案 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_解决了我的问题。谢谢大家的帮助!