使用 dask read_parquet 方法过滤会产生不需要的结果

Posted

技术标签:

【中文标题】使用 dask read_parquet 方法过滤会产生不需要的结果【英文标题】:filtering with dask read_parquet method gives unwanted results 【发布时间】:2018-12-17 01:32:38 【问题描述】:

我正在尝试使用dask read_parquet 方法和filters kwarg 读取镶木地板文件。但是它有时不会根据给定的条件进行过滤。

示例: 使用dates 列创建和保存数据框

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

nums  = range(1,6)
dates = pd.date_range('2018-07-01', periods=5, freq='1d')
df = pd.DataFrame('dates':dates, 'nums': nums)

ddf = dd.from_pandas(df, npartitions=3).to_parquet('test_par', engine = 'fastparquet')

当我从'test_par' 文件夹中读取和过滤dates 列时,它似乎不起作用

filters=[('dates', '>', np.datetime64('2018-07-04'))]
df  = dd.read_parquet('test_par', engine='fastparquet', filters=filters).compute()

正如您在输出中看到的那样,2018-07-032018-07-04 存在。

+-------+------------+------+
|       | dates      | nums |
+-------+------------+------+
| index |            |      |
+-------+------------+------+
| 2     | 2018-07-03 | 3    |
+-------+------------+------+
| 3     | 2018-07-04 | 4    |
+-------+------------+------+
| 4     | 2018-07-05 | 5    |
+-------+------------+------+

我做错了吗?还是我应该在 github 上报告这个?

【问题讨论】:

【参考方案1】:

filters 关键字是一个行组操作(行组是一组数据行的拼花术语,如数据帧的分区)。它不在分区内进行任何过滤。

当您使用filters 时,您将排除分区,根据文件中的最大/最小统计信息,在给定分区中没有没有行可以匹配给定过滤器.例如,如果您指定 x>5,则 min=2,max=4 的分区将被排除,但 min=2,max=6 的分区不会,即使后者仅包含满足过滤器。

要过滤数据,您仍然应该使用通常的语法

df[df.dates > np.datetime64('2018-07-04')]

除了过滤器,并将过滤器的使用视为一种可选的优化。没有它,Dask 甚至必须读取没有好的数据的分区,然后应用条件,导致这些分区没有结果。如果可能,最好不要加载它们。

【讨论】:

以上是关于使用 dask read_parquet 方法过滤会产生不需要的结果的主要内容,如果未能解决你的问题,请参考以下文章

将Dask包的Pandas DataFrame转换为单个Dask DataFrame

如何将单个镶木地板文件从 s3 读入 dask 数据帧?

读取大量 parquet 文件:read_parquet vs from_delayed

使用 Dask 进行 Parquet 谓词下推过滤

使用Dask并行过滤数据帧的块

我如何将每个Parquet行组读入一个单独的分区?