Dask是否真的比Pandas更快?700万行DataFrame性能测试咨询
问题
我正在处理大型DataFrame(计划处理1000万行数据),目前针对700万行、14列的DataFrame进行Dask与Pandas的性能基准测试。我是Dask新手,可能存在配置问题。
测试代码
import dask from dask.dataframe import from_pandas import sys timer = [] for cnt in range(10): ddf = from_pandas(df, npartitions=cnt+1) for j in range(3): t0 = pd.Timestamp.now() d = ddf[(ddf['FIRSTNAME'] == 'first') & (ddf['LASTNAME'] == 'last') & (ddf['dob']== 'yyyy-mm-dd')].compute() t1=(pd.Timestamp.now() - t0).total_seconds() t0 = pd.Timestamp.now() d = df[(df['FIRSTNAME'] == 'first') & (df['LASTNAME'] == 'last') & (df['dob']== 'yyyy-mm-dd')] t2=(pd.Timestamp.now() - t0).total_seconds() timer.append([cnt+1, j, t1,t2]) df = pd.DataFrame(timer, columns = ['partition','B','ddf','df']) df.groupby('partition').mean()
测试结果
B ddf df partition 1 1.0 3.548936 3.612199 2 1.0 3.556940 3.088862 3 1.0 3.097758 3.052725 4 1.0 4.054630 3.715735 5 1.0 3.391483 3.115667 6 1.0 3.241238 3.152429 7 1.0 3.676911 3.048394 8 1.0 3.395394 3.395397 9 1.0 3.183287 3.164195 10 1.0 3.306066 3.068059
结果显示仅1分区或8分区时Dask的速度略快于Pandas。我使用的是8核处理器,请问Dask是否会利用全部核心?有没有方法能让Dask运行得更快一些?
回答
Dask是否利用全部核心?
默认情况下,Dask会使用与CPU核心数匹配的线程池(8核对应默认8线程),但你的测试场景没充分发挥并行优势:
- 过滤操作会在各分区并行执行,但如果过滤后结果集极小,合并分区结果的开销会抵消并行收益。
- 700万行数据完全能放进内存,Pandas单线程内存操作效率极高,Dask的并行优势在数据超出内存、或复杂多阶段计算(如分组聚合、多表关联)时才会更显著。
让Dask更快的优化方法
- 调整分区策略:不要盲目加分区,分区过小会导致调度开销飙升(比如测试中4分区反而变慢)。内存中数据的分区数建议设为CPU核心数的1-2倍(8-16个),同时保证每个分区大小在100MB-1GB区间(Dask推荐的合理范围),可通过
ddf = from_pandas(df, npartitions=dask.system.cpu_count()*2)自动匹配。 - 提前设置复合索引:针对你用到的
FIRSTNAME、LASTNAME、dob三个过滤字段,给Dask DataFrame设置复合索引(ddf = ddf.set_index(['FIRSTNAME', 'LASTNAME', 'dob'])),Dask能利用索引快速定位分区,避免全表扫描,大幅提升过滤速度。 - 优化
compute()调用:纯CPU密集型任务可尝试改用进程池(compute(scheduler='processes'))规避GIL限制,也可显式指定线程数:dask.config.set(scheduler='threads', num_workers=8)确保用满核心。 - 避免重复创建Dask DataFrame:测试循环中每次重新调用
from_pandas会产生额外开销,建议提前创建不同分区数的ddf再执行测试。 - 匹配实际场景:内存能容纳数据时,Pandas单线程效率不会比Dask差太多;当数据量超出内存(如你计划的1000万行内存吃紧时),Dask分块处理的优势才会显现。
内容的提问来源于stack exchange,提问作者frank
相关产品推荐
相关产品推荐

