本文介绍了今年早些时候进行的 2021 年 Dask 用户调查结果。感谢所有花时间填写问卷的人!这些结果有助于我们更好地了解 Dask 社区,并将指导未来的开发工作。

原始数据以及初步分析结果可以在此 binder 中找到

Binder

如果您在数据中发现了任何东西,请告知我们。

目录

亮点

我们收到了 247 份调查回复(与去年约 240 份回复大致相同)。总体而言,回复与往年相似。

我们在调查中提出了 43 个问题(比前一年增加了 18 个问题)。我们询问了大量关于人们使用的数据集类型、Dask 的稳定性以及人们工作的行业类型的新问题。

我们的社区希望

  • 更多文档和示例
  • 更多中级文档
  • 提高 Dask 的弹性(即计算能否完成?)

用户也看重这些特性

  • 改进的扩展性
  • 易于部署
  • 更好的 scikit-learn 和机器学习支持

典型的 Dask 用户

调查显示我们的社区具有多样性,并且没有统一的使用 Dask 的方式。尽管如此,我们假定的“典型”Dask 用户

  • 处理千兆字节大小的数据集
  • 存储在本地文件系统上
  • 使用 Dask 介于 1 到 3 年之间
  • 偶尔使用 Dask,而非每天
  • 至少部分时间以交互方式使用 Dask
  • 使用计算集群(可能)
  • 喜欢使用网页浏览器查看 Dask 面板
  • 大多数情况下,Dask 的稳定性足以满足他们的需求,但提高 Dask 的弹性会有所帮助
  • 使用 Dask dataframe、delayed 以及可能使用 Dask Array API,同时使用 numpy/pandas 和其他 Python 库
  • 对这些人最有帮助的是更多文档,以及在其领域中使用 Dask 的更多示例。
  • 他们可能在科学领域工作(或许是地球科学、生命科学、物理学或天文学),或者他们可能在会计、金融、保险领域工作,或者是一名技术工作者。

您可以在此处阅读往年调查结果:2020 年调查结果, 2019 年调查结果

# Let's load in the survey data...
%matplotlib inline

from pprint import pprint
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import textwrap
import re


df2019 = (
    pd.read_csv("data/2019-user-survey-results.csv.gz", parse_dates=["Timestamp"])
      .replace({"How often do you use Dask?": "I use Dask all the time, even when I sleep"}, "Every day")
)

df2020 = (
    pd.read_csv("data/2020-user-survey-results.csv.gz")
      .assign(Timestamp=lambda df: pd.to_datetime(df['Timestamp'], format="%Y/%m/%d %H:%M:%S %p %Z").astype('datetime64[ns]'))
      .replace({"How often do you use Dask?": "I use Dask all the time, even when I sleep"}, "Every day")
)

df2021 = (
    pd.read_csv("data/2021-user-survey-results.csv.gz")
      .assign(Timestamp=lambda df: pd.to_datetime(df['Timestamp']).astype('datetime64[ns]'))
      .replace({"How often do you use Dask?": "I use Dask all the time, even when I sleep"}, "Every day")
)

common = df2019.columns.intersection(df2020.columns).intersection(df2021.columns)
added = df2021.columns.difference(df2020.columns)
dropped = df2020.columns.difference(df2021.columns)

df = pd.concat([df2019, df2020, df2021])
df['Year'] = df.Timestamp.dt.year
df = df.set_index(['Year', 'Timestamp']).sort_index()

谁是 Dask 用户?

大多数人表示他们偶尔使用 Dask,而一小部分人每天都使用 Dask。人们使用 Dask 的时长差异很大,最常见的回答是介于一到三年之间。

q = "How often do you use Dask?"
ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(";").explode().to_frame());
ax.set(ylabel="", title=q);

png

q = "How long have you used Dask?"  # New question in 2021
order = ["More than 3 years", "1 - 3 years", "3 months - 1 year", "Less than 3 months", "I've never used Dask"]
ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(";").explode().to_frame(), order=order);
ax.set(ylabel="", title=q);

png

