{ "cells": [ { "cell_type": "markdown", "id": "76d8206a-83f1-41c1-8fa6-fd70ca444669", "metadata": {}, "source": [ "# 2021 Dask User Survey Results\n", "\n", "This post presents the results of the 2021 Dask User Survey, which ran earlier this year.\n", "Thanks to everyone who took the time to fill out the survey!\n", "These results help us better understand the Dask community and will guide future development efforts.\n", "\n", "The raw data, as well as the start of an analysis, can be found in this binder:\n", "\n", "[![2021 Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/dask/dask-examples/main?urlpath=%2Ftree%2Fsurveys%2F2021.ipynb)\n", "\n", "Let us know if you find anything in the data." ] }, { "cell_type": "markdown", "id": "380c49e1-3e15-468f-ae7a-60d7cadca070", "metadata": {}, "source": [ "## Contents\n", "\n", "- [Highlights](#highlights)\n", "- [Who are Dask users?](#who-are-dask-users)\n", "- [How people like to use Dask](#how-people-like-to-use-dask)\n", "- [Diagnostics](#diagnostics)\n", "- [Stability](#stability)\n", "- [User satisfaction, support, and documentation](#user-satisfaction)\n", "- [Suggestions for improvement](#suggestions-for-improvement)\n", "- [Previous survey results](#previous-survey-results)\n" ] }, { "cell_type": "markdown", "id": "d65a2a5c-f76b-4644-9bdc-acbea53deaf9", "metadata": {}, "source": [ "## Highlights \n", "\n", "We had 247 responses to the survey (roughly the same as last year, which had just under 240 responses). Overall, responses were similar to previous years.\n", "\n", "We asked 43 questions in the survey (an increase of 18 questions compared to the year before). We asked a bunch of new questions about the types of datasets people work with, the stability of Dask, and what kinds of industries people work in.\n", "\n", "Our community wants:\n", "\n", "- More documentation and examples\n", "- More intermediate level documentation\n", "- To improve the resiliency of Dask (i.e. do computations complete?)\n", "\n", "Users also value these features:\n", "\n", "- Improved scaling\n", "- Ease of deployment\n", "- Better scikit-learn & machine learning support" ] }, { "cell_type": "markdown", "id": "e7e15abb-5195-4825-b28e-8d63ba8321f8", "metadata": {}, "source": [ "### The typical Dask user\n", "\n", "The survey shows us there is a lot of diversity in our community, and there is no one way to use Dask. That said, our hypothetical \"typical\" Dask user:\n", "\n", "- Works with gigabyte sized datasets\n", "- Stored on a local filesystem\n", "- Has been using Dask between 1 and 3 years\n", "- Uses Dask occasionally, not every day\n", "- Uses Dask interactively at least part of the time\n", "- Uses a compute cluster (probably)\n", "- Likes to view the Dask dashboard with a web browser\n", "- For the most part, Dask is stable enough for their needs, but improving the Dask's resiliancy would be helpful\n", "- Uses the Dask dataframe, delayed, and maybe the Dask Array API, alongside numpy/pandas and other python libraries\n", "- The most useful thing that would help this person is more documentation, and more examples using Dask in their field.\n", "- They likely work in a scientific field (perhaps geoscience, life science, physics, or astronomy), or alternatively they might work in accounting, finance, insurance, or as a tech worker.\n", "\n", "You can read the survey results from previous years here: [2020 survey results](https://blog.dask.org/2020/09/22/user_survey), [2019 survey results](https://blog.dask.org/2019/08/05/user-survey)." ] }, { "cell_type": "code", "execution_count": null, "id": "a45f6f64-b1a7-467e-917d-eb1f0d29541b", "metadata": {}, "outputs": [], "source": [ "# Let's load in the survey data...\n", "%matplotlib inline\n", "\n", "from pprint import pprint\n", "import pandas as pd\n", "import seaborn as sns\n", "import matplotlib.pyplot as plt\n", "import textwrap\n", "import re\n", "\n", "\n", "df2019 = (\n", " pd.read_csv(\"data/2019-user-survey-results.csv.gz\", parse_dates=[\"Timestamp\"])\n", " .replace({\"How often do you use Dask?\": \"I use Dask all the time, even when I sleep\"}, \"Every day\")\n", ")\n", "\n", "df2020 = (\n", " pd.read_csv(\"data/2020-user-survey-results.csv.gz\")\n", " .assign(Timestamp=lambda df: pd.to_datetime(df['Timestamp'], format=\"%Y/%m/%d %H:%M:%S %p %Z\").astype('datetime64[ns]'))\n", " .replace({\"How often do you use Dask?\": \"I use Dask all the time, even when I sleep\"}, \"Every day\")\n", ")\n", "\n", "df2021 = (\n", " pd.read_csv(\"data/2021-user-survey-results.csv.gz\")\n", " .assign(Timestamp=lambda df: pd.to_datetime(df['Timestamp']).astype('datetime64[ns]'))\n", " .replace({\"How often do you use Dask?\": \"I use Dask all the time, even when I sleep\"}, \"Every day\")\n", ")\n", "\n", "common = df2019.columns.intersection(df2020.columns).intersection(df2021.columns)\n", "added = df2021.columns.difference(df2020.columns)\n", "dropped = df2020.columns.difference(df2021.columns)\n", "\n", "df = pd.concat([df2019, df2020, df2021])\n", "df['Year'] = df.Timestamp.dt.year\n", "df = df.set_index(['Year', 'Timestamp']).sort_index()" ] }, { "cell_type": "markdown", "id": "a24c470c-5f1a-489a-af11-176b071e8030", "metadata": {}, "source": [ "## Who are Dask users? " ] }, { "cell_type": "markdown", "id": "68d1923d-0907-4d3c-945e-dc69c5a1a18e", "metadata": {}, "source": [ "Most people said they use Dask occasionally, while a smaller group use Dask every day. There is a wide variety in how long people have used Dask for, with the most common response being between one and three years." ] }, { "cell_type": "code", "execution_count": null, "id": "feedb3bc-81a6-48f3-b178-440ffcdf5af0", "metadata": {}, "outputs": [], "source": [ "q = \"How often do you use Dask?\"\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(\";\").explode().to_frame());\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "code", "execution_count": null, "id": "bdf6c339-f5b6-4166-9276-5e96914db395", "metadata": {}, "outputs": [], "source": [ "q = \"How long have you used Dask?\" # New question in 2021\n", "order = [\"More than 3 years\", \"1 - 3 years\", \"3 months - 1 year\", \"Less than 3 months\", \"I've never used Dask\"]\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(\";\").explode().to_frame(), order=order);\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "1b158090-7827-4df6-8ae1-b6f488883b76", "metadata": {}, "source": [ "Just over half of respondants use Dask with other people (their team or organisation), and the other half use Dask on their own. " ] }, { "cell_type": "code", "execution_count": null, "id": "ab69c571-e7f6-4376-9a0e-04126d9c22cb", "metadata": {}, "outputs": [], "source": [ "q = \"Do you use Dask as part of a larger group?\"\n", "order = [\n", " 'I use Dask mostly on my own',\n", " 'My team or research group also use Dask',\n", " 'Beyond my group, many people throughout my institution use Dask',\n", "]\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(\";\").explode().to_frame(), order=order)\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "a4593c6a", "metadata": {}, "source": [ "In the last year, there has been an increase in the number of people who say that many people throughout their institution use Dask (32 people said this in 2021, compared to 19 in 2020). Between 2019 and 2020, there was a drop in the number of people who said their immediate team also uses Dask (121 people said this in 2019, compared to 94 in 2020). It's not clear why we saw either of these changes, so it will be interesting to see what happens in future years." ] }, { "cell_type": "code", "execution_count": null, "id": "afb24121", "metadata": {}, "outputs": [], "source": [ "q = 'Do you use Dask as part of a larger group?'\n", "ax = sns.countplot(y=q, hue=\"Year\", data=df.reset_index());\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "65654498-ff04-41b4-b1cb-5ae3a7308eaf", "metadata": {}, "source": [ "### What industry do you work in?\n", "\n", "There was a wide variety of industries represented in the survey.\n", "\n", "Almost half of responses were in an industry related to science, academia, or a governmant laboratory. Geoscicence had the most responses, while life sciences, physics, and astronomy were also popular fields.\n", "\n", "Around 30 percent of responses were from people in businesss and tech. Of these, there was a roughly even split between people in accounting/finance/insurance vs other tech workers.\n", "\n", "Around 10 percent of responses belonged to manufacturing, engineering, and other industry (energy, aerospace, etc). The remaining responses were difficult to categorise." ] }, { "cell_type": "code", "execution_count": null, "id": "508967cd-4ac8-4773-bd80-861422625586", "metadata": {}, "outputs": [], "source": [ "q = \"What industry do you work in?\" # New question in 2021\n", "data = df2021[q].dropna().str.split(\";\").explode().to_frame()\n", "order = data.value_counts()[data.value_counts() > 1].keys().get_level_values(0)\n", "ax = sns.countplot(y=q, data=data, order=order);\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "b74e6612-9eea-4d02-8323-22636c445e73", "metadata": {}, "source": [ "### How easy is it for you to upgrade to newer versions of Python libraries?\n", "\n", "The majority of users are able to easily upgrade to newer versoins of python libraries when they want." ] }, { "cell_type": "code", "execution_count": null, "id": "079e6d4c-a41e-480c-bd78-9d25e0ade2fb", "metadata": {}, "outputs": [], "source": [ "q = \"How easy is it for you to upgrade to newer versions of Python libraries\"\n", "sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame()).set_ylabel('Scale from 1 (Difficult) to 4 (Easy)');" ] }, { "cell_type": "markdown", "id": "0f26cc8f-7efa-4320-9f38-5e364416a51e", "metadata": {}, "source": [ "## How people like to use Dask " ] }, { "cell_type": "markdown", "id": "f8936f7a-f788-483f-a640-892deed37895", "metadata": {}, "source": [ "\n", "People like to use Dask in conjunction with numpy and pandas, along with a range of other python libraries.\n", "The most popular Dask APIs are [Dask Dataframes](https://docs.dask.org/en/latest/dataframe.html), [Dask Delayed](https://docs.dask.org/en/latest/delayed.html), and [Dask Arrays](https://docs.dask.org/en/latest/array.html).\n", "\n", "The vast majority of people like to use Dask interactively with Jupyter or IPython at least part of the time, and most people view the [Dask Dashboard](https://docs.dask.org/en/latest/diagnostics-distributed.html) with a web browser.\n" ] }, { "cell_type": "markdown", "id": "5bd6b0f8-5b46-4a61-b283-2fe3cac4453d", "metadata": {}, "source": [ "### What are some other libraries that you often use with Dask?\"\n", "\n", "The ten most common libraries people use with Dask are: `numpy`, `pandas`, `xarray`, `scikit-learn`, `scipy`, `statsmodels`, `matplotlib`, `xgboost`, `numba`, and `joblib`.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "91878b91-2fa0-404e-8e7f-9c089f20defc", "metadata": {}, "outputs": [], "source": [ "q = \"What are some other libraries that you often use with Dask?\"\n", "data = df2021[q].dropna().str.lower().str.split(\", \").explode().to_frame()\n", "labels = pd.value_counts(data[q]).iloc[:10].index\n", "sns.countplot(y=q, data=data, order=labels).set_ylabel('');" ] }, { "cell_type": "markdown", "id": "80679b24-b6ec-462c-9ac1-03f1d283ee72", "metadata": {}, "source": [ "## Dask APIs\n", "\n", "The three most popular Dask APIs people use are:\n", "1. [Dask Dataframes](https://docs.dask.org/en/latest/dataframe.html)\n", "2. [Dask Delayed](https://docs.dask.org/en/latest/delayed.html)\n", "3. [Dask Arrays](https://docs.dask.org/en/latest/array.html)\n", "\n", "In 2021, we saw a small increase in the number of people who use [dask delayed](https://docs.dask.org/en/latest/delayed.html), compared with previous years. This might be a good thing, it's possible that as people develop experience and confidence with Dask, they are more likely to start using more advanced features such as [delayed](https://docs.dask.org/en/latest/delayed.html). Besides this change, preferences were pretty simliar to the results from previous years." ] }, { "cell_type": "code", "execution_count": null, "id": "8c49e423-23a9-40cc-9e99-cc5d7bac36f7", "metadata": {}, "outputs": [], "source": [ "apis = df2021['Dask APIs'].str.split(\", \").explode()\n", "top = apis.value_counts().loc[lambda x: x > 10]\n", "apis = apis[apis.isin(top.index)].reset_index()\n", "\n", "sns.countplot(y=\"Dask APIs\", data=apis);" ] }, { "cell_type": "markdown", "id": "bc24feb8-aa37-44a5-b5ff-5440b1f84d1e", "metadata": {}, "source": [ "### Interactive or Batch?\n", "\n", "The vast majority of people like to use Dask interactively with Jupyter or IPython at least part of the time. Less than 15% of Dask users only use Dask in batch mode (submitting scripts that run in the future)." ] }, { "cell_type": "code", "execution_count": null, "id": "e7e0d37f-ac0d-4045-9012-ac79e86328ff", "metadata": {}, "outputs": [], "source": [ "q = 'Interactive or Batch?'\n", "data = df2021[q].dropna()\n", "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\")\n", "data = data.str.replace('Interactive: I use Dask with Jupyter or IPython when playing with data', \"Interactive\")\n", "data = data.str.replace('Batch: I submit scripts that run in the future', \"Batch\")\n", "order = [\"Interactive and Batch\", \"Interactive\", \"Batch\"]\n", "sns.countplot(y=q, data=data.explode().to_frame(), order=order).set_ylabel('');" ] }, { "cell_type": "markdown", "id": "beaafc3f-cd93-4087-8d4e-cf08305a3576", "metadata": {}, "source": [ "### How do you view Dask's dashboard?\n", "\n", "Most people look at the Dask dashboard using a web browser. A smaller group use the [dask jupyterlab extension](https://github.com/dask/dask-labextension).\n", "\n", "A few people are still not sure what the dashboard is all about. If that's you too, you might like to watch [this 20 minute video](https://youtu.be/N_GqzcuGLCY) that explains why the dashboard is super useful, or see the rest of the docs [here](https://docs.dask.org/en/latest/diagnostics-distributed.html)." ] }, { "cell_type": "code", "execution_count": null, "id": "4bbdccc2-2a75-419a-aed5-2199ddefcc29", "metadata": {}, "outputs": [], "source": [ "q = \"How do you view Dask's dashboard?\"\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(\", \").explode().to_frame());\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "4113e0cc-f26b-4b68-81d6-7e991347bce5", "metadata": {}, "source": [ "### Local machine or Cluster?\n", "\n", "Roughly two thirds of respondants use a computing cluster at least part of the time." ] }, { "cell_type": "code", "execution_count": null, "id": "69da5136-23bc-449a-b0b8-1937ae2c7e74", "metadata": {}, "outputs": [], "source": [ "q = 'Local machine or Cluster?'\n", "df[q].dropna().str.contains(\"Cluster\").astype(int).groupby(\"Year\").mean()" ] }, { "cell_type": "code", "execution_count": null, "id": "b7aeb59a-147d-495f-bf2e-318bbb2025d7", "metadata": {}, "outputs": [], "source": [ "q = 'Local machine or Cluster?'\n", "order = [\n", " 'Personal laptop',\n", " 'Large workstation',\n", " 'Cluster of 2-10 machines',\n", " 'Cluster with 10-100 machines',\n", " 'Cluster with 100+ machines'\n", "]\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(\", \").explode().to_frame(), order=order);\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "4e59c698-8438-496a-ad77-9a1be33d649c", "metadata": {}, "source": [ "#### If you use a cluster, how do you launch Dask?\n", "\n", "SSH is the most common way to launch Dask on a compute cluster, followed by a HPC resource manager, then Kubernetes." ] }, { "cell_type": "code", "execution_count": null, "id": "ee6c2ea8-2ef5-44c2-96e5-658d2de0927f", "metadata": {}, "outputs": [], "source": [ "q = \"If you use a cluster, how do you launch Dask? \"\n", "data = df2021[q].dropna()\n", "data = data.str.replace(\"HPC resource manager (SLURM, PBS, SGE, LSF or similar)\", \"HPC resource manager (SLURM PBS SGE LSF or similar)\", regex=False)\n", "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)\n", "data = data.str.split(\", \").explode().to_frame()\n", "order = data.value_counts()[data.value_counts() > 1].keys().get_level_values(0)\n", "ax = sns.countplot(y=q, data=data, order=order);\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "b4757457-e1e3-47de-a238-1788b54dbe1c", "metadata": {}, "source": [ "#### If you use a cluster, do you have a need for multiple worker types in the same cluster?\n", "\n", "Of the people who use compute clusters, a little less than half have a need for multiple worker types in the same cluster. Examples of this might include mixed workers with GPU vs no GPU, mixed workers with low or high memory allocations, etc." ] }, { "cell_type": "code", "execution_count": null, "id": "254dcecf-6100-4174-ae68-58e0274cb486", "metadata": {}, "outputs": [], "source": [ "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\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(\";\").explode().to_frame());\n", "ax.set(ylabel=\"\", title=\"Do you need multiple worker/machine types on a cluster?\");" ] }, { "cell_type": "markdown", "id": "31c12bba-39c7-49eb-aba6-836bcc07d6aa", "metadata": {}, "source": [ "### Datasets\n", "\n", "#### How large are your datasets typically?\n", "\n", "Dask users most commonly work with gigabyte sized datasets. Very few users work with petabyte sized datasets." ] }, { "cell_type": "code", "execution_count": null, "id": "e14743e9-9636-4ccd-a8f6-85575d6aa2f5", "metadata": {}, "outputs": [], "source": [ "q = \"How large are your datasets typically?\" # New question in 2021\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(\", \").explode().to_frame());\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "fc99643e-f7fc-4a86-a325-4bca5cc3a464", "metadata": {}, "source": [ "#### Where are your datasets typically stored?\n", "\n", "Most people store their data on a local filesystem." ] }, { "cell_type": "code", "execution_count": null, "id": "cf7c38be-0f9b-4f0b-83a7-3a46981149fb", "metadata": {}, "outputs": [], "source": [ "q = \"Where are your datasets typically stored?\" # New question in 2021\n", "data = df2021[q].dropna().str.split(\", \").explode().to_frame()\n", "order = data.value_counts()[data.value_counts() > 1].keys().get_level_values(0)\n", "ax = sns.countplot(y=q, data=data, order=order);\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "1dbf9da0-3eef-4e8f-8319-fb37fcd62583", "metadata": {}, "source": [ "#### What file formats do you typically work with?\n", "\n", "The two most common file formats (`csv` and `parquet`) are popular among Dask Dataframe users. The `JSON` file format is also very commonly used with Dask. The fourth and fifth most common filetypes (`HDF5` and `zarr`) are popular among Dask Array users. This fits with what we know about the Dask Dataframe API being the most popular, with Dask Arrays close behind." ] }, { "cell_type": "code", "execution_count": null, "id": "d1c7ccd5-c191-4ebe-9bb6-099a31fe30c4", "metadata": {}, "outputs": [], "source": [ "q = \"What file formats do you typically work with?\" # New question in 2021\n", "data = df2021[q].dropna().str.split(\", \").explode().to_frame()\n", "order = data.value_counts()[data.value_counts() > 1].keys().get_level_values(0)\n", "ax = sns.countplot(y=q, data=data, order=order);\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "cdcd7f32-6a64-4c04-9293-c97844a1ff4a", "metadata": {}, "source": [ "This survey question had a long tail: a very wide variety of specialized file formats were reported, most only being used by one or two individuals who replied to the survey.\n", "\n", "A lot of these specialized file formats store image data, specific to particular fields (astronomy, geoscience, microscopy, etc.)." ] }, { "cell_type": "code", "execution_count": null, "id": "facb7865-c1da-44b8-830f-dead75027c8b", "metadata": {}, "outputs": [], "source": [ "list(data.value_counts()[data.value_counts() == 1].keys().get_level_values(0))" ] }, { "cell_type": "markdown", "id": "9e22bae2-c0bd-49ea-9fa3-42842e98e1d8", "metadata": {}, "source": [ "\"XKCD \n", "\n", "XKCD comic \"Standards\" https://xkcd.com/927/" ] }, { "cell_type": "markdown", "id": "f448af9c-ea64-4bfa-a918-8dfab3a01f50", "metadata": {}, "source": [ "### Preferred Cloud?\n", "\n", "The most popular cloud solution is Amazon Web Services (AWS), followed by Google Cloud Platform (GCP) and Microsoft Azure. " ] }, { "cell_type": "code", "execution_count": null, "id": "afd29942-516e-4ec9-89e1-977b1e862e8a", "metadata": {}, "outputs": [], "source": [ "q = \"Preferred Cloud?\"\n", "order = [\n", " \"Amazon Web Services (AWS)\",\n", " \"Google Cloud Platform (GCP)\",\n", " \"Microsoft Azure\",\n", " \"Digital Ocean\", \n", "]\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(\", \").explode().to_frame(), order=order);\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "40407f57-01a6-4a22-888a-8daa49182bcd", "metadata": {}, "source": [ "### Do you use Dask projects to deploy?\n", "\n", "Among those who use dask projects to deploy, [dask-jobqueue](https://github.com/dask/dask-jobqueue)\n", "and [dask helm chart](https://github.com/dask/helm-chart) are the two most popular options.\n", "There was a wide variety of projects people used for deployment.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ead01452-e559-46aa-804b-9e3fd04e28bd", "metadata": {}, "outputs": [], "source": [ "q = \"Do you use Dask projects to deploy?\"\n", "order = [\n", " \"dask-jobqueue\",\n", " \"dask's helm chart\",\n", " \"dask-kubernetes\",\n", " \"dask's docker image at daskdev/dask\",\n", " \"dask-gateway\",\n", " \"dask-ssh\",\n", " \"dask-cloudprovider\",\n", " \"dask-yarn\",\n", " \"qhub\",\n", " \"dask-mpi\",\n", "]\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().str.lower().str.split(\", \").explode().to_frame(), order=order);\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "da08aacf-260f-46d4-8004-dd8a1ecce9d0", "metadata": {}, "source": [ "## Diagnostics \n", "\n", "We saw earlier that most people like to view the Dask Dashboard using their web browser.\n", "\n", "In the dashboard, people said the most useful diagnostics plots were:\n", "\n", "1. The task stream plot\n", "2. The progress plot, and\n", "3. The memory useage per worker plot\n" ] }, { "cell_type": "code", "execution_count": null, "id": "b4f82846-03d0-4f91-bf75-6e443a10dd44", "metadata": {}, "outputs": [], "source": [ "q = \"Which Diagnostic plots are most useful?\" # New question in 2021\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().str.split(', ').explode().to_frame());\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "4559feb5-33dd-4f35-882c-9c8b92a3b466", "metadata": {}, "source": [ "We also asked some new questions about diagnostics in 2021.\n", "\n", "We found that most people (65 percent) do not use [Dask performance reports](https://distributed.dask.org/en/latest/diagnosing-performance.html#performance-reports), which is a way to save the diagnostic dashboard to static HTML plots for later review." ] }, { "cell_type": "code", "execution_count": null, "id": "f2e741b8-c1f4-4f3c-9006-c49ebb3bd52c", "metadata": {}, "outputs": [], "source": [ "q = \"Do you use Dask's Performance reports?\" # New question in 2021\n", "ax = sns.countplot(y=q, data=df2021[q].explode().to_frame(), order=[\"Yes\", \"No\"]);\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "a9e43043-5032-44ea-a434-886a9d122354", "metadata": {}, "source": [ "Very few people use Dask's [Prometheus metrics](https://docs.dask.org/en/latest/setup/prometheus.html). Jacob Tomlinson has an excellent article on [Monitoring Dask + RAPIDS with Prometheus + Grafana](https://medium.com/rapids-ai/monitoring-dask-rapids-with-prometheus-grafana-96eaf6b8f3a0), if you're interested in learning more about how to use this feature." ] }, { "cell_type": "code", "execution_count": null, "id": "cce4bd07-456f-4d70-ac83-30455c43f865", "metadata": {}, "outputs": [], "source": [ "q = \"Do you use Dask's Prometheus Metrics?\" # New question in 2021\n", "ax = sns.countplot(y=q, data=df2021[q].explode().to_frame(), order=[\"Yes\", \"No\"]);\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "d10f4c88-55d7-4b14-95c7-64220bcd18b9", "metadata": {}, "source": [ "## Stability \n", "\n", "We asked a number of questions around the stability of Dask, many of them new questions in 2021.\n", "\n", "The majority of people said Dask was resiliant enough for them (eg: computations complete).\n", "However this is an area we could improve in, as 36 percent of people are not satisfied.\n", "This was a new question 2021, so we can't say how people opinion of Dask's resiliancy has changed over time.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "c4bcefbe-694c-4efb-8016-eb9c84ae33c9", "metadata": {}, "outputs": [], "source": [ "q = \"Is Dask resilient enough for you? (e.g. computations complete).\" # new question in 2021\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame(), order=[\"Yes\", \"No\"]);\n", "ax.set(ylabel=\"\", title=\"Is Dask resilient enough for you?\");" ] }, { "cell_type": "markdown", "id": "3609dd15-c9d7-4e7f-ae8d-8f69205d6d82", "metadata": {}, "source": [ "Most people say Dask in general is stable enough for them (eg: between different version releases). This is similar to the survey results from previous years." ] }, { "cell_type": "code", "execution_count": null, "id": "2521b81e-b3bb-499d-a2f6-f17a40f45c86", "metadata": {}, "outputs": [], "source": [ "q = \"Is Dask stable enough for you?\"\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame(), order=[\"Yes\", \"No\"]);\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "1043d415-065e-42b7-be9e-cd11fc6dc7de", "metadata": {}, "source": [ "People also say that the API of Dask is stable enough for them too." ] }, { "cell_type": "code", "execution_count": null, "id": "481266a1-ecdd-42f2-b6b8-c8a5c1d6dcdd", "metadata": {}, "outputs": [], "source": [ "q = \"Is Dask's API stable enough for you?\"\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame(), order=[\"Yes\", \"No\"]);\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "ab1eec67-48e5-44cb-a423-cdf8f8d9c3e0", "metadata": {}, "source": [ "The vast majority of people are satisfied with the current release frequency (roughly once every two weeks)." ] }, { "cell_type": "code", "execution_count": null, "id": "a1a97e9d-ad6a-4c01-8a92-b320587482c0", "metadata": {}, "outputs": [], "source": [ "q = \"How is Dask's release frequency?\" # New question in 2021\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame());\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "20514ffd-88cc-4b0b-921f-e83484010e31", "metadata": {}, "source": [ "Most people say they would pin their code to a long term support release, if one was available for Dask." ] }, { "cell_type": "code", "execution_count": null, "id": "076d6737-c6e3-42f6-b5cc-fac45a461675", "metadata": {}, "outputs": [], "source": [ "q = \"If Dask had Long-term support (LTS) releases, would you pin your code to use them?\" # New question in 2021\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame(), order=[\"Yes\", \"No\"]);\n", "ax.set(ylabel=\"\", title=\"Would you pin to a long term support release?\");" ] }, { "cell_type": "markdown", "id": "0053422e-0f23-4662-a2ae-4d102c0c17f0", "metadata": {}, "source": [ "## User satisfaction, support, and documentation \n", "\n", "We asked a bunch of new questions about user satisfaction in the 2021 survey." ] }, { "cell_type": "markdown", "id": "24e2d6fc-84a3-4295-958f-f08d619d2a0c", "metadata": {}, "source": [ "### How easy is Dask to use?\n", "\n", "The majority of people say that Dask is moderately easy to use, the same as in previous surveys." ] }, { "cell_type": "code", "execution_count": null, "id": "d461469e-4262-441a-9a7c-7566afa88fff", "metadata": {}, "outputs": [], "source": [ "q = \"On a scale of 1 - 5 (1 being hardest, 5 being easiest) how easy is Dask to use?\"\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame());\n", "ax.set(ylabel=\"1 = Difficult, 5 = Easy\", title=\"How easy is Dask to use?\");" ] }, { "cell_type": "markdown", "id": "227a7864-9f89-4ec9-8cc3-38ee8c2fb268", "metadata": {}, "source": [ "### How is Dask's documentation?\n", "\n", "Most people think that Dask's documentation is pretty good." ] }, { "cell_type": "code", "execution_count": null, "id": "85699dad-f6fd-40df-ab32-2753acd8aafd", "metadata": {}, "outputs": [], "source": [ "q = \"How is Dask's documentation?\" # New question in 2021\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame());\n", "ax.set(ylabel=\"1 = Not good, 5 = Great\", title=q);" ] }, { "cell_type": "markdown", "id": "e3e3559f-4222-45b8-9d33-12a44a121343", "metadata": {}, "source": [ "### How satisfied are you with maintainer responsiveness on GitHub?\n", "\n", "Almost everybody who responded feels positively about Dask's maintainer responsiveness on GitHub .\n" ] }, { "cell_type": "code", "execution_count": null, "id": "4b1e4373-cc44-4494-8611-0937469c55c8", "metadata": {}, "outputs": [], "source": [ "q = \"How satisfied are you with maintainer responsiveness on GitHub?\" # New question in 2021\n", "ax = sns.countplot(y=q, data=df2021[q].dropna().explode().to_frame());\n", "ax.set(ylabel=\"1 = Not satisfied, 5 = Thrilled\", title=q);" ] }, { "cell_type": "markdown", "id": "842c2163-db17-4d42-8ad8-b09df3952542", "metadata": {}, "source": [ "### What Dask resources have you used for support in the last six months?\n", "\n", "The documentation at [dask.org](https://dask.org/) is the first place most users look for help.\n", "\n", "The breakdown of responses to this question in 2021 was very similar to previous years, with the exception that no-one seemed to know that the [Dask YouTube channel](https://www.youtube.com/c/Dask-dev/videos) or Gitter chat existed in 2019." ] }, { "cell_type": "code", "execution_count": null, "id": "2191162b-ecce-4239-ae8e-6f7e8bf2c1be", "metadata": {}, "outputs": [], "source": [ "q = 'What Dask resources have you used for support in the last six months?'\n", "\n", "resource_map = {\n", " \"Tutorial\": \"Tutorial at tutorial.dask.org\",\n", " \"YouTube\": \"YouTube channel\",\n", " \"gitter\": \"Gitter chat\"\n", "}\n", "\n", "df[q] = df[q].str.replace(';',', ') # Make separator values consistent\n", "d = df[q].str.split(', ').explode().replace(resource_map)\n", "top = d.value_counts()[:8].index\n", "d = d[d.isin(top)]\n", "\n", "fig, ax = plt.subplots(figsize=(8, 8))\n", "ax = sns.countplot(y=q, hue=\"Year\", data=d.reset_index(), ax=ax);\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "94d96e9b-f927-40ec-9bf1-8de704da74f6", "metadata": {}, "source": [ "## Suggestions for improvement " ] }, { "cell_type": "markdown", "id": "1a65e94b-6ead-4ffa-bf1c-ba45c377d924", "metadata": {}, "source": [ "### Which would help you most right now?\n", "\n", "The two top priorities people said would help most right now are both related to documentation. People want more documentation, and more examples in their field. Performance improvements were also commonly mentioned as something that would help the most right now." ] }, { "cell_type": "code", "execution_count": null, "id": "034fac9f-e810-49bf-aa80-ff91c7876e9b", "metadata": {}, "outputs": [], "source": [ "q = \"Which would help you most right now?\"\n", "order = [\n", " \"More documentation\",\n", " \"More examples in my field\",\n", " \"Performance improvements\",\n", " \"New features\",\n", " \"Bug fixes\",\n", "] \n", "ax = sns.countplot(y=q, data=df2021[q].explode().to_frame(), order=order)\n", "ax.set(ylabel=\"\", title=q);" ] }, { "cell_type": "markdown", "id": "16d42bfb-fd54-43ca-b162-e9e37e4a5dee", "metadata": {}, "source": [ "### How can Dask improve?\n", "\n", "We also gave people the opportunity for a free text response to the question \"How can Dask imporove?\"\n", "\n", "Matt has previously written an [early anecdotes blogpost](https://blog.dask.org/2021/06/18/early-survey)\n", "that dives into the responses to this question in more detail.\n", "\n", "He found these recurring themes:\n", "\n", "- Intermediate Documentation\n", "- Documentation Organization\n", "- Functionality\n", "- High Level Optimization\n", "- Runtime Stability and Advanced Troubleshooting\n", "\n", "Since more documentation and examples were the two most requested improvements, I'll summarize some of the steps forward in that area here:\n", "\n", "- Regarding more intermediate documentation, Matt says:\n", " > There is a lot of good potential material that advanced users have around performance and debugging that could be fun to publish.\n", "\n", "- Matt points out that Dask has excellent *reference documentation*, but lacks a lot of good *narrative documentation*. To address this, Julia Signell is currently investigating how we could improve the organization of Dask's documentation (you can subscribe to [this issue thread](https://github.com/dask/community/issues/170) if you want to follow that discussion)\n", "\n", "- Matt comments that it's hard to have good *narrative documentation* when there are so many different *user narratives* (i.e. Dask is used by people from many different industries). This year, we added a new question to the survey asking for the industry people work in. We added this because *\"More examples in my field\"* has been one of the top two requests for the last three years. Now we can use that information to better target narrative documentation to the areas that need it most (geoscience, life science, and finance)." ] }, { "cell_type": "code", "execution_count": null, "id": "0d3d8960-64b7-474d-859d-41e64317439b", "metadata": {}, "outputs": [], "source": [ "q = 'What industry do you work in?'\n", "data = df2021[df2021[\"Which would help you most right now?\"] == \"More examples in my field\"]\n", "order = data[q].value_counts()[data[q].value_counts() > 1].keys()\n", "ax = sns.countplot(y=q, data=data[q].dropna().str.split(', ').explode().to_frame(), order=order);\n", "ax.set(ylabel=\"\", title=\"What field do you want more documentation examples for?\");" ] }, { "cell_type": "markdown", "id": "3d377cfb-2127-4f9d-87a8-b99f2794c64b", "metadata": {}, "source": [ "### What common feature requests do you care about most?\n", "\n", "Good support for numpy and pandas is critical for most users.\n", "Users also value:\n", "\n", "- Improved scaling\n", "- Ease of deployment\n", "- Resiliancy of Dask\n", "- Better scikit-learn & machine learning support\n", "\n", "Most feature requests are similar to the survey results from previous years, although there was an increase in the number of people who say better scikit-learn/ML support is critical to them. We also added a new question about Dask's resiliancy in 2021.\n", "\n", "In the figure below you can see how people rated the importance of each feature request, for each of the three years we've run this survey." ] }, { "cell_type": "code", "execution_count": null, "id": "f32b754c-fbf1-4f8d-877e-8fe9f94e53dc", "metadata": {}, "outputs": [], "source": [ "common = (df[df.columns[df.columns.str.startswith(\"What common feature\")]]\n", " .rename(columns=lambda x: x.lstrip(\"What common feature requests do you care about most?[\").rstrip(r\"]\")))\n", "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)\n", "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)\n", "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)\n", "\n", "counts = pd.concat([a, b, c], ignore_index=True)\n", "\n", "d = common.stack().reset_index().rename(columns={\"level_2\": \"Feature\", 0: \"Importance\"})\n", "order = [\"Not relevant for me\", \"Somewhat useful\", 'Critical to me']\n", "sns.catplot(x='Importance', row=\"Feature\", kind=\"count\", col=\"Year\", data=d, sharex=False, order=order);" ] }, { "cell_type": "markdown", "id": "139409e8-7938-44dc-bf4e-6629605bb466", "metadata": {}, "source": [ "## Previous survey results \n", "\n", "Thanks to everyone who took the survey!\n", "\n", "If you want to read more about the 2021 Dask survey, the blogpost on early anecdotes from the Dask 2021 survey [is available here](https://blog.dask.org/2021/06/18/early-survey).\n", "\n", "You can read the survey results from previous years here: \n", "\n", "- [2020 survey results](https://blog.dask.org/2020/09/22/user_survey)\n", "- [2019 survey results](https://blog.dask.org/2019/08/05/user-survey).\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.12" } }, "nbformat": 4, "nbformat_minor": 5 }