如何使用dask快速访问数据的子集?

How to use dask to quickly access subsets of the data?

我喜欢 pandas 的主要原因之一是它很容易归入子集,例如df[df.sample.isin(['a', 'c', 'p'])]df[df.age < 35]。 dask dataframe 是否也擅长(针对)这一点?我看过的教程都侧重于整列操作。

我的具体应用是(数千个命名的 GCMS 样本)x(每个样本约 20000 个时间点)x(500 m/z 通道)x(强度),我正在寻找最快的工具来拉任意子集,例如

df[df.sample.isin([...]) & df.rt.lt(800) & df.rt.gt(600) & df.mz.isin(...)]

如果 dask 是一个不错的选择,那么我将不胜感激有关如何最好地构建它的建议。

我试过的

到目前为止我尝试的是将每个样本转换为 pandas 看起来像

的数据帧
                  smp     rt       14       15       16       17       18  
0  160602_JK_OFCmix:1  271.0  64088.0   9976.0  26848.0  23928.0  89600.0   
1  160602_JK_OFCmix:1  271.1  65472.0  10880.0  28328.0  24808.0  91840.0   
2  160602_JK_OFCmix:1  271.2  64528.0  10232.0  27672.0  25464.0  90624.0   
3  160602_JK_OFCmix:1  271.3  63424.0  10272.0  27600.0  25064.0  90176.0   
4  160602_JK_OFCmix:1  271.4  64816.0  10640.0  27592.0  24896.0  90624.0  

('smp'是样品名,'rt'是保留时间,14,15,...500是m/z通道),用zlib保存到hdf,level=1 ,然后使用

制作 dask 数据框
ddf = dd.read_hdf(*.hdf5, key='/*', chunksize=100000, lock=False)

但是 df = ddf[ddf.smp.isin([...a couple of samples...]).compute()ddf['57'].mean().compute() 慢 100 倍。

(注意:这是 dask.set_options(get=dask.multiprocessing.get)

您的 dask.dataframe 由 HDF 文件支持,因此每次您执行任何操作时,您都是从磁盘读取数据。如果您的数据不适合内存,这很好,但如果您的数据适合内存,那就太浪费了。

如果您的数据适合内存

相反,如果您的数据适合内存,那么请尝试从 Pandas 数据帧中备份您的 dask.dataframe:

# ddf = dd.from_hdf(...)
ddf = dd.from_pandas(df, npartitions=20)

我希望您会从线程或分布式调度程序中看到更好的性能:http://dask.pydata.org/en/latest/scheduler-choice.html

如果您的数据不适合内存

尝试通过指定一组要在 read_hdf 调用中读取的列来减少必须读取的字节数

df = dd.read_hdf(..., columns=['57'])

或者,更好的是,使用可让您高效加载各个列的数据存储。您可以尝试像 Feather 或 Parquet 这样的东西,尽管它们都处于早期阶段:

我怀疑如果您小心避免一次阅读所有列,您可能只使用 Pandas 而不是使用 Dask.dataframe.