略多于一半的受访者与其他人(他们的团队或组织)一起使用 Dask,另一半则独自使用 Dask。

q = "Do you use Dask as part of a larger group?"
order = [
    'I use Dask mostly on my own',
    'My team or research group also use Dask',
    'Beyond my group, many people throughout my institution use Dask',
]
ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(";").explode().to_frame(), order=order)
ax.set(ylabel="", title=q);

png

在过去一年中,表示其机构内许多人使用 Dask 的人数有所增加(2021 年有 32 人,而 2020 年为 19 人)。在 2019 年至 2020 年期间,表示其直属团队也使用 Dask 的人数有所下降(2019 年有 121 人,而 2020 年为 94 人)。目前尚不清楚为什么会出现这些变化,所以观察未来几年会发生什么将很有趣。

q = 'Do you use Dask as part of a larger group?'
ax = sns.countplot(y=q, hue="Year", data=df.reset_index());
ax.set(ylabel="", title=q);

png

您在哪一个行业工作?

调查涵盖了广泛的行业。

近一半的回复来自与科学、学术界或政府实验室相关的行业。地球科学领域的回复最多,生命科学、物理学和天文学也是热门领域。

约 30% 的回复来自商业和科技领域。其中,来自会计/金融/保险领域的人员与来自其他技术领域的人员数量大致相当。

约 10% 的回复来自制造业、工程以及其他行业(能源、航空航天等)。其余回复难以分类。

q = "What industry do you work in?"  # New question in 2021
data = df2021[q].dropna().str.split(";").explode().to_frame()
order = data.value_counts()[data.value_counts() > 1].keys().get_level_values(0)
ax = sns.countplot(y=q, data=data, order=order);
ax.set(ylabel="", title=q);

png

您升级到较新版本的 Python 库有多容易?

大多数用户在需要时能够轻松升级到较新版本的 Python 库。

q = "How easy is it for you to upgrade to newer versions of Python libraries"
sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame()).set_ylabel('Scale from 1 (Difficult) to 4 (Easy)');

png

人们喜欢如何使用 Dask

人们喜欢将 Dask 与 numpy 和 pandas 以及其他一系列 Python 库结合使用。最受欢迎的 Dask API 是 Dask DataframesDask DelayedDask Arrays

绝大多数人喜欢至少部分时间通过 Jupyter 或 IPython 以交互方式使用 Dask,并且大多数人使用网页浏览器查看 Dask 面板

您经常与 Dask 一起使用的其他库有哪些?

人们与 Dask 一起使用的十个最常用库是:numpy, pandas, xarray, scikit-learn, scipy, statsmodels, matplotlib, xgboost, numba, 和 joblib

q = "What are some other libraries that you often use with Dask?"
data = df2021[q].dropna().str.lower().str.split(", ").explode().to_frame()
labels = pd.value_counts(data[q]).iloc[:10].index
sns.countplot(y=q, data=data, order=labels).set_ylabel('');

png

Dask API

人们使用的三个最受欢迎的 Dask API 是

  1. Dask Dataframes
  2. Dask Delayed
  3. Dask Arrays

2021 年,与往年相比,使用 dask delayed 的人数略有增加。这可能是件好事,随着人们在使用 Dask 方面积累经验和信心,他们可能更倾向于开始使用更高级的功能,例如 delayed。除了这一变化,偏好与往年结果非常相似。

apis = df2021['Dask APIs'].str.split(", ").explode()
top = apis.value_counts().loc[lambda x: x > 10]
apis = apis[apis.isin(top.index)].reset_index()

sns.countplot(y="Dask APIs", data=apis);

png

交互式还是批处理?

绝大多数人喜欢至少部分时间通过 Jupyter 或 IPython 以交互方式使用 Dask。只有不到 15% 的 Dask 用户仅在批处理模式下使用 Dask(提交将来运行的脚本)。

q = 'Interactive or Batch?'
data = df2021[q].dropna()
data = data.str.replace('Interactive:  I use Dask with Jupyter or IPython when playing with data, Batch: I submit scripts that run in the future', "Interactive and Batch")
data = data.str.replace('Interactive:  I use Dask with Jupyter or IPython when playing with data', "Interactive")
data = data.str.replace('Batch: I submit scripts that run in the future', "Batch")
order = ["Interactive and Batch", "Interactive", "Batch"]
sns.countplot(y=q, data=data.explode().to_frame(), order=order).set_ylabel('');

png

您如何查看 Dask 的面板?

大多数人使用网页浏览器查看 Dask 面板。一小部分人使用 dask jupyterlab 扩展

有些人仍然不确定面板的用途。如果您也是如此,您可能会想观看这个 20 分钟的视频,它解释了为什么面板超级有用,或者在此处查看其余文档 此处

q = "How do you view Dask's dashboard?"
ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(", ").explode().to_frame());
ax.set(ylabel="", title=q);

png

本地机器还是集群?

大约三分之二的受访者至少部分时间使用计算集群。

q = 'Local machine or Cluster?'
df[q].dropna().str.contains("Cluster").astype(int).groupby("Year").mean()
Year
2019    0.654902
2020    0.666667
2021    0.630081
Name: Local machine or Cluster?, dtype: float64
q = 'Local machine or Cluster?'
order = [
    'Personal laptop',
    'Large workstation',
    'Cluster of 2-10 machines',
    'Cluster with 10-100 machines',
    'Cluster with 100+ machines'
]
ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(", ").explode().to_frame(), order=order);
ax.set(ylabel="", title=q);

png

如果您使用集群,如何启动 Dask?

SSH 是在计算集群上启动 Dask 最常用的方式,其次是 HPC 资源管理器,然后是 Kubernetes。

q = "If you use a cluster, how do you launch Dask? "
data = df2021[q].dropna()
data = data.str.replace("HPC resource manager (SLURM, PBS, SGE, LSF or similar)", "HPC resource manager (SLURM PBS SGE LSF or similar)", regex=False)
data = data.str.replace("I don't know, someone else does this for me", "I don't know someone else does this for me", regex=False)
data = data.str.split(", ").explode().to_frame()
order = data.value_counts()[data.value_counts() > 1].keys().get_level_values(0)
ax = sns.countplot(y=q, data=data, order=order);
ax.set(ylabel="", title=q);

png

如果您使用集群,是否需要在同一个集群中使用多种工作节点类型?

在使用计算集群的人中,略低于一半的人需要在同一个集群中使用多种工作节点类型。例如,这可能包括混合使用带 GPU 和不带 GPU 的工作节点,混合使用内存分配低或高的工作节点等。

q = "If you use a cluster, do you have a need for multiple worker / machine types (e.g. GPU / no GPU, low / high memory) in the same cluster?"  # New question in 2021
ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(";").explode().to_frame());
ax.set(ylabel="", title="Do you need multiple worker/machine types on a cluster?");

png

数据集

您的数据集通常有多大?

Dask 用户最常处理千兆字节大小的数据集。很少有用户处理拍字节大小的数据集。

q = "How large are your datasets typically?"  # New question in 2021
ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(", ").explode().to_frame());
ax.set(ylabel="", title=q);

png

您的数据集通常存储在哪里?

大多数人将数据存储在本地文件系统上。

q = "Where are your datasets typically stored?"  # New question in 2021
data = df2021[q].dropna().str.split(", ").explode().to_frame()
order = data.value_counts()[data.value_counts() > 1].keys().get_level_values(0)
ax = sns.countplot(y=q, data=data, order=order);
ax.set(ylabel="", title=q);

png

您通常使用哪些文件格式?

最常见的两种文件格式(csvparquet)在 Dask Dataframe 用户中很受欢迎。JSON 文件格式也经常与 Dask 一起使用。第四和第五常见的的文件类型(HDF5zarr)在 Dask Array 用户中很受欢迎。这与我们了解到的 Dask Dataframe API 最受欢迎、Dask Arrays 紧随其后的情况相符。

q = "What file formats do you typically work with?"  # New question in 2021
data = df2021[q].dropna().str.split(", ").explode().to_frame()
order = data.value_counts()[data.value_counts() > 1].keys().get_level_values(0)
ax = sns.countplot(y=q, data=data, order=order);
ax.set(ylabel="", title=q);

png

这个调查问题呈现出长尾效应:报告了各种各样的专业文件格式,其中大多数只被一两个回复调查的个人使用。

这些专业文件格式中有很多存储图像数据,特定于特定领域(天文学、地球科学、显微镜等)。

list(data.value_counts()[data.value_counts() == 1].keys().get_level_values(0))
['proprietary measurement format',
 'netCDF3',
 'czi',
 'specifically NetCDF4',
 'grib2',
 'in-house npy-like array format',
 'jpeg2000',
 'netCDF4 (based on HDF5)',
 'proprietary microscopy file types. Often I convert to Zarr with a loss of metadata.',
 'sas7bdat',
 'npy',
 'npy and pickle',
 'root with uproot',
 'root',
 'regular GeoTiff',
 '.npy',
 'Text',
 'VCF BAM CRAM',
 'UM',
 'CASA measurement sets',
 'Casa Tables (Radio Astronomy specific)',
 'Custom binary',
 'FITS',
 'FITS (astronomical images)',
 'FITS and a custom semi-relational table specification that I want to kill and replace with something better',
 'Feather (Arrow)',
 'GPKG',
 'GeoTIFF',
 'NetCDF4',
 'Netcdf',
 'Netcdf4',
 'PP',
 'SQL',
 'SQL query to remote DB',
 'SQL to Dataframe',
 'Seismic data (miniSEED)',
 'TFRecords',
 'TIFF',
 'Testing with all file formats. Just want it as a replacement for spark. ',
 '.raw image files',
 'ugh']

XKCD comic 927: Standards

XKCD 漫画 “标准” https://xkcd.com/927/

偏好的云服务?

最受欢迎的云解决方案是 Amazon Web Services (AWS),其次是 Google Cloud Platform (GCP) 和 Microsoft Azure。

q = "Preferred Cloud?"
order = [
    "Amazon Web Services (AWS)",
    "Google Cloud Platform (GCP)",
    "Microsoft Azure",
    "Digital Ocean",
]
ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(", ").explode().to_frame(), order=order);
ax.set(ylabel="", title=q);

png

您是否使用 Dask 项目进行部署?

在使用 Dask 项目进行部署的用户中,dask-jobqueuedask helm chart 是两个最受欢迎的选择。人们用于部署的项目种类繁多。

q = "Do you use Dask projects to deploy?"
order = [
    "dask-jobqueue",
    "dask's helm chart",
    "dask-kubernetes",
    "dask's docker image at daskdev/dask",
    "dask-gateway",
    "dask-ssh",
    "dask-cloudprovider",
    "dask-yarn",
    "qhub",
    "dask-mpi",
]
ax = sns.countplot(y=q, data=df2021[q].dropna().str.lower().str.split(", ").explode().to_frame(), order=order);
ax.set(ylabel="", title=q);

png

诊断

我们之前看到,大多数人喜欢使用网页浏览器查看 Dask 面板。

在面板中,人们表示最有用的诊断图是

  1. 任务流图
  2. 进度图,以及
  3. 每个工作节点的内存使用图
q = "Which Diagnostic plots are most useful?"  # New question in 2021
ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(', ').explode().to_frame());
ax.set(ylabel="", title=q);

png

我们还在 2021 年提出了一些关于诊断的新问题。

我们发现大多数人(65%)不使用 Dask 性能报告,这是一种将诊断面板保存为静态 HTML 图以供后续查看的方式。

q = "Do you use Dask's Performance reports?"  # New question in 2021
ax = sns.countplot(y=q, data=df2021[q].explode().to_frame(), order=["Yes", "No"]);
ax.set(ylabel="", title=q);

png

很少有人使用 Dask 的 Prometheus 指标。如果您有兴趣了解如何使用此功能,Jacob Tomlinson 有一篇关于 使用 Prometheus + Grafana 监控 Dask + RAPIDS 的优秀文章。

q = "Do you use Dask's Prometheus Metrics?"  # New question in 2021
ax = sns.countplot(y=q, data=df2021[q].explode().to_frame(), order=["Yes", "No"]);
ax.set(ylabel="", title=q);

png

稳定性

我们问了许多关于 Dask 稳定性的问题,其中许多是 2021 年的新问题。

大多数人认为 Dask 的弹性足以满足他们的需求(例如:计算能够完成)。然而,这是一个我们可以改进的领域,因为有 36% 的人对此不满意。这是 2021 年的一个新问题,所以我们无法判断随着时间的推移,人们对 Dask 弹性的看法发生了怎样的变化。

q = "Is Dask resilient enough for you? (e.g. computations complete)."  # new question in 2021
ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame(), order=["Yes", "No"]);
ax.set(ylabel="", title="Is Dask resilient enough for you?");

png

大多数人认为 Dask 总体上对他们来说足够稳定(例如:不同版本发布之间)。这与往年的调查结果相似。

q = "Is Dask stable enough for you?"
ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame(), order=["Yes", "No"]);
ax.set(ylabel="", title=q);

png

人们还表示 Dask 的 API 对他们来说也足够稳定。

q = "Is Dask's API stable enough for you?"
ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame(), order=["Yes", "No"]);
ax.set(ylabel="", title=q);

png

绝大多数人对当前的发布频率感到满意(大约每两周一次)。

q = "How is Dask's release frequency?"  # New question in 2021
ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame());
ax.set(ylabel="", title=q);

png

大多数人表示,如果 Dask 提供长期支持版本,他们会将代码锁定在该版本上。

q = "If Dask had Long-term support (LTS) releases, would you pin your code to use them?"  # New question in 2021
ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame(), order=["Yes", "No"]);
ax.set(ylabel="", title="Would you pin to a long term support release?");

png

用户满意度、支持和文档

我们在 2021 年的调查中问了许多关于用户满意度的新问题。

Dask 有多容易使用?

大多数人表示 Dask 适度易用,与之前的调查结果一致。

q = "On a scale of 1 - 5 (1 being hardest, 5 being easiest) how easy is Dask to use?"
ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame());
ax.set(ylabel="1 = Difficult, 5 = Easy", title="How easy is Dask to use?");

png

Dask 的文档如何?

大多数人认为 Dask 的文档相当不错。

q = "How is Dask's documentation?"  # New question in 2021
ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame());
ax.set(ylabel="1 = Not good, 5 = Great", title=q);

png

您对 GitHub 上维护人员的响应速度有多满意?

几乎所有回复者都对 Dask 在 GitHub 上的维护人员响应速度给予了积极评价。

q = "How satisfied are you with maintainer responsiveness on GitHub?"  # New question in 2021
ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame());
ax.set(ylabel="1 = Not satisfied, 5 = Thrilled", title=q);

png

过去六个月中,您使用了哪些 Dask 资源来获取支持?

大多数用户首先会在 dask.org 上的文档中寻找帮助。

2021 年对此问题的回复分布与往年非常相似,例外的是,在 2019 年似乎没有人知道 Dask YouTube 频道或 Gitter 聊天室的存在。

q = 'What Dask resources have you used for support in the last six months?'

resource_map = {
    "Tutorial": "Tutorial at tutorial.dask.org",
    "YouTube": "YouTube channel",
    "gitter": "Gitter chat"
}

df[q] = df[q].str.replace(';',', ')  # Make separator values consistent
d = df[q].str.split(', ').explode().replace(resource_map)
top = d.value_counts()[:8].index
d = d[d.isin(top)]

fig, ax = plt.subplots(figsize=(8, 8))
ax = sns.countplot(y=q, hue="Year", data=d.reset_index(), ax=ax);
ax.set(ylabel="", title=q);

png

改进建议

目前哪些最能帮助您?

人们认为目前最有帮助的两个首要优先事项都与文档相关。人们希望获得更多文档以及在其领域内的更多示例。性能改进也被普遍提及为目前最有帮助的事情。

q = "Which would help you most right now?"
order = [
    "More documentation",
    "More examples in my field",
    "Performance improvements",
    "New features",
    "Bug fixes",
]
ax = sns.countplot(y=q, data=df2021[q].explode().to_frame(), order=order)
ax.set(ylabel="", title=q);

png

Dask 如何改进?

我们还为人们提供了一个自由文本回答的机会,回答问题“Dask 如何改进?”

Matt 之前写了一篇 早期趣闻博客文章,更详细地探讨了对此问题的回答。

他发现了以下反复出现的主题

  • 中级文档
  • 文档组织
  • 功能性
  • 高层次优化
  • 运行时稳定性和高级故障排除

由于更多文档和示例是两个最常被要求的改进,我将在此总结一下该领域的一些进展

  • 关于更多中级文档,Matt 说

    高级用户在性能和调试方面有很多很好的潜在材料,发布出来可能会很有趣。

  • Matt 指出 Dask 拥有出色的 参考文档,但缺乏大量好的 叙事文档。为了解决这个问题,Julia Signell 目前正在研究如何改进 Dask 文档的组织结构(如果您想关注该讨论,可以订阅 此议题线程

  • Matt 评论说,当存在如此多不同的 用户叙事 (即 Dask 被来自许多不同行业的人使用)时,很难有好的 叙事文档。今年,我们在调查中增加了一个新问题,询问人们工作的行业。我们之所以添加这个问题,是因为 “更多我领域内的示例” 在过去三年中一直是排名前两位的请求之一。现在我们可以利用这些信息更好地针对最需要叙事文档的领域(地球科学、生命科学和金融)进行优化。

q = 'What industry do you work in?'
data = df2021[df2021["Which would help you most right now?"] == "More examples in my field"]
order = data[q].value_counts()[data[q].value_counts() > 1].keys()
ax = sns.countplot(y=q, data=data[q].dropna().str.split(', ').explode().to_frame(), order=order);
ax.set(ylabel="", title="What field do you want more documentation examples for?");

png

您最关心哪些常见的功能请求?

对 numpy 和 pandas 的良好支持对大多数用户至关重要。用户也看重

  • 改进的扩展性
  • 易于部署
  • Dask 的弹性
  • 更好的 scikit-learn 和机器学习支持

大多数功能请求与往年的调查结果相似,尽管表示更好的 scikit-learn/ML 支持对他们至关重要的人数有所增加。我们还在 2021 年增加了一个关于 Dask 弹性方面的新问题。

在下图中,您可以看到人们在我们进行这项调查的三年中对每个功能请求重要性的评分。

common = (df[df.columns[df.columns.str.startswith("What common feature")]]
          .rename(columns=lambda x: x.lstrip("What common feature requests do you care about most?[").rstrip(r"]")))
a = common.loc[2019].apply(pd.value_counts).T.stack().reset_index().rename(columns={'level_0': 'Question', 'level_1': "Importance", 0: "count"}).assign(Year=2019)
b = common.loc[2020].apply(pd.value_counts).T.stack().reset_index().rename(columns={'level_0': 'Question', 'level_1': "Importance", 0: "count"}).assign(Year=2020)
c = common.loc[2021].apply(pd.value_counts).T.stack().reset_index().rename(columns={'level_0': 'Question', 'level_1': "Importance", 0: "count"}).assign(Year=2021)

counts = pd.concat([a, b, c], ignore_index=True)

d = common.stack().reset_index().rename(columns={"level_2": "Feature", 0: "Importance"})
order = ["Not relevant for me", "Somewhat useful", 'Critical to me']
sns.catplot(x='Importance', row="Feature", kind="count", col="Year", data=d, sharex=False, order=order);

png

往年调查结果

感谢所有参与调查的人!

如果您想详细了解 2021 年 Dask 调查,可在此处查阅关于 2021 年 Dask 调查早期趣闻的博客文章。

您可以在此处阅读往年的调查结果


博客评论由 Disqus 提供支持