Created
June 14, 2025 12:25
-
-
Save dsj976/9022fda0d479bf0e03c3d79e121edf2b to your computer and use it in GitHub Desktop.
SVD on the ERA5 dataset using Dask
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "id": "117b95de", | |
| "metadata": {}, | |
| "source": [ | |
| "# Singular Value Decomposition (SVD) using Dask\n", | |
| "\n", | |
| "This notebook applies the SVD to a slice of the ERA5 dataset using different algorithms implemented in Dask." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "id": "4c553a53", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "import dask.array as da\n", | |
| "from dask.distributed import Client, progress\n", | |
| "from dask_ml.decomposition import TruncatedSVD\n", | |
| "import matplotlib.pyplot as plt\n", | |
| "import numpy as np\n", | |
| "import xarray as xr" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "432615d9", | |
| "metadata": {}, | |
| "source": [ | |
| "Start a local distributed cluster with workers on the same process." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 4, | |
| "id": "74f4b7ae", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "client = Client(processes=False)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 3, | |
| "id": "fcdfbe52", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| " <div style=\"width: 24px; height: 24px; background-color: #e1e1e1; border: 3px solid #9D9D9D; border-radius: 5px; position: absolute;\"> </div>\n", | |
| " <div style=\"margin-left: 48px;\">\n", | |
| " <h3 style=\"margin-bottom: 0px;\">Client</h3>\n", | |
| " <p style=\"color: #9D9D9D; margin-bottom: 0px;\">Client-83e8bad0-4913-11f0-9d09-fad6f7f922f6</p>\n", | |
| " <table style=\"width: 100%; text-align: left;\">\n", | |
| "\n", | |
| " <tr>\n", | |
| " \n", | |
| " <td style=\"text-align: left;\"><strong>Connection method:</strong> Cluster object</td>\n", | |
| " <td style=\"text-align: left;\"><strong>Cluster type:</strong> distributed.LocalCluster</td>\n", | |
| " \n", | |
| " </tr>\n", | |
| "\n", | |
| " \n", | |
| " <tr>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Dashboard: </strong> <a href=\"http://10.0.100.90:8787/status\" target=\"_blank\">http://10.0.100.90:8787/status</a>\n", | |
| " </td>\n", | |
| " <td style=\"text-align: left;\"></td>\n", | |
| " </tr>\n", | |
| " \n", | |
| "\n", | |
| " </table>\n", | |
| "\n", | |
| " \n", | |
| "\n", | |
| " \n", | |
| " <details>\n", | |
| " <summary style=\"margin-bottom: 20px;\"><h3 style=\"display: inline;\">Cluster Info</h3></summary>\n", | |
| " <div class=\"jp-RenderedHTMLCommon jp-RenderedHTML jp-mod-trusted jp-OutputArea-output\">\n", | |
| " <div style=\"width: 24px; height: 24px; background-color: #e1e1e1; border: 3px solid #9D9D9D; border-radius: 5px; position: absolute;\">\n", | |
| " </div>\n", | |
| " <div style=\"margin-left: 48px;\">\n", | |
| " <h3 style=\"margin-bottom: 0px; margin-top: 0px;\">LocalCluster</h3>\n", | |
| " <p style=\"color: #9D9D9D; margin-bottom: 0px;\">5991a027</p>\n", | |
| " <table style=\"width: 100%; text-align: left;\">\n", | |
| " <tr>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Dashboard:</strong> <a href=\"http://10.0.100.90:8787/status\" target=\"_blank\">http://10.0.100.90:8787/status</a>\n", | |
| " </td>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Workers:</strong> 1\n", | |
| " </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Total threads:</strong> 10\n", | |
| " </td>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Total memory:</strong> 32.00 GiB\n", | |
| " </td>\n", | |
| " </tr>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <td style=\"text-align: left;\"><strong>Status:</strong> running</td>\n", | |
| " <td style=\"text-align: left;\"><strong>Using processes:</strong> False</td>\n", | |
| "</tr>\n", | |
| "\n", | |
| " \n", | |
| " </table>\n", | |
| "\n", | |
| " <details>\n", | |
| " <summary style=\"margin-bottom: 20px;\">\n", | |
| " <h3 style=\"display: inline;\">Scheduler Info</h3>\n", | |
| " </summary>\n", | |
| "\n", | |
| " <div style=\"\">\n", | |
| " <div>\n", | |
| " <div style=\"width: 24px; height: 24px; background-color: #FFF7E5; border: 3px solid #FF6132; border-radius: 5px; position: absolute;\"> </div>\n", | |
| " <div style=\"margin-left: 48px;\">\n", | |
| " <h3 style=\"margin-bottom: 0px;\">Scheduler</h3>\n", | |
| " <p style=\"color: #9D9D9D; margin-bottom: 0px;\">Scheduler-4a12e5c2-cc94-4da3-9580-4fa78579ed6c</p>\n", | |
| " <table style=\"width: 100%; text-align: left;\">\n", | |
| " <tr>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Comm:</strong> inproc://10.0.100.90/7433/1\n", | |
| " </td>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Workers:</strong> 0 \n", | |
| " </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Dashboard:</strong> <a href=\"http://10.0.100.90:8787/status\" target=\"_blank\">http://10.0.100.90:8787/status</a>\n", | |
| " </td>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Total threads:</strong> 0\n", | |
| " </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Started:</strong> Just now\n", | |
| " </td>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Total memory:</strong> 0 B\n", | |
| " </td>\n", | |
| " </tr>\n", | |
| " </table>\n", | |
| " </div>\n", | |
| " </div>\n", | |
| "\n", | |
| " <details style=\"margin-left: 48px;\">\n", | |
| " <summary style=\"margin-bottom: 20px;\">\n", | |
| " <h3 style=\"display: inline;\">Workers</h3>\n", | |
| " </summary>\n", | |
| "\n", | |
| " \n", | |
| " <div style=\"margin-bottom: 20px;\">\n", | |
| " <div style=\"width: 24px; height: 24px; background-color: #DBF5FF; border: 3px solid #4CC9FF; border-radius: 5px; position: absolute;\"> </div>\n", | |
| " <div style=\"margin-left: 48px;\">\n", | |
| " <details>\n", | |
| " <summary>\n", | |
| " <h4 style=\"margin-bottom: 0px; display: inline;\">Worker: 0</h4>\n", | |
| " </summary>\n", | |
| " <table style=\"width: 100%; text-align: left;\">\n", | |
| " <tr>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Comm: </strong> inproc://10.0.100.90/7433/4\n", | |
| " </td>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Total threads: </strong> 10\n", | |
| " </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Dashboard: </strong> <a href=\"http://10.0.100.90:60161/status\" target=\"_blank\">http://10.0.100.90:60161/status</a>\n", | |
| " </td>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Memory: </strong> 32.00 GiB\n", | |
| " </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <td style=\"text-align: left;\">\n", | |
| " <strong>Nanny: </strong> None\n", | |
| " </td>\n", | |
| " <td style=\"text-align: left;\"></td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <td colspan=\"2\" style=\"text-align: left;\">\n", | |
| " <strong>Local directory: </strong> /var/folders/3p/bn7y7hcd6s7_28j4tq3cv2hr0000gs/T/dask-scratch-space/worker-334nu93l\n", | |
| " </td>\n", | |
| " </tr>\n", | |
| "\n", | |
| " \n", | |
| "\n", | |
| " \n", | |
| "\n", | |
| " </table>\n", | |
| " </details>\n", | |
| " </div>\n", | |
| " </div>\n", | |
| " \n", | |
| "\n", | |
| " </details>\n", | |
| "</div>\n", | |
| "\n", | |
| " </details>\n", | |
| " </div>\n", | |
| "</div>\n", | |
| " </details>\n", | |
| " \n", | |
| "\n", | |
| " </div>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| "<Client: 'inproc://10.0.100.90/7433/1' processes=1 threads=10, memory=32.00 GiB>" | |
| ] | |
| }, | |
| "execution_count": 3, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "client # dashboard at http://localhost:8787" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "0ee14bf3", | |
| "metadata": {}, | |
| "source": [ | |
| "Open the Zarr store with Xarray with Dask support." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 4, | |
| "id": "0e3b018c", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n", | |
| "<defs>\n", | |
| "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n", | |
| "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n", | |
| "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n", | |
| "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n", | |
| "</symbol>\n", | |
| "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n", | |
| "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n", | |
| "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n", | |
| "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n", | |
| "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n", | |
| "</symbol>\n", | |
| "</defs>\n", | |
| "</svg>\n", | |
| "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n", | |
| " *\n", | |
| " */\n", | |
| "\n", | |
| ":root {\n", | |
| " --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n", | |
| " --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n", | |
| " --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n", | |
| " --xr-border-color: var(--jp-border-color2, #e0e0e0);\n", | |
| " --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n", | |
| " --xr-background-color: var(--jp-layout-color0, white);\n", | |
| " --xr-background-color-row-even: var(--jp-layout-color1, white);\n", | |
| " --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n", | |
| "}\n", | |
| "\n", | |
| "html[theme=\"dark\"],\n", | |
| "html[data-theme=\"dark\"],\n", | |
| "body[data-theme=\"dark\"],\n", | |
| "body.vscode-dark {\n", | |
| " --xr-font-color0: rgba(255, 255, 255, 1);\n", | |
| " --xr-font-color2: rgba(255, 255, 255, 0.54);\n", | |
| " --xr-font-color3: rgba(255, 255, 255, 0.38);\n", | |
| " --xr-border-color: #1f1f1f;\n", | |
| " --xr-disabled-color: #515151;\n", | |
| " --xr-background-color: #111111;\n", | |
| " --xr-background-color-row-even: #111111;\n", | |
| " --xr-background-color-row-odd: #313131;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-wrap {\n", | |
| " display: block !important;\n", | |
| " min-width: 300px;\n", | |
| " max-width: 700px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-text-repr-fallback {\n", | |
| " /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n", | |
| " display: none;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-header {\n", | |
| " padding-top: 6px;\n", | |
| " padding-bottom: 6px;\n", | |
| " margin-bottom: 4px;\n", | |
| " border-bottom: solid 1px var(--xr-border-color);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-header > div,\n", | |
| ".xr-header > ul {\n", | |
| " display: inline;\n", | |
| " margin-top: 0;\n", | |
| " margin-bottom: 0;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-obj-type,\n", | |
| ".xr-array-name {\n", | |
| " margin-left: 2px;\n", | |
| " margin-right: 10px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-obj-type {\n", | |
| " color: var(--xr-font-color2);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-sections {\n", | |
| " padding-left: 0 !important;\n", | |
| " display: grid;\n", | |
| " grid-template-columns: 150px auto auto 1fr 0 20px 0 20px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-item {\n", | |
| " display: contents;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-item input {\n", | |
| " display: inline-block;\n", | |
| " opacity: 0;\n", | |
| " height: 0;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-item input + label {\n", | |
| " color: var(--xr-disabled-color);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-item input:enabled + label {\n", | |
| " cursor: pointer;\n", | |
| " color: var(--xr-font-color2);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-item input:focus + label {\n", | |
| " border: 2px solid var(--xr-font-color0);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-item input:enabled + label:hover {\n", | |
| " color: var(--xr-font-color0);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary {\n", | |
| " grid-column: 1;\n", | |
| " color: var(--xr-font-color2);\n", | |
| " font-weight: 500;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary > span {\n", | |
| " display: inline-block;\n", | |
| " padding-left: 0.5em;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary-in:disabled + label {\n", | |
| " color: var(--xr-font-color2);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary-in + label:before {\n", | |
| " display: inline-block;\n", | |
| " content: \"►\";\n", | |
| " font-size: 11px;\n", | |
| " width: 15px;\n", | |
| " text-align: center;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary-in:disabled + label:before {\n", | |
| " color: var(--xr-disabled-color);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary-in:checked + label:before {\n", | |
| " content: \"▼\";\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary-in:checked + label > span {\n", | |
| " display: none;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary,\n", | |
| ".xr-section-inline-details {\n", | |
| " padding-top: 4px;\n", | |
| " padding-bottom: 4px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-inline-details {\n", | |
| " grid-column: 2 / -1;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-details {\n", | |
| " display: none;\n", | |
| " grid-column: 1 / -1;\n", | |
| " margin-bottom: 5px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary-in:checked ~ .xr-section-details {\n", | |
| " display: contents;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-array-wrap {\n", | |
| " grid-column: 1 / -1;\n", | |
| " display: grid;\n", | |
| " grid-template-columns: 20px auto;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-array-wrap > label {\n", | |
| " grid-column: 1;\n", | |
| " vertical-align: top;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-preview {\n", | |
| " color: var(--xr-font-color3);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-array-preview,\n", | |
| ".xr-array-data {\n", | |
| " padding: 0 5px !important;\n", | |
| " grid-column: 2;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-array-data,\n", | |
| ".xr-array-in:checked ~ .xr-array-preview {\n", | |
| " display: none;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-array-in:checked ~ .xr-array-data,\n", | |
| ".xr-array-preview {\n", | |
| " display: inline-block;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-dim-list {\n", | |
| " display: inline-block !important;\n", | |
| " list-style: none;\n", | |
| " padding: 0 !important;\n", | |
| " margin: 0;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-dim-list li {\n", | |
| " display: inline-block;\n", | |
| " padding: 0;\n", | |
| " margin: 0;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-dim-list:before {\n", | |
| " content: \"(\";\n", | |
| "}\n", | |
| "\n", | |
| ".xr-dim-list:after {\n", | |
| " content: \")\";\n", | |
| "}\n", | |
| "\n", | |
| ".xr-dim-list li:not(:last-child):after {\n", | |
| " content: \",\";\n", | |
| " padding-right: 5px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-has-index {\n", | |
| " font-weight: bold;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-list,\n", | |
| ".xr-var-item {\n", | |
| " display: contents;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-item > div,\n", | |
| ".xr-var-item label,\n", | |
| ".xr-var-item > .xr-var-name span {\n", | |
| " background-color: var(--xr-background-color-row-even);\n", | |
| " margin-bottom: 0;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-item > .xr-var-name:hover span {\n", | |
| " padding-right: 5px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-list > li:nth-child(odd) > div,\n", | |
| ".xr-var-list > li:nth-child(odd) > label,\n", | |
| ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n", | |
| " background-color: var(--xr-background-color-row-odd);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-name {\n", | |
| " grid-column: 1;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-dims {\n", | |
| " grid-column: 2;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-dtype {\n", | |
| " grid-column: 3;\n", | |
| " text-align: right;\n", | |
| " color: var(--xr-font-color2);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-preview {\n", | |
| " grid-column: 4;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-index-preview {\n", | |
| " grid-column: 2 / 5;\n", | |
| " color: var(--xr-font-color2);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-name,\n", | |
| ".xr-var-dims,\n", | |
| ".xr-var-dtype,\n", | |
| ".xr-preview,\n", | |
| ".xr-attrs dt {\n", | |
| " white-space: nowrap;\n", | |
| " overflow: hidden;\n", | |
| " text-overflow: ellipsis;\n", | |
| " padding-right: 10px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-name:hover,\n", | |
| ".xr-var-dims:hover,\n", | |
| ".xr-var-dtype:hover,\n", | |
| ".xr-attrs dt:hover {\n", | |
| " overflow: visible;\n", | |
| " width: auto;\n", | |
| " z-index: 1;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-attrs,\n", | |
| ".xr-var-data,\n", | |
| ".xr-index-data {\n", | |
| " display: none;\n", | |
| " background-color: var(--xr-background-color) !important;\n", | |
| " padding-bottom: 5px !important;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n", | |
| ".xr-var-data-in:checked ~ .xr-var-data,\n", | |
| ".xr-index-data-in:checked ~ .xr-index-data {\n", | |
| " display: block;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-data > table {\n", | |
| " float: right;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-name span,\n", | |
| ".xr-var-data,\n", | |
| ".xr-index-name div,\n", | |
| ".xr-index-data,\n", | |
| ".xr-attrs {\n", | |
| " padding-left: 25px !important;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-attrs,\n", | |
| ".xr-var-attrs,\n", | |
| ".xr-var-data,\n", | |
| ".xr-index-data {\n", | |
| " grid-column: 1 / -1;\n", | |
| "}\n", | |
| "\n", | |
| "dl.xr-attrs {\n", | |
| " padding: 0;\n", | |
| " margin: 0;\n", | |
| " display: grid;\n", | |
| " grid-template-columns: 125px auto;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-attrs dt,\n", | |
| ".xr-attrs dd {\n", | |
| " padding: 0;\n", | |
| " margin: 0;\n", | |
| " float: left;\n", | |
| " padding-right: 10px;\n", | |
| " width: auto;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-attrs dt {\n", | |
| " font-weight: normal;\n", | |
| " grid-column: 1;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-attrs dt:hover span {\n", | |
| " display: inline-block;\n", | |
| " background: var(--xr-background-color);\n", | |
| " padding-right: 10px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-attrs dd {\n", | |
| " grid-column: 2;\n", | |
| " white-space: pre-wrap;\n", | |
| " word-break: break-all;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-icon-database,\n", | |
| ".xr-icon-file-text2,\n", | |
| ".xr-no-icon {\n", | |
| " display: inline-block;\n", | |
| " vertical-align: middle;\n", | |
| " width: 1em;\n", | |
| " height: 1.5em !important;\n", | |
| " stroke-width: 0;\n", | |
| " stroke: currentColor;\n", | |
| " fill: currentColor;\n", | |
| "}\n", | |
| "</style><pre class='xr-text-repr-fallback'><xarray.DataArray 'temperature' (time: 19716, latitude: 721, longitude: 1440)> Size: 82GB\n", | |
| "dask.array<open_dataset-temperature, shape=(19716, 721, 1440), dtype=float32, chunksize=(32, 721, 1440), chunktype=numpy.ndarray>\n", | |
| "Coordinates:\n", | |
| " * latitude (latitude) float32 3kB 90.0 89.75 89.5 ... -89.5 -89.75 -90.0\n", | |
| " level int64 8B ...\n", | |
| " * longitude (longitude) float32 6kB 0.0 0.25 0.5 0.75 ... 359.2 359.5 359.8\n", | |
| " * time (time) datetime64[ns] 158kB 2018-01-01 ... 2020-06-30T22:00:00\n", | |
| "Attributes:\n", | |
| " long_name: Temperature\n", | |
| " short_name: t\n", | |
| " standard_name: air_temperature\n", | |
| " units: K</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'temperature'</div><ul class='xr-dim-list'><li><span class='xr-has-index'>time</span>: 19716</li><li><span class='xr-has-index'>latitude</span>: 721</li><li><span class='xr-has-index'>longitude</span>: 1440</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-aa59b650-1f5f-44ff-a7b4-b4e3ccace8c5' class='xr-array-in' type='checkbox' checked><label for='section-aa59b650-1f5f-44ff-a7b4-b4e3ccace8c5' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>dask.array<chunksize=(32, 721, 1440), meta=np.ndarray></span></div><div class='xr-array-data'><table>\n", | |
| " <tr>\n", | |
| " <td>\n", | |
| " <table style=\"border-collapse: collapse;\">\n", | |
| " <thead>\n", | |
| " <tr>\n", | |
| " <td> </td>\n", | |
| " <th> Array </th>\n", | |
| " <th> Chunk </th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <th> Bytes </th>\n", | |
| " <td> 76.26 GiB </td>\n", | |
| " <td> 126.74 MiB </td>\n", | |
| " </tr>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <th> Shape </th>\n", | |
| " <td> (19716, 721, 1440) </td>\n", | |
| " <td> (32, 721, 1440) </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th> Dask graph </th>\n", | |
| " <td colspan=\"2\"> 617 chunks in 2 graph layers </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th> Data type </th>\n", | |
| " <td colspan=\"2\"> float32 numpy.ndarray </td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| " </table>\n", | |
| " </td>\n", | |
| " <td>\n", | |
| " <svg width=\"167\" height=\"153\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n", | |
| "\n", | |
| " <!-- Horizontal lines -->\n", | |
| " <line x1=\"10\" y1=\"0\" x2=\"80\" y2=\"70\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"10\" y1=\"32\" x2=\"80\" y2=\"103\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Vertical lines -->\n", | |
| " <line x1=\"10\" y1=\"0\" x2=\"10\" y2=\"32\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"13\" y1=\"3\" x2=\"13\" y2=\"36\" />\n", | |
| " <line x1=\"17\" y1=\"7\" x2=\"17\" y2=\"39\" />\n", | |
| " <line x1=\"21\" y1=\"11\" x2=\"21\" y2=\"43\" />\n", | |
| " <line x1=\"24\" y1=\"14\" x2=\"24\" y2=\"47\" />\n", | |
| " <line x1=\"28\" y1=\"18\" x2=\"28\" y2=\"51\" />\n", | |
| " <line x1=\"32\" y1=\"22\" x2=\"32\" y2=\"54\" />\n", | |
| " <line x1=\"36\" y1=\"26\" x2=\"36\" y2=\"58\" />\n", | |
| " <line x1=\"39\" y1=\"29\" x2=\"39\" y2=\"62\" />\n", | |
| " <line x1=\"43\" y1=\"33\" x2=\"43\" y2=\"66\" />\n", | |
| " <line x1=\"47\" y1=\"37\" x2=\"47\" y2=\"69\" />\n", | |
| " <line x1=\"50\" y1=\"40\" x2=\"50\" y2=\"73\" />\n", | |
| " <line x1=\"54\" y1=\"44\" x2=\"54\" y2=\"77\" />\n", | |
| " <line x1=\"58\" y1=\"48\" x2=\"58\" y2=\"80\" />\n", | |
| " <line x1=\"62\" y1=\"52\" x2=\"62\" y2=\"84\" />\n", | |
| " <line x1=\"65\" y1=\"55\" x2=\"65\" y2=\"88\" />\n", | |
| " <line x1=\"69\" y1=\"59\" x2=\"69\" y2=\"92\" />\n", | |
| " <line x1=\"73\" y1=\"63\" x2=\"73\" y2=\"95\" />\n", | |
| " <line x1=\"76\" y1=\"66\" x2=\"76\" y2=\"99\" />\n", | |
| " <line x1=\"80\" y1=\"70\" x2=\"80\" y2=\"103\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Colored Rectangle -->\n", | |
| " <polygon points=\"10.0,0.0 80.58823529411765,70.58823529411765 80.58823529411765,103.17485576364696 10.0,32.58662046952931\" style=\"fill:#8B4903A0;stroke-width:0\"/>\n", | |
| "\n", | |
| " <!-- Horizontal lines -->\n", | |
| " <line x1=\"10\" y1=\"0\" x2=\"46\" y2=\"0\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"13\" y1=\"3\" x2=\"50\" y2=\"3\" />\n", | |
| " <line x1=\"17\" y1=\"7\" x2=\"54\" y2=\"7\" />\n", | |
| " <line x1=\"21\" y1=\"11\" x2=\"57\" y2=\"11\" />\n", | |
| " <line x1=\"24\" y1=\"14\" x2=\"61\" y2=\"14\" />\n", | |
| " <line x1=\"28\" y1=\"18\" x2=\"65\" y2=\"18\" />\n", | |
| " <line x1=\"32\" y1=\"22\" x2=\"69\" y2=\"22\" />\n", | |
| " <line x1=\"36\" y1=\"26\" x2=\"72\" y2=\"26\" />\n", | |
| " <line x1=\"39\" y1=\"29\" x2=\"76\" y2=\"29\" />\n", | |
| " <line x1=\"43\" y1=\"33\" x2=\"80\" y2=\"33\" />\n", | |
| " <line x1=\"47\" y1=\"37\" x2=\"83\" y2=\"37\" />\n", | |
| " <line x1=\"50\" y1=\"40\" x2=\"87\" y2=\"40\" />\n", | |
| " <line x1=\"54\" y1=\"44\" x2=\"91\" y2=\"44\" />\n", | |
| " <line x1=\"58\" y1=\"48\" x2=\"95\" y2=\"48\" />\n", | |
| " <line x1=\"62\" y1=\"52\" x2=\"98\" y2=\"52\" />\n", | |
| " <line x1=\"65\" y1=\"55\" x2=\"102\" y2=\"55\" />\n", | |
| " <line x1=\"69\" y1=\"59\" x2=\"106\" y2=\"59\" />\n", | |
| " <line x1=\"73\" y1=\"63\" x2=\"110\" y2=\"63\" />\n", | |
| " <line x1=\"76\" y1=\"66\" x2=\"113\" y2=\"66\" />\n", | |
| " <line x1=\"80\" y1=\"70\" x2=\"117\" y2=\"70\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Vertical lines -->\n", | |
| " <line x1=\"10\" y1=\"0\" x2=\"80\" y2=\"70\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"46\" y1=\"0\" x2=\"117\" y2=\"70\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Colored Rectangle -->\n", | |
| " <polygon points=\"10.0,0.0 46.79157840450466,0.0 117.37981369862231,70.58823529411765 80.58823529411765,70.58823529411765\" style=\"fill:#8B4903A0;stroke-width:0\"/>\n", | |
| "\n", | |
| " <!-- Horizontal lines -->\n", | |
| " <line x1=\"80\" y1=\"70\" x2=\"117\" y2=\"70\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"80\" y1=\"103\" x2=\"117\" y2=\"103\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Vertical lines -->\n", | |
| " <line x1=\"80\" y1=\"70\" x2=\"80\" y2=\"103\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"117\" y1=\"70\" x2=\"117\" y2=\"103\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Colored Rectangle -->\n", | |
| " <polygon points=\"80.58823529411765,70.58823529411765 117.37981369862231,70.58823529411765 117.37981369862231,103.17485576364696 80.58823529411765,103.17485576364696\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n", | |
| "\n", | |
| " <!-- Text -->\n", | |
| " <text x=\"98.984024\" y=\"123.174856\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >1440</text>\n", | |
| " <text x=\"137.379814\" y=\"86.881546\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,137.379814,86.881546)\">721</text>\n", | |
| " <text x=\"35.294118\" y=\"87.880738\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(45,35.294118,87.880738)\">19716</text>\n", | |
| "</svg>\n", | |
| " </td>\n", | |
| " </tr>\n", | |
| "</table></div></div></li><li class='xr-section-item'><input id='section-d9ea6dcb-e1ad-4145-b56d-535c0ae5d4fc' class='xr-section-summary-in' type='checkbox' checked><label for='section-d9ea6dcb-e1ad-4145-b56d-535c0ae5d4fc' class='xr-section-summary' >Coordinates: <span>(4)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>latitude</span></div><div class='xr-var-dims'>(latitude)</div><div class='xr-var-dtype'>float32</div><div class='xr-var-preview xr-preview'>90.0 89.75 89.5 ... -89.75 -90.0</div><input id='attrs-9f44f98d-b5b6-45c3-a487-3c189b3f91da' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-9f44f98d-b5b6-45c3-a487-3c189b3f91da' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-a0ec79c1-e5d5-41f7-aafa-98d31835ef4e' class='xr-var-data-in' type='checkbox'><label for='data-a0ec79c1-e5d5-41f7-aafa-98d31835ef4e' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>long_name :</span></dt><dd>latitude</dd><dt><span>units :</span></dt><dd>degrees_north</dd></dl></div><div class='xr-var-data'><pre>array([ 90. , 89.75, 89.5 , ..., -89.5 , -89.75, -90. ],\n", | |
| " shape=(721,), dtype=float32)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>level</span></div><div class='xr-var-dims'>()</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>...</div><input id='attrs-ecfa72fd-23f2-41d8-9907-4d501ff0734a' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-ecfa72fd-23f2-41d8-9907-4d501ff0734a' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-f4a13335-b638-40de-88a0-1003b20f69ca' class='xr-var-data-in' type='checkbox'><label for='data-f4a13335-b638-40de-88a0-1003b20f69ca' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>[1 values with dtype=int64]</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>longitude</span></div><div class='xr-var-dims'>(longitude)</div><div class='xr-var-dtype'>float32</div><div class='xr-var-preview xr-preview'>0.0 0.25 0.5 ... 359.2 359.5 359.8</div><input id='attrs-1e5bd008-bb2a-4735-86e5-6508302d0a1a' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-1e5bd008-bb2a-4735-86e5-6508302d0a1a' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-83b60eef-4513-4ee1-8fea-2e54d94c3960' class='xr-var-data-in' type='checkbox'><label for='data-83b60eef-4513-4ee1-8fea-2e54d94c3960' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>long_name :</span></dt><dd>longitude</dd><dt><span>units :</span></dt><dd>degrees_east</dd></dl></div><div class='xr-var-data'><pre>array([0.0000e+00, 2.5000e-01, 5.0000e-01, ..., 3.5925e+02, 3.5950e+02,\n", | |
| " 3.5975e+02], shape=(1440,), dtype=float32)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>time</span></div><div class='xr-var-dims'>(time)</div><div class='xr-var-dtype'>datetime64[ns]</div><div class='xr-var-preview xr-preview'>2018-01-01 ... 2020-06-30T22:00:00</div><input id='attrs-0b70c7ee-5813-4a7f-8369-9589367af77b' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-0b70c7ee-5813-4a7f-8369-9589367af77b' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-39a0a620-a8d5-481c-822d-43beab8b56db' class='xr-var-data-in' type='checkbox'><label for='data-39a0a620-a8d5-481c-822d-43beab8b56db' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array(['2018-01-01T00:00:00.000000000', '2018-01-01T02:00:00.000000000',\n", | |
| " '2018-01-01T04:00:00.000000000', ..., '2020-06-30T18:00:00.000000000',\n", | |
| " '2020-06-30T20:00:00.000000000', '2020-06-30T22:00:00.000000000'],\n", | |
| " shape=(19716,), dtype='datetime64[ns]')</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-f15d8279-fe42-4eba-a2d1-99e04bf47975' class='xr-section-summary-in' type='checkbox' ><label for='section-f15d8279-fe42-4eba-a2d1-99e04bf47975' class='xr-section-summary' >Indexes: <span>(3)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-index-name'><div>latitude</div></div><div class='xr-index-preview'>PandasIndex</div><input type='checkbox' disabled/><label></label><input id='index-56a1f314-4b5e-4473-96c3-7aef25aab987' class='xr-index-data-in' type='checkbox'/><label for='index-56a1f314-4b5e-4473-96c3-7aef25aab987' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(Index([ 90.0, 89.75, 89.5, 89.25, 89.0, 88.75, 88.5, 88.25, 88.0,\n", | |
| " 87.75,\n", | |
| " ...\n", | |
| " -87.75, -88.0, -88.25, -88.5, -88.75, -89.0, -89.25, -89.5, -89.75,\n", | |
| " -90.0],\n", | |
| " dtype='float32', name='latitude', length=721))</pre></div></li><li class='xr-var-item'><div class='xr-index-name'><div>longitude</div></div><div class='xr-index-preview'>PandasIndex</div><input type='checkbox' disabled/><label></label><input id='index-ca8a1e08-fb6c-411e-a859-bf8d5363be6c' class='xr-index-data-in' type='checkbox'/><label for='index-ca8a1e08-fb6c-411e-a859-bf8d5363be6c' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(Index([ 0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0,\n", | |
| " 2.25,\n", | |
| " ...\n", | |
| " 357.5, 357.75, 358.0, 358.25, 358.5, 358.75, 359.0, 359.25, 359.5,\n", | |
| " 359.75],\n", | |
| " dtype='float32', name='longitude', length=1440))</pre></div></li><li class='xr-var-item'><div class='xr-index-name'><div>time</div></div><div class='xr-index-preview'>PandasIndex</div><input type='checkbox' disabled/><label></label><input id='index-4a0309a1-9bb4-4115-bf74-ea39cc978e58' class='xr-index-data-in' type='checkbox'/><label for='index-4a0309a1-9bb4-4115-bf74-ea39cc978e58' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(DatetimeIndex(['2018-01-01 00:00:00', '2018-01-01 02:00:00',\n", | |
| " '2018-01-01 04:00:00', '2018-01-01 06:00:00',\n", | |
| " '2018-01-01 08:00:00', '2018-01-01 10:00:00',\n", | |
| " '2018-01-01 12:00:00', '2018-01-01 14:00:00',\n", | |
| " '2018-01-01 16:00:00', '2018-01-01 18:00:00',\n", | |
| " ...\n", | |
| " '2020-06-30 04:00:00', '2020-06-30 06:00:00',\n", | |
| " '2020-06-30 08:00:00', '2020-06-30 10:00:00',\n", | |
| " '2020-06-30 12:00:00', '2020-06-30 14:00:00',\n", | |
| " '2020-06-30 16:00:00', '2020-06-30 18:00:00',\n", | |
| " '2020-06-30 20:00:00', '2020-06-30 22:00:00'],\n", | |
| " dtype='datetime64[ns]', name='time', length=19716, freq=None))</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-b52f91b8-18de-4781-96ab-62303751cab2' class='xr-section-summary-in' type='checkbox' checked><label for='section-b52f91b8-18de-4781-96ab-62303751cab2' class='xr-section-summary' >Attributes: <span>(4)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'><dt><span>long_name :</span></dt><dd>Temperature</dd><dt><span>short_name :</span></dt><dd>t</dd><dt><span>standard_name :</span></dt><dd>air_temperature</dd><dt><span>units :</span></dt><dd>K</dd></dl></div></li></ul></div></div>" | |
| ], | |
| "text/plain": [ | |
| "<xarray.DataArray 'temperature' (time: 19716, latitude: 721, longitude: 1440)> Size: 82GB\n", | |
| "dask.array<open_dataset-temperature, shape=(19716, 721, 1440), dtype=float32, chunksize=(32, 721, 1440), chunktype=numpy.ndarray>\n", | |
| "Coordinates:\n", | |
| " * latitude (latitude) float32 3kB 90.0 89.75 89.5 ... -89.5 -89.75 -90.0\n", | |
| " level int64 8B ...\n", | |
| " * longitude (longitude) float32 6kB 0.0 0.25 0.5 0.75 ... 359.2 359.5 359.8\n", | |
| " * time (time) datetime64[ns] 158kB 2018-01-01 ... 2020-06-30T22:00:00\n", | |
| "Attributes:\n", | |
| " long_name: Temperature\n", | |
| " short_name: t\n", | |
| " standard_name: air_temperature\n", | |
| " units: K" | |
| ] | |
| }, | |
| "execution_count": 4, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "X = xr.open_dataset(\n", | |
| " \"datasets/t500_ERA5_2h_0p25deg.zarr\", chunks=\"auto\"\n", | |
| ")\n", | |
| "X = X[\"temperature\"]\n", | |
| "X" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "21ae70b7", | |
| "metadata": {}, | |
| "source": [ | |
| "Choose a time slice and stack the lat and lon coordinates along a single spatial dimension. Transpose the array to have dimensions (space x time) - i.e. a tall and skinny matrix - and chunk along rows, keeping all columns in the same chunk." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 5, | |
| "id": "d329a046", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n", | |
| "<defs>\n", | |
| "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n", | |
| "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n", | |
| "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n", | |
| "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n", | |
| "</symbol>\n", | |
| "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n", | |
| "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n", | |
| "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n", | |
| "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n", | |
| "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n", | |
| "</symbol>\n", | |
| "</defs>\n", | |
| "</svg>\n", | |
| "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n", | |
| " *\n", | |
| " */\n", | |
| "\n", | |
| ":root {\n", | |
| " --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n", | |
| " --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n", | |
| " --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n", | |
| " --xr-border-color: var(--jp-border-color2, #e0e0e0);\n", | |
| " --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n", | |
| " --xr-background-color: var(--jp-layout-color0, white);\n", | |
| " --xr-background-color-row-even: var(--jp-layout-color1, white);\n", | |
| " --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n", | |
| "}\n", | |
| "\n", | |
| "html[theme=\"dark\"],\n", | |
| "html[data-theme=\"dark\"],\n", | |
| "body[data-theme=\"dark\"],\n", | |
| "body.vscode-dark {\n", | |
| " --xr-font-color0: rgba(255, 255, 255, 1);\n", | |
| " --xr-font-color2: rgba(255, 255, 255, 0.54);\n", | |
| " --xr-font-color3: rgba(255, 255, 255, 0.38);\n", | |
| " --xr-border-color: #1f1f1f;\n", | |
| " --xr-disabled-color: #515151;\n", | |
| " --xr-background-color: #111111;\n", | |
| " --xr-background-color-row-even: #111111;\n", | |
| " --xr-background-color-row-odd: #313131;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-wrap {\n", | |
| " display: block !important;\n", | |
| " min-width: 300px;\n", | |
| " max-width: 700px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-text-repr-fallback {\n", | |
| " /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n", | |
| " display: none;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-header {\n", | |
| " padding-top: 6px;\n", | |
| " padding-bottom: 6px;\n", | |
| " margin-bottom: 4px;\n", | |
| " border-bottom: solid 1px var(--xr-border-color);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-header > div,\n", | |
| ".xr-header > ul {\n", | |
| " display: inline;\n", | |
| " margin-top: 0;\n", | |
| " margin-bottom: 0;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-obj-type,\n", | |
| ".xr-array-name {\n", | |
| " margin-left: 2px;\n", | |
| " margin-right: 10px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-obj-type {\n", | |
| " color: var(--xr-font-color2);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-sections {\n", | |
| " padding-left: 0 !important;\n", | |
| " display: grid;\n", | |
| " grid-template-columns: 150px auto auto 1fr 0 20px 0 20px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-item {\n", | |
| " display: contents;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-item input {\n", | |
| " display: inline-block;\n", | |
| " opacity: 0;\n", | |
| " height: 0;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-item input + label {\n", | |
| " color: var(--xr-disabled-color);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-item input:enabled + label {\n", | |
| " cursor: pointer;\n", | |
| " color: var(--xr-font-color2);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-item input:focus + label {\n", | |
| " border: 2px solid var(--xr-font-color0);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-item input:enabled + label:hover {\n", | |
| " color: var(--xr-font-color0);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary {\n", | |
| " grid-column: 1;\n", | |
| " color: var(--xr-font-color2);\n", | |
| " font-weight: 500;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary > span {\n", | |
| " display: inline-block;\n", | |
| " padding-left: 0.5em;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary-in:disabled + label {\n", | |
| " color: var(--xr-font-color2);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary-in + label:before {\n", | |
| " display: inline-block;\n", | |
| " content: \"►\";\n", | |
| " font-size: 11px;\n", | |
| " width: 15px;\n", | |
| " text-align: center;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary-in:disabled + label:before {\n", | |
| " color: var(--xr-disabled-color);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary-in:checked + label:before {\n", | |
| " content: \"▼\";\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary-in:checked + label > span {\n", | |
| " display: none;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary,\n", | |
| ".xr-section-inline-details {\n", | |
| " padding-top: 4px;\n", | |
| " padding-bottom: 4px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-inline-details {\n", | |
| " grid-column: 2 / -1;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-details {\n", | |
| " display: none;\n", | |
| " grid-column: 1 / -1;\n", | |
| " margin-bottom: 5px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-section-summary-in:checked ~ .xr-section-details {\n", | |
| " display: contents;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-array-wrap {\n", | |
| " grid-column: 1 / -1;\n", | |
| " display: grid;\n", | |
| " grid-template-columns: 20px auto;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-array-wrap > label {\n", | |
| " grid-column: 1;\n", | |
| " vertical-align: top;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-preview {\n", | |
| " color: var(--xr-font-color3);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-array-preview,\n", | |
| ".xr-array-data {\n", | |
| " padding: 0 5px !important;\n", | |
| " grid-column: 2;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-array-data,\n", | |
| ".xr-array-in:checked ~ .xr-array-preview {\n", | |
| " display: none;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-array-in:checked ~ .xr-array-data,\n", | |
| ".xr-array-preview {\n", | |
| " display: inline-block;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-dim-list {\n", | |
| " display: inline-block !important;\n", | |
| " list-style: none;\n", | |
| " padding: 0 !important;\n", | |
| " margin: 0;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-dim-list li {\n", | |
| " display: inline-block;\n", | |
| " padding: 0;\n", | |
| " margin: 0;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-dim-list:before {\n", | |
| " content: \"(\";\n", | |
| "}\n", | |
| "\n", | |
| ".xr-dim-list:after {\n", | |
| " content: \")\";\n", | |
| "}\n", | |
| "\n", | |
| ".xr-dim-list li:not(:last-child):after {\n", | |
| " content: \",\";\n", | |
| " padding-right: 5px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-has-index {\n", | |
| " font-weight: bold;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-list,\n", | |
| ".xr-var-item {\n", | |
| " display: contents;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-item > div,\n", | |
| ".xr-var-item label,\n", | |
| ".xr-var-item > .xr-var-name span {\n", | |
| " background-color: var(--xr-background-color-row-even);\n", | |
| " margin-bottom: 0;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-item > .xr-var-name:hover span {\n", | |
| " padding-right: 5px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-list > li:nth-child(odd) > div,\n", | |
| ".xr-var-list > li:nth-child(odd) > label,\n", | |
| ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n", | |
| " background-color: var(--xr-background-color-row-odd);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-name {\n", | |
| " grid-column: 1;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-dims {\n", | |
| " grid-column: 2;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-dtype {\n", | |
| " grid-column: 3;\n", | |
| " text-align: right;\n", | |
| " color: var(--xr-font-color2);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-preview {\n", | |
| " grid-column: 4;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-index-preview {\n", | |
| " grid-column: 2 / 5;\n", | |
| " color: var(--xr-font-color2);\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-name,\n", | |
| ".xr-var-dims,\n", | |
| ".xr-var-dtype,\n", | |
| ".xr-preview,\n", | |
| ".xr-attrs dt {\n", | |
| " white-space: nowrap;\n", | |
| " overflow: hidden;\n", | |
| " text-overflow: ellipsis;\n", | |
| " padding-right: 10px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-name:hover,\n", | |
| ".xr-var-dims:hover,\n", | |
| ".xr-var-dtype:hover,\n", | |
| ".xr-attrs dt:hover {\n", | |
| " overflow: visible;\n", | |
| " width: auto;\n", | |
| " z-index: 1;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-attrs,\n", | |
| ".xr-var-data,\n", | |
| ".xr-index-data {\n", | |
| " display: none;\n", | |
| " background-color: var(--xr-background-color) !important;\n", | |
| " padding-bottom: 5px !important;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n", | |
| ".xr-var-data-in:checked ~ .xr-var-data,\n", | |
| ".xr-index-data-in:checked ~ .xr-index-data {\n", | |
| " display: block;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-data > table {\n", | |
| " float: right;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-var-name span,\n", | |
| ".xr-var-data,\n", | |
| ".xr-index-name div,\n", | |
| ".xr-index-data,\n", | |
| ".xr-attrs {\n", | |
| " padding-left: 25px !important;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-attrs,\n", | |
| ".xr-var-attrs,\n", | |
| ".xr-var-data,\n", | |
| ".xr-index-data {\n", | |
| " grid-column: 1 / -1;\n", | |
| "}\n", | |
| "\n", | |
| "dl.xr-attrs {\n", | |
| " padding: 0;\n", | |
| " margin: 0;\n", | |
| " display: grid;\n", | |
| " grid-template-columns: 125px auto;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-attrs dt,\n", | |
| ".xr-attrs dd {\n", | |
| " padding: 0;\n", | |
| " margin: 0;\n", | |
| " float: left;\n", | |
| " padding-right: 10px;\n", | |
| " width: auto;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-attrs dt {\n", | |
| " font-weight: normal;\n", | |
| " grid-column: 1;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-attrs dt:hover span {\n", | |
| " display: inline-block;\n", | |
| " background: var(--xr-background-color);\n", | |
| " padding-right: 10px;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-attrs dd {\n", | |
| " grid-column: 2;\n", | |
| " white-space: pre-wrap;\n", | |
| " word-break: break-all;\n", | |
| "}\n", | |
| "\n", | |
| ".xr-icon-database,\n", | |
| ".xr-icon-file-text2,\n", | |
| ".xr-no-icon {\n", | |
| " display: inline-block;\n", | |
| " vertical-align: middle;\n", | |
| " width: 1em;\n", | |
| " height: 1.5em !important;\n", | |
| " stroke-width: 0;\n", | |
| " stroke: currentColor;\n", | |
| " fill: currentColor;\n", | |
| "}\n", | |
| "</style><pre class='xr-text-repr-fallback'><xarray.DataArray 'temperature' (space: 1038240, time: 2184)> Size: 9GB\n", | |
| "dask.array<rechunk-p2p, shape=(1038240, 2184), dtype=float32, chunksize=(15363, 2184), chunktype=numpy.ndarray>\n", | |
| "Coordinates:\n", | |
| " level int64 8B ...\n", | |
| " * time (time) datetime64[ns] 17kB 2016-01-01 ... 2016-06-30T22:00:00\n", | |
| " * space (space) object 8MB MultiIndex\n", | |
| " * latitude (space) float32 4MB 90.0 90.0 90.0 90.0 ... -90.0 -90.0 -90.0\n", | |
| " * longitude (space) float32 4MB 0.0 0.25 0.5 0.75 ... 359.0 359.2 359.5 359.8\n", | |
| "Attributes:\n", | |
| " long_name: Temperature\n", | |
| " short_name: t\n", | |
| " standard_name: air_temperature\n", | |
| " units: K</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'temperature'</div><ul class='xr-dim-list'><li><span class='xr-has-index'>space</span>: 1038240</li><li><span class='xr-has-index'>time</span>: 2184</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-dda70b92-a7c2-4ebe-b048-3e1afe250fa1' class='xr-array-in' type='checkbox' checked><label for='section-dda70b92-a7c2-4ebe-b048-3e1afe250fa1' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>dask.array<chunksize=(15363, 2184), meta=np.ndarray></span></div><div class='xr-array-data'><table>\n", | |
| " <tr>\n", | |
| " <td>\n", | |
| " <table style=\"border-collapse: collapse;\">\n", | |
| " <thead>\n", | |
| " <tr>\n", | |
| " <td> </td>\n", | |
| " <th> Array </th>\n", | |
| " <th> Chunk </th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <th> Bytes </th>\n", | |
| " <td> 8.45 GiB </td>\n", | |
| " <td> 127.99 MiB </td>\n", | |
| " </tr>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <th> Shape </th>\n", | |
| " <td> (1038240, 2184) </td>\n", | |
| " <td> (15363, 2184) </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th> Dask graph </th>\n", | |
| " <td colspan=\"2\"> 68 chunks in 7 graph layers </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th> Data type </th>\n", | |
| " <td colspan=\"2\"> float32 numpy.ndarray </td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| " </table>\n", | |
| " </td>\n", | |
| " <td>\n", | |
| " <svg width=\"75\" height=\"170\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n", | |
| "\n", | |
| " <!-- Horizontal lines -->\n", | |
| " <line x1=\"0\" y1=\"0\" x2=\"25\" y2=\"0\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"0\" y1=\"5\" x2=\"25\" y2=\"5\" />\n", | |
| " <line x1=\"0\" y1=\"12\" x2=\"25\" y2=\"12\" />\n", | |
| " <line x1=\"0\" y1=\"17\" x2=\"25\" y2=\"17\" />\n", | |
| " <line x1=\"0\" y1=\"24\" x2=\"25\" y2=\"24\" />\n", | |
| " <line x1=\"0\" y1=\"30\" x2=\"25\" y2=\"30\" />\n", | |
| " <line x1=\"0\" y1=\"37\" x2=\"25\" y2=\"37\" />\n", | |
| " <line x1=\"0\" y1=\"44\" x2=\"25\" y2=\"44\" />\n", | |
| " <line x1=\"0\" y1=\"49\" x2=\"25\" y2=\"49\" />\n", | |
| " <line x1=\"0\" y1=\"56\" x2=\"25\" y2=\"56\" />\n", | |
| " <line x1=\"0\" y1=\"62\" x2=\"25\" y2=\"62\" />\n", | |
| " <line x1=\"0\" y1=\"69\" x2=\"25\" y2=\"69\" />\n", | |
| " <line x1=\"0\" y1=\"74\" x2=\"25\" y2=\"74\" />\n", | |
| " <line x1=\"0\" y1=\"81\" x2=\"25\" y2=\"81\" />\n", | |
| " <line x1=\"0\" y1=\"88\" x2=\"25\" y2=\"88\" />\n", | |
| " <line x1=\"0\" y1=\"94\" x2=\"25\" y2=\"94\" />\n", | |
| " <line x1=\"0\" y1=\"101\" x2=\"25\" y2=\"101\" />\n", | |
| " <line x1=\"0\" y1=\"106\" x2=\"25\" y2=\"106\" />\n", | |
| " <line x1=\"0\" y1=\"113\" x2=\"25\" y2=\"113\" />\n", | |
| " <line x1=\"0\" y1=\"120\" x2=\"25\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Vertical lines -->\n", | |
| " <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"25\" y1=\"0\" x2=\"25\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Colored Rectangle -->\n", | |
| " <polygon points=\"0.0,0.0 25.412616514582485,0.0 25.412616514582485,120.0 0.0,120.0\" style=\"fill:#8B4903A0;stroke-width:0\"/>\n", | |
| "\n", | |
| " <!-- Text -->\n", | |
| " <text x=\"12.706308\" y=\"140.000000\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >2184</text>\n", | |
| " <text x=\"45.412617\" y=\"60.000000\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,45.412617,60.000000)\">1038240</text>\n", | |
| "</svg>\n", | |
| " </td>\n", | |
| " </tr>\n", | |
| "</table></div></div></li><li class='xr-section-item'><input id='section-1d48f892-b5ff-43fc-8e6b-1545efd75fa1' class='xr-section-summary-in' type='checkbox' checked><label for='section-1d48f892-b5ff-43fc-8e6b-1545efd75fa1' class='xr-section-summary' >Coordinates: <span>(5)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span>level</span></div><div class='xr-var-dims'>()</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>...</div><input id='attrs-8ab0cf64-7346-4759-a95a-56f9aa048748' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-8ab0cf64-7346-4759-a95a-56f9aa048748' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-939431f8-81db-4dcd-a422-838016abcd88' class='xr-var-data-in' type='checkbox'><label for='data-939431f8-81db-4dcd-a422-838016abcd88' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>[1 values with dtype=int64]</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>time</span></div><div class='xr-var-dims'>(time)</div><div class='xr-var-dtype'>datetime64[ns]</div><div class='xr-var-preview xr-preview'>2016-01-01 ... 2016-06-30T22:00:00</div><input id='attrs-376f3c4f-7171-47b2-a89d-939a92470b69' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-376f3c4f-7171-47b2-a89d-939a92470b69' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-baecfa72-93d0-4701-b030-2e5b632804d1' class='xr-var-data-in' type='checkbox'><label for='data-baecfa72-93d0-4701-b030-2e5b632804d1' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array(['2016-01-01T00:00:00.000000000', '2016-01-01T02:00:00.000000000',\n", | |
| " '2016-01-01T04:00:00.000000000', ..., '2016-06-30T18:00:00.000000000',\n", | |
| " '2016-06-30T20:00:00.000000000', '2016-06-30T22:00:00.000000000'],\n", | |
| " shape=(2184,), dtype='datetime64[ns]')</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>space</span></div><div class='xr-var-dims'>(space)</div><div class='xr-var-dtype'>object</div><div class='xr-var-preview xr-preview'>MultiIndex</div><input id='attrs-7e81e273-42bf-49cc-aef6-23506a47df3f' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-7e81e273-42bf-49cc-aef6-23506a47df3f' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-a69cc9af-e2ab-4d52-8227-37d56182e67b' class='xr-var-data-in' type='checkbox'><label for='data-a69cc9af-e2ab-4d52-8227-37d56182e67b' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([(90.0, 0.0), (90.0, 0.25), (90.0, 0.5), ..., (-90.0, 359.25),\n", | |
| " (-90.0, 359.5), (-90.0, 359.75)], shape=(202,), dtype=object)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>latitude</span></div><div class='xr-var-dims'>(space)</div><div class='xr-var-dtype'>float32</div><div class='xr-var-preview xr-preview'>90.0 90.0 90.0 ... -90.0 -90.0</div><input id='attrs-ceca3dba-2c42-4e35-a984-8b70652169d2' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-ceca3dba-2c42-4e35-a984-8b70652169d2' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-bd44b3a8-6e5a-4473-bc8f-6bb80c395870' class='xr-var-data-in' type='checkbox'><label for='data-bd44b3a8-6e5a-4473-bc8f-6bb80c395870' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>long_name :</span></dt><dd>latitude</dd><dt><span>units :</span></dt><dd>degrees_north</dd></dl></div><div class='xr-var-data'><pre>array([ 90., 90., 90., ..., -90., -90., -90.], shape=(202,), dtype=float32)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>longitude</span></div><div class='xr-var-dims'>(space)</div><div class='xr-var-dtype'>float32</div><div class='xr-var-preview xr-preview'>0.0 0.25 0.5 ... 359.2 359.5 359.8</div><input id='attrs-73853f43-de44-45d7-8eb6-89cd961ae1b6' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-73853f43-de44-45d7-8eb6-89cd961ae1b6' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-792d5fb5-dee1-4c31-93f8-38ee573d32b4' class='xr-var-data-in' type='checkbox'><label for='data-792d5fb5-dee1-4c31-93f8-38ee573d32b4' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>long_name :</span></dt><dd>longitude</dd><dt><span>units :</span></dt><dd>degrees_east</dd></dl></div><div class='xr-var-data'><pre>array([0.0000e+00, 2.5000e-01, 5.0000e-01, ..., 3.5925e+02, 3.5950e+02,\n", | |
| " 3.5975e+02], shape=(202,), dtype=float32)</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-28b63197-ace4-4916-9c4d-aa58db5409bb' class='xr-section-summary-in' type='checkbox' ><label for='section-28b63197-ace4-4916-9c4d-aa58db5409bb' class='xr-section-summary' >Indexes: <span>(2)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-index-name'><div>time</div></div><div class='xr-index-preview'>PandasIndex</div><input type='checkbox' disabled/><label></label><input id='index-2e804e1c-1a86-409a-9a38-dbd48acb7053' class='xr-index-data-in' type='checkbox'/><label for='index-2e804e1c-1a86-409a-9a38-dbd48acb7053' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(DatetimeIndex(['2016-01-01 00:00:00', '2016-01-01 02:00:00',\n", | |
| " '2016-01-01 04:00:00', '2016-01-01 06:00:00',\n", | |
| " '2016-01-01 08:00:00', '2016-01-01 10:00:00',\n", | |
| " '2016-01-01 12:00:00', '2016-01-01 14:00:00',\n", | |
| " '2016-01-01 16:00:00', '2016-01-01 18:00:00',\n", | |
| " ...\n", | |
| " '2016-06-30 04:00:00', '2016-06-30 06:00:00',\n", | |
| " '2016-06-30 08:00:00', '2016-06-30 10:00:00',\n", | |
| " '2016-06-30 12:00:00', '2016-06-30 14:00:00',\n", | |
| " '2016-06-30 16:00:00', '2016-06-30 18:00:00',\n", | |
| " '2016-06-30 20:00:00', '2016-06-30 22:00:00'],\n", | |
| " dtype='datetime64[ns]', name='time', length=2184, freq=None))</pre></div></li><li class='xr-var-item'><div class='xr-index-name'><div>space<br>latitude<br>longitude</div></div><div class='xr-index-preview'>PandasMultiIndex</div><input type='checkbox' disabled/><label></label><input id='index-8732f7aa-dfb9-4200-aff6-af9075819d7c' class='xr-index-data-in' type='checkbox'/><label for='index-8732f7aa-dfb9-4200-aff6-af9075819d7c' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(MultiIndex([( 90.0, 0.0),\n", | |
| " ( 90.0, 0.25),\n", | |
| " ( 90.0, 0.5),\n", | |
| " ( 90.0, 0.75),\n", | |
| " ( 90.0, 1.0),\n", | |
| " ( 90.0, 1.25),\n", | |
| " ( 90.0, 1.5),\n", | |
| " ( 90.0, 1.75),\n", | |
| " ( 90.0, 2.0),\n", | |
| " ( 90.0, 2.25),\n", | |
| " ...\n", | |
| " (-90.0, 357.5),\n", | |
| " (-90.0, 357.75),\n", | |
| " (-90.0, 358.0),\n", | |
| " (-90.0, 358.25),\n", | |
| " (-90.0, 358.5),\n", | |
| " (-90.0, 358.75),\n", | |
| " (-90.0, 359.0),\n", | |
| " (-90.0, 359.25),\n", | |
| " (-90.0, 359.5),\n", | |
| " (-90.0, 359.75)],\n", | |
| " name='space', length=1038240))</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-bf42d5fb-9b01-4a79-b030-ba32d771bf0d' class='xr-section-summary-in' type='checkbox' checked><label for='section-bf42d5fb-9b01-4a79-b030-ba32d771bf0d' class='xr-section-summary' >Attributes: <span>(4)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'><dt><span>long_name :</span></dt><dd>Temperature</dd><dt><span>short_name :</span></dt><dd>t</dd><dt><span>standard_name :</span></dt><dd>air_temperature</dd><dt><span>units :</span></dt><dd>K</dd></dl></div></li></ul></div></div>" | |
| ], | |
| "text/plain": [ | |
| "<xarray.DataArray 'temperature' (space: 1038240, time: 2184)> Size: 9GB\n", | |
| "dask.array<rechunk-p2p, shape=(1038240, 2184), dtype=float32, chunksize=(15363, 2184), chunktype=numpy.ndarray>\n", | |
| "Coordinates:\n", | |
| " level int64 8B ...\n", | |
| " * time (time) datetime64[ns] 17kB 2016-01-01 ... 2016-06-30T22:00:00\n", | |
| " * space (space) object 8MB MultiIndex\n", | |
| " * latitude (space) float32 4MB 90.0 90.0 90.0 90.0 ... -90.0 -90.0 -90.0\n", | |
| " * longitude (space) float32 4MB 0.0 0.25 0.5 0.75 ... 359.0 359.2 359.5 359.8\n", | |
| "Attributes:\n", | |
| " long_name: Temperature\n", | |
| " short_name: t\n", | |
| " standard_name: air_temperature\n", | |
| " units: K" | |
| ] | |
| }, | |
| "execution_count": 5, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "X = X.sortby(\"time\")\n", | |
| "X = X.sel(time=slice(\"2016-01-01\", \"2016-06-30\"))\n", | |
| "X = X.stack(space=(\"latitude\", \"longitude\"))\n", | |
| "X = X.transpose(\"space\", \"time\")\n", | |
| "X = X.chunk({\"space\": \"auto\", \"time\": -1})\n", | |
| "X" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "c6eea24b", | |
| "metadata": {}, | |
| "source": [ | |
| "Extract the Dask Array from the Xarray DataArray." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 6, | |
| "id": "6b1f6683", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<table>\n", | |
| " <tr>\n", | |
| " <td>\n", | |
| " <table style=\"border-collapse: collapse;\">\n", | |
| " <thead>\n", | |
| " <tr>\n", | |
| " <td> </td>\n", | |
| " <th> Array </th>\n", | |
| " <th> Chunk </th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <th> Bytes </th>\n", | |
| " <td> 8.45 GiB </td>\n", | |
| " <td> 127.99 MiB </td>\n", | |
| " </tr>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <th> Shape </th>\n", | |
| " <td> (1038240, 2184) </td>\n", | |
| " <td> (15363, 2184) </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th> Dask graph </th>\n", | |
| " <td colspan=\"2\"> 68 chunks in 7 graph layers </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th> Data type </th>\n", | |
| " <td colspan=\"2\"> float32 numpy.ndarray </td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| " </table>\n", | |
| " </td>\n", | |
| " <td>\n", | |
| " <svg width=\"75\" height=\"170\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n", | |
| "\n", | |
| " <!-- Horizontal lines -->\n", | |
| " <line x1=\"0\" y1=\"0\" x2=\"25\" y2=\"0\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"0\" y1=\"5\" x2=\"25\" y2=\"5\" />\n", | |
| " <line x1=\"0\" y1=\"12\" x2=\"25\" y2=\"12\" />\n", | |
| " <line x1=\"0\" y1=\"17\" x2=\"25\" y2=\"17\" />\n", | |
| " <line x1=\"0\" y1=\"24\" x2=\"25\" y2=\"24\" />\n", | |
| " <line x1=\"0\" y1=\"30\" x2=\"25\" y2=\"30\" />\n", | |
| " <line x1=\"0\" y1=\"37\" x2=\"25\" y2=\"37\" />\n", | |
| " <line x1=\"0\" y1=\"44\" x2=\"25\" y2=\"44\" />\n", | |
| " <line x1=\"0\" y1=\"49\" x2=\"25\" y2=\"49\" />\n", | |
| " <line x1=\"0\" y1=\"56\" x2=\"25\" y2=\"56\" />\n", | |
| " <line x1=\"0\" y1=\"62\" x2=\"25\" y2=\"62\" />\n", | |
| " <line x1=\"0\" y1=\"69\" x2=\"25\" y2=\"69\" />\n", | |
| " <line x1=\"0\" y1=\"74\" x2=\"25\" y2=\"74\" />\n", | |
| " <line x1=\"0\" y1=\"81\" x2=\"25\" y2=\"81\" />\n", | |
| " <line x1=\"0\" y1=\"88\" x2=\"25\" y2=\"88\" />\n", | |
| " <line x1=\"0\" y1=\"94\" x2=\"25\" y2=\"94\" />\n", | |
| " <line x1=\"0\" y1=\"101\" x2=\"25\" y2=\"101\" />\n", | |
| " <line x1=\"0\" y1=\"106\" x2=\"25\" y2=\"106\" />\n", | |
| " <line x1=\"0\" y1=\"113\" x2=\"25\" y2=\"113\" />\n", | |
| " <line x1=\"0\" y1=\"120\" x2=\"25\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Vertical lines -->\n", | |
| " <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"25\" y1=\"0\" x2=\"25\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Colored Rectangle -->\n", | |
| " <polygon points=\"0.0,0.0 25.412616514582485,0.0 25.412616514582485,120.0 0.0,120.0\" style=\"fill:#8B4903A0;stroke-width:0\"/>\n", | |
| "\n", | |
| " <!-- Text -->\n", | |
| " <text x=\"12.706308\" y=\"140.000000\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >2184</text>\n", | |
| " <text x=\"45.412617\" y=\"60.000000\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,45.412617,60.000000)\">1038240</text>\n", | |
| "</svg>\n", | |
| " </td>\n", | |
| " </tr>\n", | |
| "</table>" | |
| ], | |
| "text/plain": [ | |
| "dask.array<rechunk-p2p, shape=(1038240, 2184), dtype=float32, chunksize=(15363, 2184), chunktype=numpy.ndarray>" | |
| ] | |
| }, | |
| "execution_count": 6, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "X = X.data\n", | |
| "X" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 7, | |
| "id": "fe81f06d", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/plain": [ | |
| "dask.array.core.Array" | |
| ] | |
| }, | |
| "execution_count": 7, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "type(X)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "1a39167b", | |
| "metadata": {}, | |
| "source": [ | |
| "Pin data in distributed RAM and trigger the computation." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 8, | |
| "id": "7e5ddd0d", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "application/vnd.jupyter.widget-view+json": { | |
| "model_id": "416b2a64af2d4fe69074ae09f1d69e1c", | |
| "version_major": 2, | |
| "version_minor": 0 | |
| }, | |
| "text/plain": [ | |
| "VBox()" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "X = X.persist()\n", | |
| "progress(X)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "77d693dd", | |
| "metadata": {}, | |
| "source": [ | |
| "## Exact SVD\n", | |
| "\n", | |
| "First we will compute the exact SVD, which in Dask works for tall-and-skinny matrices or short-and-fat matrices, chunked along one direction only. This is computationally expensive, and returns all singular values and associated singular vectors (similar to `numpy.linalg.svd` with `full_matrices=False`), which might be very large." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 28, | |
| "id": "26e3f082", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "application/vnd.jupyter.widget-view+json": { | |
| "model_id": "a69832efaf2f4924947655ff23b18dc6", | |
| "version_major": 2, | |
| "version_minor": 0 | |
| }, | |
| "text/plain": [ | |
| "VBox()" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "u, s, v = da.linalg.svd(X)\n", | |
| "svd_result = client.persist([u, s, v]) # pin data in distributed RAM and trigger computation\n", | |
| "progress(svd_result)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 30, | |
| "id": "c1fa2cff", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<table>\n", | |
| " <tr>\n", | |
| " <td>\n", | |
| " <table style=\"border-collapse: collapse;\">\n", | |
| " <thead>\n", | |
| " <tr>\n", | |
| " <td> </td>\n", | |
| " <th> Array </th>\n", | |
| " <th> Chunk </th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <th> Bytes </th>\n", | |
| " <td> 8.45 GiB </td>\n", | |
| " <td> 127.99 MiB </td>\n", | |
| " </tr>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <th> Shape </th>\n", | |
| " <td> (1038240, 2184) </td>\n", | |
| " <td> (15363, 2184) </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th> Dask graph </th>\n", | |
| " <td colspan=\"2\"> 68 chunks in 1 graph layer </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th> Data type </th>\n", | |
| " <td colspan=\"2\"> float32 numpy.ndarray </td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| " </table>\n", | |
| " </td>\n", | |
| " <td>\n", | |
| " <svg width=\"75\" height=\"170\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n", | |
| "\n", | |
| " <!-- Horizontal lines -->\n", | |
| " <line x1=\"0\" y1=\"0\" x2=\"25\" y2=\"0\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"0\" y1=\"5\" x2=\"25\" y2=\"5\" />\n", | |
| " <line x1=\"0\" y1=\"12\" x2=\"25\" y2=\"12\" />\n", | |
| " <line x1=\"0\" y1=\"17\" x2=\"25\" y2=\"17\" />\n", | |
| " <line x1=\"0\" y1=\"24\" x2=\"25\" y2=\"24\" />\n", | |
| " <line x1=\"0\" y1=\"30\" x2=\"25\" y2=\"30\" />\n", | |
| " <line x1=\"0\" y1=\"37\" x2=\"25\" y2=\"37\" />\n", | |
| " <line x1=\"0\" y1=\"44\" x2=\"25\" y2=\"44\" />\n", | |
| " <line x1=\"0\" y1=\"49\" x2=\"25\" y2=\"49\" />\n", | |
| " <line x1=\"0\" y1=\"56\" x2=\"25\" y2=\"56\" />\n", | |
| " <line x1=\"0\" y1=\"62\" x2=\"25\" y2=\"62\" />\n", | |
| " <line x1=\"0\" y1=\"69\" x2=\"25\" y2=\"69\" />\n", | |
| " <line x1=\"0\" y1=\"74\" x2=\"25\" y2=\"74\" />\n", | |
| " <line x1=\"0\" y1=\"81\" x2=\"25\" y2=\"81\" />\n", | |
| " <line x1=\"0\" y1=\"88\" x2=\"25\" y2=\"88\" />\n", | |
| " <line x1=\"0\" y1=\"94\" x2=\"25\" y2=\"94\" />\n", | |
| " <line x1=\"0\" y1=\"101\" x2=\"25\" y2=\"101\" />\n", | |
| " <line x1=\"0\" y1=\"106\" x2=\"25\" y2=\"106\" />\n", | |
| " <line x1=\"0\" y1=\"113\" x2=\"25\" y2=\"113\" />\n", | |
| " <line x1=\"0\" y1=\"120\" x2=\"25\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Vertical lines -->\n", | |
| " <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"25\" y1=\"0\" x2=\"25\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Colored Rectangle -->\n", | |
| " <polygon points=\"0.0,0.0 25.412616514582485,0.0 25.412616514582485,120.0 0.0,120.0\" style=\"fill:#8B4903A0;stroke-width:0\"/>\n", | |
| "\n", | |
| " <!-- Text -->\n", | |
| " <text x=\"12.706308\" y=\"140.000000\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >2184</text>\n", | |
| " <text x=\"45.412617\" y=\"60.000000\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,45.412617,60.000000)\">1038240</text>\n", | |
| "</svg>\n", | |
| " </td>\n", | |
| " </tr>\n", | |
| "</table>" | |
| ], | |
| "text/plain": [ | |
| "dask.array<mul, shape=(1038240, 2184), dtype=float32, chunksize=(15363, 2184), chunktype=numpy.ndarray>" | |
| ] | |
| }, | |
| "execution_count": 30, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "u, s, v = svd_result\n", | |
| "del svd_result\n", | |
| "u" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "ed51a45f", | |
| "metadata": {}, | |
| "source": [ | |
| "Keep only 50 components." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 31, | |
| "id": "867f7143", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "n_components = 50\n", | |
| "u = u[:, :n_components]\n", | |
| "s = s[:n_components]\n", | |
| "v = v[:n_components, :]" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "188f3958", | |
| "metadata": {}, | |
| "source": [ | |
| "Convert the Dask arrays into in-memory NumPy arrays." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 32, | |
| "id": "54fe52f7", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "u_exact_svd_np = u.compute()\n", | |
| "s_exact_svd_np = s.compute()\n", | |
| "v_exact_svd_np = v.compute()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 13, | |
| "id": "ad66f4a5", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/plain": [ | |
| "numpy.ndarray" | |
| ] | |
| }, | |
| "execution_count": 13, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "type(u_exact_svd_np)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "a2ca96eb", | |
| "metadata": {}, | |
| "source": [ | |
| "Remove data from distributed RAM by removing the collection from the local process. See [Clearing Data](https://distributed.dask.org/en/stable/memory.html#clearing-data) and [Aggressively Clearing Data](https://distributed.dask.org/en/stable/memory.html#aggressively-clearing-data)." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 33, | |
| "id": "46d8832d", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "client.cancel([u, s, v]) # explicitly release worker memory\n", | |
| "del u, s, v # delete local data" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "a099518f", | |
| "metadata": {}, | |
| "source": [ | |
| "### Transpose matrix\n", | |
| "\n", | |
| "Now let's see how the exact SVD algorithm performs on a short and fat matrix." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 15, | |
| "id": "3b7b1860", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "application/vnd.jupyter.widget-view+json": { | |
| "model_id": "c169d7790c5b488d86a87a822f6e04cb", | |
| "version_major": 2, | |
| "version_minor": 0 | |
| }, | |
| "text/plain": [ | |
| "VBox()" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "X = da.transpose(X)\n", | |
| "X = X.persist()\n", | |
| "progress(X)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 16, | |
| "id": "67a91b68", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "(2184, 1038240)\n", | |
| "(2184, 15363)\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "print(X.shape)\n", | |
| "print(X.chunksize)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 17, | |
| "id": "b7b91f6f", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "application/vnd.jupyter.widget-view+json": { | |
| "model_id": "c8b70687a58944049e3b3b3c213b3ee6", | |
| "version_major": 2, | |
| "version_minor": 0 | |
| }, | |
| "text/plain": [ | |
| "VBox()" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "u, s, v = da.linalg.svd(X)\n", | |
| "svd_result = client.persist([u, s, v]) # pin data in distributed RAM and trigger computation\n", | |
| "progress(svd_result)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 18, | |
| "id": "27df9ace", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<table>\n", | |
| " <tr>\n", | |
| " <td>\n", | |
| " <table style=\"border-collapse: collapse;\">\n", | |
| " <thead>\n", | |
| " <tr>\n", | |
| " <td> </td>\n", | |
| " <th> Array </th>\n", | |
| " <th> Chunk </th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <th> Bytes </th>\n", | |
| " <td> 8.45 GiB </td>\n", | |
| " <td> 127.99 MiB </td>\n", | |
| " </tr>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <th> Shape </th>\n", | |
| " <td> (2184, 1038240) </td>\n", | |
| " <td> (2184, 15363) </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th> Dask graph </th>\n", | |
| " <td colspan=\"2\"> 68 chunks in 1 graph layer </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th> Data type </th>\n", | |
| " <td colspan=\"2\"> float32 numpy.ndarray </td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| " </table>\n", | |
| " </td>\n", | |
| " <td>\n", | |
| " <svg width=\"170\" height=\"75\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n", | |
| "\n", | |
| " <!-- Horizontal lines -->\n", | |
| " <line x1=\"0\" y1=\"0\" x2=\"120\" y2=\"0\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"0\" y1=\"25\" x2=\"120\" y2=\"25\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Vertical lines -->\n", | |
| " <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"25\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"5\" y1=\"0\" x2=\"5\" y2=\"25\" />\n", | |
| " <line x1=\"12\" y1=\"0\" x2=\"12\" y2=\"25\" />\n", | |
| " <line x1=\"17\" y1=\"0\" x2=\"17\" y2=\"25\" />\n", | |
| " <line x1=\"24\" y1=\"0\" x2=\"24\" y2=\"25\" />\n", | |
| " <line x1=\"30\" y1=\"0\" x2=\"30\" y2=\"25\" />\n", | |
| " <line x1=\"37\" y1=\"0\" x2=\"37\" y2=\"25\" />\n", | |
| " <line x1=\"44\" y1=\"0\" x2=\"44\" y2=\"25\" />\n", | |
| " <line x1=\"49\" y1=\"0\" x2=\"49\" y2=\"25\" />\n", | |
| " <line x1=\"56\" y1=\"0\" x2=\"56\" y2=\"25\" />\n", | |
| " <line x1=\"62\" y1=\"0\" x2=\"62\" y2=\"25\" />\n", | |
| " <line x1=\"69\" y1=\"0\" x2=\"69\" y2=\"25\" />\n", | |
| " <line x1=\"74\" y1=\"0\" x2=\"74\" y2=\"25\" />\n", | |
| " <line x1=\"81\" y1=\"0\" x2=\"81\" y2=\"25\" />\n", | |
| " <line x1=\"88\" y1=\"0\" x2=\"88\" y2=\"25\" />\n", | |
| " <line x1=\"94\" y1=\"0\" x2=\"94\" y2=\"25\" />\n", | |
| " <line x1=\"101\" y1=\"0\" x2=\"101\" y2=\"25\" />\n", | |
| " <line x1=\"106\" y1=\"0\" x2=\"106\" y2=\"25\" />\n", | |
| " <line x1=\"113\" y1=\"0\" x2=\"113\" y2=\"25\" />\n", | |
| " <line x1=\"120\" y1=\"0\" x2=\"120\" y2=\"25\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Colored Rectangle -->\n", | |
| " <polygon points=\"0.0,0.0 120.0,0.0 120.0,25.412616514582485 0.0,25.412616514582485\" style=\"fill:#8B4903A0;stroke-width:0\"/>\n", | |
| "\n", | |
| " <!-- Text -->\n", | |
| " <text x=\"60.000000\" y=\"45.412617\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >1038240</text>\n", | |
| " <text x=\"140.000000\" y=\"12.706308\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,140.000000,12.706308)\">2184</text>\n", | |
| "</svg>\n", | |
| " </td>\n", | |
| " </tr>\n", | |
| "</table>" | |
| ], | |
| "text/plain": [ | |
| "dask.array<mul, shape=(2184, 1038240), dtype=float32, chunksize=(2184, 15363), chunktype=numpy.ndarray>" | |
| ] | |
| }, | |
| "execution_count": 18, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "u, s, v = svd_result\n", | |
| "del svd_result\n", | |
| "v" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "d455837c", | |
| "metadata": {}, | |
| "source": [ | |
| "Keep only 50 components." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 19, | |
| "id": "fd1ecd7e", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "n_components = 50\n", | |
| "u = u[:, :n_components]\n", | |
| "s = s[:n_components]\n", | |
| "v = v[:n_components, :]" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "a7dbd365", | |
| "metadata": {}, | |
| "source": [ | |
| "Convert Dask arrays into in-memory NumPy arrays." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 20, | |
| "id": "c51785d6", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "u_exact_svd_np_t = u.compute()\n", | |
| "s_exact_svd_np_t = s.compute()\n", | |
| "v_exact_svd_np_t = v.compute()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "6bdaaa9d", | |
| "metadata": {}, | |
| "source": [ | |
| "Verify that the left singular vectors of X are the same as the right singular vectors of X transposed. We would expect the dot product matrix to be a diagonal matrix containing 1 or -1 along the diagonal, and zero everywhere else. " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 64, | |
| "id": "e1a14fba", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "dot_product = u_exact_svd_np.T @ v_exact_svd_np_t.T" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 65, | |
| "id": "691091fb", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "image/png": "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", | |
| "text/plain": [ | |
| "<Figure size 640x480 with 2 Axes>" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "plt.imshow(dot_product, cmap=\"bwr\", interpolation=\"nearest\", vmin=-1, vmax=1)\n", | |
| "plt.colorbar(label='Dot Product Value')\n", | |
| "plt.title(\"Left singular vectors\")\n", | |
| "plt.show()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "5dc6a514", | |
| "metadata": {}, | |
| "source": [ | |
| "Similarly, the right singular vectors of X should be the same as the left singular vectors of X transposed." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 69, | |
| "id": "960746aa", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "dot_product = v_exact_svd_np @ u_exact_svd_np_t" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 70, | |
| "id": "4a50cdf2", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "image/png": "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", | |
| "text/plain": [ | |
| "<Figure size 640x480 with 2 Axes>" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "plt.imshow(dot_product, cmap=\"bwr\", interpolation=\"nearest\", vmin=-1, vmax=1)\n", | |
| "plt.colorbar(label='Dot Product Value')\n", | |
| "plt.title(\"Right singular vectors\")\n", | |
| "plt.show()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "9a3ed861", | |
| "metadata": {}, | |
| "source": [ | |
| "And the singular values should be the same" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 71, | |
| "id": "3ff61f26", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGzCAYAAAD9pBdvAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAJZxJREFUeJzt3QucVnWdP/DfAHIxBUPkpqB0UUsSDS+RlmtiZC5/zXbV3BbSrDQsFSuhVGRLsbV1NcW8tZLbyxuuWnk30FhdFEXdvCdJwhIXqbiqoHD+r+/ZntkZGGAGZ+Y3l/f79Toyz3nOOc/v/J7HOZ/ndzlTVRRFkQAAMumQ64UBAIIwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACzez8889PVVVVWV77iSeeSB//+MfTe97znrIMzzzzTKs8j7pMmTKlLM8f/vCH1Nq0tLqE5iaM0O5VLmKVpVOnTmnnnXdOX/rSl9KCBQu26phvvPFGeYF5+OGHU0vx9ttvp7//+79Pf/7zn9O//uu/pn//939Pu+66a+5iAaROuQsALcU//dM/pUGDBqW33norPfbYY2VIeeSRR9Jzzz2Xunbt2uAwMnHixPLnv/mbv6n13DnnnJPGjRuXmtvvf//79Nprr6Vrr702nXzyye/6eLnOA2h7hBH4qyOOOCLtt99+5c9xse7Vq1f64Q9/mH75y1+mY489ttFeJ1peYmluS5YsKf/dYYcdWvV5NJcIlNtuu23uYkC7oJsGNuETn/hEdYtCxdq1a9N5552Xhg4dmnr06FGOvYjtHnrooeptYszCTjvtVP4crSOV7p/ottnU+IB33nknff/730/vf//7U5cuXdJuu+2Wvvvd76Y1a9bUq6zTp08vyxHlibBx1FFHpRdffLH6+ehyOuSQQ8qfo6smXn/DFpsNu3Si7B/84AfLVqEdd9wxHXzwwenBBx+s3qau84jHp512WrrzzjvT4MGDy3PZa6+90n333bfRa0QXVoS/OH6c99VXX73RMaMu43G0Um2oZp1uyi9+8Yt05JFHpv79+5dlideJel63bl2t7aIuoryzZ89On/zkJ8sQEvVflx/96Efla0cr04bGjx+fOnfunP7yl7+Uj//zP/+zrO+BAweWrz9gwIB05plnpjfffHOz5W7oeUd34kknnZT69OlTXef/9m//ttG+l19+eflcnN973/vesv5vvPHGzZYFmkPb/VoD71JlIGT80q5YsWJFuu6669IXvvCF9JWvfCWtXLky/fSnP00jRoxIs2bNSvvss08ZRH7yk5+kU089NX3uc59LxxxzTLnv3nvvvcnXipaYn/3sZ+nv/u7v0llnnZUef/zxNGnSpDJQ3HHHHZst569//euyVed973tfeZGKC11cdA466KD01FNPlcHma1/7WjkO5sILL0zf/OY30/77719euDYljhOvH+U64IADyvN+8skny+Mdfvjhmy1PdG3dfvvt6etf/3rafvvt049//OP0+c9/Ps2bN68MNeHpp59On/nMZ1K/fv3K0BPhILrJKiGuscTFfLvttktjx44t/43QFmEyzufiiy+ute2f/vSnsh6PP/749MUvfnGT9ROtZN/5znfSrbfemr797W/Xei7WffrTn67+zEydOrVsYYnPQpx7fEbivfmf//mf8rnGsHjx4vSxj32sOghGHd57773py1/+cnmeZ5xxRrlddM/Fex+fsdNPP73sjvztb39bftZOOOGERikLbLUC2rnrr7++iP8Vfv3rXxevv/56MX/+/OK2224rdtppp6JLly7l44p33nmnWLNmTa39//KXvxR9+vQpTjrppOp1cZw45oQJEzZ6vVhX83+9Z555pnx88skn19ruW9/6Vrl++vTpmy3/PvvsU/Tu3bv405/+VL3uv//7v4sOHToUo0aNql730EMPlcebOnXqFutkyJAhxZFHHrnZbTY8jxCPO3fuXMyZM6dWWWL95ZdfXr1u5MiRxbbbblssWLCget0rr7xSdOrUqdYx586dWz6O92hDG9Zv5X2MfSreeOONjfb72te+Vr72W2+9Vb3ukEMOKfe96qqrivoYNmxYMXTo0FrrZs2aVR7jhhtu2OzrT5o0qaiqqipee+21TdZlQ877y1/+ctGvX79i6dKltbY7/vjjix49elSX4aijjir22muvep0fNDfdNPBXw4cPL79VRlN6fHuMLo8YL7LLLrtUb9OxY8eyGT6sX7++nJkSXSzR3B2tBlvjnnvuKf+Nb+81RQtJuPvuuze578KFC8vpudEN07Nnz+r10QoTLRiVYzdUdPU8//zz6ZVXXtmqeozukJpl6d69e3r11VfLx9EKEq05Rx99dNl9UvGBD3ygbJloTN26dav+OVqx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EQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAWlcYmTFjRho5cmTq379/qqqqSnfeeWe993300UdTp06d0j777NPQlwUA2qgGh5HVq1enIUOGpMmTJzdov2XLlqVRo0alww47rKEvCQC0YZ0ausMRRxxRLg11yimnpBNOOCF17NixQa0pAEDb1ixjRq6//vr06quvpgkTJtRr+zVr1qQVK1bUWgCAtqnJw8grr7ySxo0bl37+85+X40XqY9KkSalHjx7Vy4ABA5q6mABAWwwj69atK7tmJk6cmHbfffd67zd+/Pi0fPny6mX+/PlNWUwAoDWNGWmIlStXpieffDI9/fTT6bTTTivXrV+/PhVFUbaSPPDAA+lTn/rURvt16dKlXACAtq9Jw0j37t3Ts88+W2vdlVdemaZPn55uu+22NGjQoKZ8eQCgLYaRVatWpTlz5lQ/njt3bnrmmWdSz54908CBA8sulgULFqQbbrghdejQIQ0ePLjW/r17905du3bdaD0A0D41OIxEt8uhhx5a/Xjs2LHlv6NHj05TpkxJCxcuTPPmzWvcUgIAbVZVEQM4WriY2huzamIwa3T9AAAtX32v3/42DQCQlTACAGQljAAAWQkjAEBWwggAkJUwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACAGQljAAAWQkjAEBWwggAkJUwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACAGQljAAAWQkjAEBWwggAkJUwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACAGQljAAAWQkjAEBWwggAkJUwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACAGQljAAAWQkjAEBWwggAkJUwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACAGQljAAArSuMzJgxI40cOTL1798/VVVVpTvvvHOz299+++3p8MMPTzvttFPq3r17GjZsWLr//vvfTZkBgPYcRlavXp2GDBmSJk+eXO/wEmHknnvuSbNnz06HHnpoGWaefvrprSkvANDGVBVFUWz1zlVV6Y477khHH310g/bba6+90nHHHZfOO++8em2/YsWK1KNHj7R8+fKydQUAaPnqe/3u1KylSimtX78+rVy5MvXs2XOT26xZs6Zcap4MANA2NfsA1h/96Edp1apV6dhjj93kNpMmTSqTVGUZMGBAs5YRAGijYeTGG29MEydOTLfeemvq3bv3JrcbP3582aRTWebPn9+cxQQAmlGzddPcfPPN6eSTT05Tp05Nw4cP3+y2Xbp0KRcAoO1rlpaRm266KZ144onlv0ceeWRzvCQA0FZbRmK8x5w5c6ofz507Nz3zzDPlgNSBAweWXSwLFixIN9xwQ3XXzOjRo9Nll12WDjzwwLRo0aJyfbdu3crxIABA+9bglpEnn3wy7bvvvuUSxo4dW/5cmaa7cOHCNG/evOrtr7nmmvTOO++kMWPGpH79+lUvp59+emOeBwDQHu8z0lzcZwQAWp/6Xr/9bRoAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAIKtOqZ1at75Is+b+OS1Z+VbqvX3XdMCgnqljh6oGb9OYx2rObVpimVpruVtimZS75W3TEsuk3C1vm5ZapqbWLsPIfc8tTBN/9UJauPyt6nX9enRNE0Z+OH1mcL96b9OYx2rObVpimVpruVtimZS75W3TEsuk3C1vm5ZapuZQVRRF0ZAdZsyYkS6++OI0e/bstHDhwnTHHXeko48+erP7PPzww2ns2LHp+eefTwMGDEjnnHNO+tKXvlTv11yxYkXq0aNHWr58eerevXt6N6LyT/35U2nDk67kwJ988aPlv1vaJt6oxjpWc26j3G27TMqt3Mqt3I1ZpnervtfvBoeRe++9Nz366KNp6NCh6ZhjjtliGJk7d24aPHhwOuWUU9LJJ5+cpk2bls4444x09913pxEjRjTqyWxJNEcd/MPptVLghm9C7+27lD8sXrFmk9v06d413XfGJ9KIS2dsdrv6HKs5t1Hutl0m5VZu5Vbu3o20Td8eXdMjZ3/qXXfZNFkYqbVzVdUWw8jZZ59dBo/nnnuuet3xxx+fli1blu67774691mzZk251DyZaFF5t2Fk5u//lL5w7WNbvT8AtBc3feVjadj7d2yWMNLks2lmzpyZhg8fXmtdtIjE+k2ZNGlSWfjKEkGkMcQAHQCgZV0zmzyMLFq0KPXp06fWungcaenNN9+sc5/x48eXKaqyzJ8/v1HKEiOFG8vZn9kjtUbK3bbLVB/K3byUu3kpd+NpzGtmq7zPSJcuXcrmnJpLY4gpSzFSeFM9YGU/WfcuqW/3zW8Tx/jywe9rlGM15zbK3bbLpNzKrdzK3bcRyxTXzDYTRvr27ZsWL15ca108joDRrVu31JxiIE5MWQobvgmVx+f/v73S+f9v89vEMTp36tAox2rObZS7bZdJuZVbuZX7/EYsU3Peb6TJw8iwYcPKGTQ1Pfjgg+X6HGKqUkxZipHCNcXjylSm+mzTmMdqzm2Uu22XSbmVW7mV+zONWKbm0uDZNKtWrUpz5swpf953333TJZdckg499NDUs2fPNHDgwHK8x4IFC9INN9xQa2rvmDFj0kknnZSmT5+evvnNb2aZ2tte7pan3Mqk3C1vm5ZYJuVuedu01DK1uKm9cQOzCB8bGj16dJoyZUp5M7M//OEP5XY19znzzDPTCy+8kHbZZZd07rnnZrvpGQDQPJrlPiPNRRgBgNanxdxnBABgc4QRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAaH1hZPLkyWm33XZLXbt2TQceeGCaNWvWZre/9NJL0x577JG6deuWBgwYkM4888z01ltvbW2ZAYD2HEZuueWWNHbs2DRhwoT01FNPpSFDhqQRI0akJUuW1Ln9jTfemMaNG1du/+KLL6af/vSn5TG++93vNkb5AYBWrqooiqIhO0RLyP7775+uuOKK8vH69evL1o5vfOMbZejY0GmnnVaGkGnTplWvO+uss9Ljjz+eHnnkkTpfY82aNeVSsWLFivI1li9fnrp3796Q4gIAmcT1u0ePHlu8fjeoZWTt2rVp9uzZafjw4f93gA4dysczZ86sc5+Pf/zj5T6VrpxXX3013XPPPemzn/3sJl9n0qRJZeErSwQRAKBt6tSQjZcuXZrWrVuX+vTpU2t9PH7ppZfq3OeEE04o9zv44INTNMK888476ZRTTtlsN8348ePLrqANW0YAgLanyWfTPPzww+nCCy9MV155ZTnG5Pbbb0933313+v73v7/Jfbp06VI259RcAIC2qUEtI7169UodO3ZMixcvrrU+Hvft27fOfc4999z0j//4j+nkk08uH3/kIx9Jq1evTl/96lfT9773vbKbBwBovxqUBDp37pyGDh1aazBqDGCNx8OGDatznzfeeGOjwBGBJjRw7CwA0N5bRkKM5Rg9enTab7/90gEHHFDeQyRaOk488cTy+VGjRqWdd965HIQaRo4cmS655JK07777ljNx5syZU7aWxPpKKAEA2q8Gh5Hjjjsuvf766+m8885LixYtSvvss0+67777qge1zps3r1ZLyDnnnJOqqqrKfxcsWJB22mmnMohccMEFjXsmAED7uM9IS56nDAC08fuMAAA0NmEEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAGh9YWTy5Mlpt912S127dk0HHnhgmjVr1ma3X7ZsWRozZkzq169f6tKlS9p9993TPffcs7VlBgDakE4N3eGWW25JY8eOTVdddVUZRC699NI0YsSI9PLLL6fevXtvtP3atWvT4YcfXj532223pZ133jm99tpraYcddmiscwAAWrGqoiiKhuwQAWT//fdPV1xxRfl4/fr1acCAAekb3/hGGjdu3EbbR2i5+OKL00svvZS22WabrSrkihUrUo8ePdLy5ctT9+7dt+oYAEDzqu/1u0HdNNHKMXv27DR8+PD/O0CHDuXjmTNn1rnPL3/5yzRs2LCym6ZPnz5p8ODB6cILL0zr1q3b5OusWbOmPIGaCwDQNjUojCxdurQMEREqaorHixYtqnOfV199teyeif1inMi5556b/uVf/iX94Ac/2OTrTJo0qUxSlSVaXgCAtqnJZ9NEN06MF7nmmmvS0KFD03HHHZe+973vld03mzJ+/PiySaeyzJ8/v6mLCQC0hgGsvXr1Sh07dkyLFy+utT4e9+3bt859YgZNjBWJ/So+9KEPlS0p0e3TuXPnjfaJGTexAABtX4NaRiI4ROvGtGnTarV8xOMYF1KXgw46KM2ZM6fcruJ3v/tdGVLqCiIAQPvS4G6amNZ77bXXpp/97GfpxRdfTKeeempavXp1OvHEE8vnR40aVXazVMTzf/7zn9Ppp59ehpC77767HMAaA1oBABp8n5EY8/H666+n8847r+xq2WeffdJ9991XPah13rx55Qybihh8ev/996czzzwz7b333uV9RiKYnH322Y17JgBA+7jPSA7uMwIArU+T3GcEAKCxCSMAQFbCCACQlTACAGQljAAAWQkjAEBWwggAkJUwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACAGQljAAAWQkjAEBWwggAkJUwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACAGQljAAAWXVKrUBRFOW/K1asyF0UAKCeKtftynW8VYeRlStXlv8OGDAgd1EAgK24jvfo0WOTz1cVW4orLcD69evTH//4x7T99tunqqqqRk1sEXDmz5+funfv3mjHpW7qu3mp7+alvpuX+m4d9R0RI4JI//79U4cOHVp3y0icwC677NJkx4+K9WFuPuq7eanv5qW+m5f6bvn1vbkWkQoDWAGArIQRACCrdh1GunTpkiZMmFD+S9NT381LfTcv9d281Hfbqu9WMYAVAGi72nXLCACQnzACAGQljAAAWQkjAEBWwggAkFW7DiOTJ09Ou+22W+ratWs68MAD06xZs3IXqU2YMWNGGjlyZHn737h9/5133lnr+ZjAdd5556V+/fqlbt26peHDh6dXXnklW3lbu0mTJqX999+//HMJvXv3TkcffXR6+eWXa23z1ltvpTFjxqQdd9wxbbfddunzn/98Wrx4cbYyt2Y/+clP0t577119J8phw4ale++9t/p5dd10LrroovJ3yhlnnFG9Tn03rvPPP7+s45rLnnvu2eT13W7DyC233JLGjh1bzpt+6qmn0pAhQ9KIESPSkiVLchet1Vu9enVZnxH26vLP//zP6cc//nG66qqr0uOPP57e8573lHUfH3Ia7je/+U35y+Gxxx5LDz74YHr77bfTpz/96fJ9qDjzzDPTr371qzR16tRy+/hbT8ccc0zWcrdW8acp4qI4e/bs9OSTT6ZPfepT6aijjkrPP/98+by6bhpPPPFEuvrqq8sgWJP6bnx77bVXWrhwYfXyyCOPNH19F+3UAQccUIwZM6b68bp164r+/fsXkyZNylqutiY+YnfccUf14/Xr1xd9+/YtLr744up1y5YtK7p06VLcdNNNmUrZtixZsqSs99/85jfV9bvNNtsUU6dOrd7mxRdfLLeZOXNmxpK2He9973uL6667Tl03kZUrVxYf/OAHiwcffLA45JBDitNPP71cr74b34QJE4ohQ4bU+VxT1ne7bBlZu3Zt+a0mugdq/jG+eDxz5sysZWvr5s6dmxYtWlSr7uOPKEU3mbpvHMuXLy//7dmzZ/lvfNajtaRmnUez68CBA9X5u7Ru3bp08803l61Q0V2jrptGtPwdeeSRteo1qO+mEd3m0c3+vve9L/3DP/xDmjdvXpPXd6v4q72NbenSpeUvkT59+tRaH49feumlbOVqDyKIhLrqvvIcW2/9+vVlf/pBBx2UBg8eXK6Leu3cuXPaYYcdam2rzrfes88+W4aP6FqMfvM77rgjffjDH07PPPOMum5kEfaiKz26aTbks9344ovhlClT0h577FF20UycODF94hOfSM8991yT1ne7DCPQlr9Bxi+Nmn28NL74RR3BI1qhbrvttjR69Oiy/5zGNX/+/HT66aeXY6FiogFN74gjjqj+OcbnRDjZdddd06233lpOOGgq7bKbplevXqljx44bjQCOx3379s1WrvagUr/qvvGddtpp6a677koPPfRQOciyIuo1uiaXLVtWa3t1vvXi2+EHPvCBNHTo0HI2UwzYvuyyy9R1I4tugZhU8NGPfjR16tSpXCL0xQD4+Dm+kavvphWtILvvvnuaM2dOk36+O7TXXyTxS2TatGm1mrfjcTS90nQGDRpUfmhr1v2KFSvKWTXqfuvEOOEIItFVMH369LKOa4rP+jbbbFOrzmPqb/QDq/PGEb8/1qxZo64b2WGHHVZ2iUUrVGXZb7/9ynEMlZ/Vd9NatWpV+v3vf1/eiqFJP99FO3XzzTeXMzimTJlSvPDCC8VXv/rVYocddigWLVqUu2htYuT7008/XS7xEbvkkkvKn1977bXy+Ysuuqis61/84hfFb3/72+Koo44qBg0aVLz55pu5i94qnXrqqUWPHj2Khx9+uFi4cGH18sYbb1Rvc8oppxQDBw4spk+fXjz55JPFsGHDyoWGGzduXDlTae7cueXnNx5XVVUVDzzwQPm8um5aNWfTBPXduM4666zyd0l8vh999NFi+PDhRa9evcpZek1Z3+02jITLL7+8rNTOnTuXU30fe+yx3EVqEx566KEyhGy4jB49unp677nnnlv06dOnDISHHXZY8fLLL+cudqtVV13Hcv3111dvE0Hv61//ejkFddttty0+97nPlYGFhjvppJOKXXfdtfy9sdNOO5Wf30oQCeq6ecOI+m5cxx13XNGvX7/y873zzjuXj+fMmdPk9V0V/3n3DTkAAFunXY4ZAQBaDmEEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQBSTv8flOvT3Je4qaUAAAAASUVORK5CYII=", | |
| "text/plain": [ | |
| "<Figure size 640x480 with 1 Axes>" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "ratio = s_exact_svd_np/s_exact_svd_np_t\n", | |
| "plt.plot(ratio, \"o-\")\n", | |
| "plt.title(\"Ratio of singular values\")\n", | |
| "plt.ylim([0.5, 1.5])\n", | |
| "plt.show()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 25, | |
| "id": "355ae393", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "client.cancel([u, s, v]) # explicitly release worker memory\n", | |
| "del u, s, v # delete local data" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "47fc16da", | |
| "metadata": {}, | |
| "source": [ | |
| "## Randomized SVD\n", | |
| "\n", | |
| "An alternative to the exact SVD algorithm which is much faster and scales well with very large arrays is the Randomly Compressed Rank-k Thin SVD, provided by `dask.array.linalg.svd_compressed`. It supports matrices that don't need to be tall-and-skinny or short-and-fat. However, it only provides approximate results." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 26, | |
| "id": "ed456b74", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "application/vnd.jupyter.widget-view+json": { | |
| "model_id": "317701bc5de64984801d57290efda8ba", | |
| "version_major": 2, | |
| "version_minor": 0 | |
| }, | |
| "text/plain": [ | |
| "VBox()" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "X = da.transpose(X)\n", | |
| "X = X.persist()\n", | |
| "progress(X)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 27, | |
| "id": "77ddc595", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "(1038240, 2184)\n", | |
| "(15363, 2184)\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "print(X.shape)\n", | |
| "print(X.chunksize)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 28, | |
| "id": "20a99d48", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "application/vnd.jupyter.widget-view+json": { | |
| "model_id": "cffa22372b7142cc88d21bca9dc0cb6b", | |
| "version_major": 2, | |
| "version_minor": 0 | |
| }, | |
| "text/plain": [ | |
| "VBox()" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "u, s, v = da.linalg.svd_compressed(X, k=50)\n", | |
| "svd_result = client.persist([u, s, v])\n", | |
| "progress(svd_result)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 29, | |
| "id": "e6527b3e", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<table>\n", | |
| " <tr>\n", | |
| " <td>\n", | |
| " <table style=\"border-collapse: collapse;\">\n", | |
| " <thead>\n", | |
| " <tr>\n", | |
| " <td> </td>\n", | |
| " <th> Array </th>\n", | |
| " <th> Chunk </th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <th> Bytes </th>\n", | |
| " <td> 198.03 MiB </td>\n", | |
| " <td> 2.93 MiB </td>\n", | |
| " </tr>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <th> Shape </th>\n", | |
| " <td> (1038240, 50) </td>\n", | |
| " <td> (15363, 50) </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th> Dask graph </th>\n", | |
| " <td colspan=\"2\"> 68 chunks in 1 graph layer </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th> Data type </th>\n", | |
| " <td colspan=\"2\"> float32 numpy.ndarray </td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| " </table>\n", | |
| " </td>\n", | |
| " <td>\n", | |
| " <svg width=\"75\" height=\"170\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n", | |
| "\n", | |
| " <!-- Horizontal lines -->\n", | |
| " <line x1=\"0\" y1=\"0\" x2=\"25\" y2=\"0\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"0\" y1=\"5\" x2=\"25\" y2=\"5\" />\n", | |
| " <line x1=\"0\" y1=\"12\" x2=\"25\" y2=\"12\" />\n", | |
| " <line x1=\"0\" y1=\"17\" x2=\"25\" y2=\"17\" />\n", | |
| " <line x1=\"0\" y1=\"24\" x2=\"25\" y2=\"24\" />\n", | |
| " <line x1=\"0\" y1=\"30\" x2=\"25\" y2=\"30\" />\n", | |
| " <line x1=\"0\" y1=\"37\" x2=\"25\" y2=\"37\" />\n", | |
| " <line x1=\"0\" y1=\"44\" x2=\"25\" y2=\"44\" />\n", | |
| " <line x1=\"0\" y1=\"49\" x2=\"25\" y2=\"49\" />\n", | |
| " <line x1=\"0\" y1=\"56\" x2=\"25\" y2=\"56\" />\n", | |
| " <line x1=\"0\" y1=\"62\" x2=\"25\" y2=\"62\" />\n", | |
| " <line x1=\"0\" y1=\"69\" x2=\"25\" y2=\"69\" />\n", | |
| " <line x1=\"0\" y1=\"74\" x2=\"25\" y2=\"74\" />\n", | |
| " <line x1=\"0\" y1=\"81\" x2=\"25\" y2=\"81\" />\n", | |
| " <line x1=\"0\" y1=\"88\" x2=\"25\" y2=\"88\" />\n", | |
| " <line x1=\"0\" y1=\"94\" x2=\"25\" y2=\"94\" />\n", | |
| " <line x1=\"0\" y1=\"101\" x2=\"25\" y2=\"101\" />\n", | |
| " <line x1=\"0\" y1=\"106\" x2=\"25\" y2=\"106\" />\n", | |
| " <line x1=\"0\" y1=\"113\" x2=\"25\" y2=\"113\" />\n", | |
| " <line x1=\"0\" y1=\"120\" x2=\"25\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Vertical lines -->\n", | |
| " <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"25\" y1=\"0\" x2=\"25\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Colored Rectangle -->\n", | |
| " <polygon points=\"0.0,0.0 25.41261651458249,0.0 25.41261651458249,120.0 0.0,120.0\" style=\"fill:#8B4903A0;stroke-width:0\"/>\n", | |
| "\n", | |
| " <!-- Text -->\n", | |
| " <text x=\"12.706308\" y=\"140.000000\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >50</text>\n", | |
| " <text x=\"45.412617\" y=\"60.000000\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,45.412617,60.000000)\">1038240</text>\n", | |
| "</svg>\n", | |
| " </td>\n", | |
| " </tr>\n", | |
| "</table>" | |
| ], | |
| "text/plain": [ | |
| "dask.array<mul, shape=(1038240, 50), dtype=float32, chunksize=(15363, 50), chunktype=numpy.ndarray>" | |
| ] | |
| }, | |
| "execution_count": 29, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "u, s, v = svd_result\n", | |
| "del svd_result\n", | |
| "u" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "144f2fe9", | |
| "metadata": {}, | |
| "source": [ | |
| "Convert Dask arrays into in-memory NumPy arrays." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 30, | |
| "id": "51e08768", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "u_rand_svd_np = u.compute()\n", | |
| "s_rand_svd_np = s.compute()\n", | |
| "v_rand_svd_np = v.compute()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "808cb5f7", | |
| "metadata": {}, | |
| "source": [ | |
| "Check how the singular vectors and singular values computed via randomized SVD compare to the exact SVD." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 58, | |
| "id": "ec8b76b3", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "dot_product = u_exact_svd_np.T @ u_rand_svd_np" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 59, | |
| "id": "6eb43deb", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "image/png": "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", | |
| "text/plain": [ | |
| "<Figure size 640x480 with 2 Axes>" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "plt.imshow(dot_product, cmap=\"bwr\", interpolation=\"nearest\", vmin=-1, vmax=1)\n", | |
| "plt.colorbar(label='Dot Product Value')\n", | |
| "plt.title(\"Left singular vectors\")\n", | |
| "plt.show()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 60, | |
| "id": "f674275b", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "dot_product = v_exact_svd_np @ v_rand_svd_np.T" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 61, | |
| "id": "3e9f32e4", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "image/png": "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", | |
| "text/plain": [ | |
| "<Figure size 640x480 with 2 Axes>" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "plt.imshow(dot_product, cmap=\"bwr\", interpolation=\"nearest\", vmin=-1, vmax=1)\n", | |
| "plt.colorbar(label='Dot Product Value')\n", | |
| "plt.title(\"Right singular vectors\")\n", | |
| "plt.show()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "id": "89e6575c", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGzCAYAAAD9pBdvAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAANfpJREFUeJzt3Ql4VNX5x/E3ISSAkCBbwiq4AAIKioKIG5uIFHFpRW0LVVGx2CK4gQuLVrG1taKiqFQp9e8GFbSiIrIWBBGUuiBIECHFJCxCAgESktz/8x696STMTGYmM3Myk+/necbJzNy5987NyP3lnPecm+A4jiMAAACWJNraMAAAgCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijABRNnnyZElISLCy7U8++UTOPfdcOe6448w+bNiwISY/hzezZs0y+/Pdd99JrKluxxKINsIIajz3JObekpKSpGXLlvKb3/xGdu7cGdI6Dx06ZE4wy5Ytk+ri6NGj8otf/EJ++OEH+etf/yr/+Mc/5IQTTrC9WwAgSbZ3AKguHnzwQWnXrp0cOXJE1qxZY0LKypUr5csvv5Q6deoEHUamTJlifr7ooovKvXb//ffL+PHjJdq2bt0q27dvlxdeeEFGjhxZ5fXZ+hwA4g9hBPjJoEGD5KyzzjI/68m6SZMm8sc//lHefvttufrqq8O2HW150Vu07dq1y9w3bNgwpj9HtGigrFevnu3dAGoEumkAH84///yyFgVXUVGRTJw4Ubp37y5paWmm9kKXW7p0adkyWrPQtGlT87O2jrjdP9pt46s+oLi4WB566CE56aSTJCUlRdq2bSv33nuvFBYWBrSvS5YsMfuh+6NhY+jQofL111+Xva5dThdeeKH5WbtqdPsVW2wqdunovp9yyimmVahx48Zy3nnnyaJFi8qW8fY59PFtt90m8+fPly5dupjP0rlzZ3n//feP2YZ2YWn40/Xr537uueeOWaceS32srVQVeR5TX9566y0ZPHiwtGjRwuyLbkePc0lJSbnl9Fjo/q5fv14uuOACE0L0+Hvz5z//2WxbW5kqmjBhgiQnJ8u+ffvM43//+9/meLdp08Zsv3Xr1jJ27Fg5fPiw3/0O9nNrd+INN9wg6enpZcf8xRdfPOa9Tz31lHlNP9/xxx9vjv8rr7zid1+AaIjfP2uAKnILIfUfbVd+fr7MnDlTrr32WrnpppvkwIED8re//U0GDhwoa9eulW7dupkg8uyzz8qtt94qV1xxhVx55ZXmvaeffrrPbWlLzN///nf5+c9/LnfccYd8/PHHMnXqVBMo5s2b53c/P/zwQ9Oqc+KJJ5qTlJ7o9KTTu3dv+fTTT02wueWWW0wdzCOPPCK///3v5eyzzzYnLl90Pbp93a8ePXqYz71u3TqzvgEDBvjdH+3aevPNN+W3v/2tNGjQQJ588km56qqrZMeOHSbUqM8++0wuueQSad68uQk9Gg60m8wNceGiJ/P69evLuHHjzL2GNg2T+nkee+yxcsvu3bvXHMdrrrlGfvWrX/k8PtpKdvfdd8sbb7whd911V7nX9LmLL7647DszZ84c08Ki3wX97Pod0d/Nf//7X/NaOOTm5so555xTFgT1GL733nty4403ms95++23m+W0e05/9/odGzNmjOmO/Pzzz8137brrrgvLvgAhc4Aa7qWXXnL0f4UPP/zQ2b17t5OVleXMnTvXadq0qZOSkmIeu4qLi53CwsJy79+3b5+Tnp7u3HDDDWXP6Xp0nZMmTTpme/qc5/96GzZsMI9HjhxZbrk777zTPL9kyRK/+9+tWzenWbNmzt69e8ue+89//uMkJiY6w4cPL3tu6dKlZn1z5syp9Jh07drVGTx4sN9lKn4OpY+Tk5OdzMzMcvuizz/11FNlzw0ZMsSpV6+es3PnzrLntmzZ4iQlJZVb57Zt28xj/R1VVPH4ur9HfY/r0KFDx7zvlltuMds+cuRI2XMXXnihee+MGTOcQPTq1cvp3r17uefWrl1r1jF79my/2586daqTkJDgbN++3eexDOZz33jjjU7z5s2dPXv2lFvummuucdLS0sr2YejQoU7nzp0D+nxAtNFNA/ykf//+5q9KbUrXvx61y0PrRVq1alW2TK1atUwzvCotLTUjU7SLRZu7tdUgFO+++66517/ePWkLiVqwYIHP92ZnZ5vhudoN06hRo7LntRVGWzDcdQdLu3q++uor2bJlS0jHUbtDPPclNTVVvv32W/NYW0G0Nefyyy833Seuk08+2bRMhFPdunXLftZWrD179pjuLG2t2LRpU7lltXvj+uuvD2i9w4YNM106nl14r7/+ulmHdpF5235BQYHZvg6t1kyhrUNVpev55z//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DBkyRFq0aCEJCQkyf/78gN+7atUqSUpKkm7dugW7WQAAEKeCDiMFBQXStWtXmT59elDv279/vwwfPlz69esX7CYBAEAcSwr2DYMGDTK3YI0aNUquu+46qVWrVlCtKQAAIL5FpWbkpZdekm+//VYmTZoU0PKFhYWSn59f7gYAAOJTxMPIli1bZPz48fLyyy+bepFATJ06VdLS0spurVu3jvRuAgCAeAwjJSUlpmtmypQp0r59+4DfN2HCBMnLyyu7ZWVlRXI3AQBALNWMBOPAgQOybt06+eyzz+S2224zz5WWlorjOKaV5IMPPpC+ffse876UlBRzAwAA8S+iYSQ1NVW++OKLcs8988wzsmTJEpk7d660a9cukpsHAADxGEYOHjwomZmZZY+3bdsmGzZskEaNGkmbNm1MF8vOnTtl9uzZkpiYKF26dCn3/mbNmkmdOnWOeR4AANRMQYcR7Xbp06dP2eNx48aZ+xEjRsisWbMkOztbduzYEd69BAAAcSvB0QKOak6H9uqoGi1m1a4fAABQ/QV6/ubaNAAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAAYiuMrFixQoYMGSItWrSQhIQEmT9/vt/l33zzTRkwYIA0bdpUUlNTpVevXrJw4cKq7DMAAKjJYaSgoEC6du0q06dPDzi8aBh59913Zf369dKnTx8TZj777LNQ9hcAAMSZBMdxnJDfnJAg8+bNk8svvzyo93Xu3FmGDRsmEydODGj5/Px8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dZj169fPdIlpK5R7O+uss0wdg/szxzuyDh48KFu3bjVTMUT0++3UUK+99poZwTFr1ixn48aNzs033+w0bNjQycnJsb1rcVH5/tlnn5mbfsUef/xx8/P27dvN648++qg51m+99Zbz+eefO0OHDnXatWvnHD582Paux6Rbb73VSUtLc5YtW+ZkZ2eX3Q4dOlS2zKhRo5w2bdo4S5YscdatW+f06tXL3BC88ePHm5FK27ZtM99ffZyQkOB88MEH5nWOdWR5jqZRHO/wuuOOO8y/Jfr9XrVqldO/f3+nSZMmZpReJI93jQ0j6qmnnjIHNTk52Qz1XbNmje1digtLly41IaTibcSIEWXDex944AEnPT3dBMJ+/fo5mzdvtr3bMcvbsdbbSy+9VLaMBr3f/va3ZghqvXr1nCuuuMIEFgTvhhtucE444QTz70bTpk3N99cNIopjHd0wwvEOr2HDhjnNmzc33++WLVuax5mZmRE/3gn6n6o35AAAAISmRtaMAACA6oMwAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAALHp/wHM9iMr9q5V2QAAAABJRU5ErkJggg==", | |
| "text/plain": [ | |
| "<Figure size 640x480 with 1 Axes>" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "ratio = s_rand_svd_np/s_exact_svd_np\n", | |
| "plt.plot(ratio, \"o-\")\n", | |
| "plt.title(\"Ratio of singular values\")\n", | |
| "plt.ylim([0.5, 1.5])\n", | |
| "plt.show()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "3e609e11", | |
| "metadata": {}, | |
| "source": [ | |
| "As we can see from the plots above, the randomized SVD only provides approximate results, and the accuracy decreases with mode number." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "939a0e48", | |
| "metadata": {}, | |
| "source": [ | |
| "Release distributed memory." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "id": "f36e5904", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "client.cancel([u, s, v]) # explicitly release worker memory\n", | |
| "del u, s, v # delete local data" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "2a285ec1", | |
| "metadata": {}, | |
| "source": [ | |
| "## Truncated SVD\n", | |
| "\n", | |
| "Another approach is to use the `TrncatedSVD` with the `tsqr` algorithm, designed for tall-and-skinny matrices, and to request only a reduced number of singular vectors and associated singular values, instead of computing all components as with the exact SVD algorithm." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 9, | |
| "id": "c167d4a7", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "(1038240, 2184)\n", | |
| "(15363, 2184)\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "print(X.shape)\n", | |
| "print(X.chunksize)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 10, | |
| "id": "73710d36", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "trun_svd = TruncatedSVD(n_components=50, algorithm=\"tsqr\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "f18feadb", | |
| "metadata": {}, | |
| "source": [ | |
| "Fit the truncated SVD." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 11, | |
| "id": "cbd7718c", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<style>#sk-container-id-1 {\n", | |
| " /* Definition of color scheme common for light and dark mode */\n", | |
| " --sklearn-color-text: #000;\n", | |
| " --sklearn-color-text-muted: #666;\n", | |
| " --sklearn-color-line: gray;\n", | |
| " /* Definition of color scheme for unfitted estimators */\n", | |
| " --sklearn-color-unfitted-level-0: #fff5e6;\n", | |
| " --sklearn-color-unfitted-level-1: #f6e4d2;\n", | |
| " --sklearn-color-unfitted-level-2: #ffe0b3;\n", | |
| " --sklearn-color-unfitted-level-3: chocolate;\n", | |
| " /* Definition of color scheme for fitted estimators */\n", | |
| " --sklearn-color-fitted-level-0: #f0f8ff;\n", | |
| " --sklearn-color-fitted-level-1: #d4ebff;\n", | |
| " --sklearn-color-fitted-level-2: #b3dbfd;\n", | |
| " --sklearn-color-fitted-level-3: cornflowerblue;\n", | |
| "\n", | |
| " /* Specific color for light theme */\n", | |
| " --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n", | |
| " --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n", | |
| " --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n", | |
| " --sklearn-color-icon: #696969;\n", | |
| "\n", | |
| " @media (prefers-color-scheme: dark) {\n", | |
| " /* Redefinition of color scheme for dark theme */\n", | |
| " --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n", | |
| " --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n", | |
| " --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n", | |
| " --sklearn-color-icon: #878787;\n", | |
| " }\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 {\n", | |
| " color: var(--sklearn-color-text);\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 pre {\n", | |
| " padding: 0;\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 input.sk-hidden--visually {\n", | |
| " border: 0;\n", | |
| " clip: rect(1px 1px 1px 1px);\n", | |
| " clip: rect(1px, 1px, 1px, 1px);\n", | |
| " height: 1px;\n", | |
| " margin: -1px;\n", | |
| " overflow: hidden;\n", | |
| " padding: 0;\n", | |
| " position: absolute;\n", | |
| " width: 1px;\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-dashed-wrapped {\n", | |
| " border: 1px dashed var(--sklearn-color-line);\n", | |
| " margin: 0 0.4em 0.5em 0.4em;\n", | |
| " box-sizing: border-box;\n", | |
| " padding-bottom: 0.4em;\n", | |
| " background-color: var(--sklearn-color-background);\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-container {\n", | |
| " /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n", | |
| " but bootstrap.min.css set `[hidden] { display: none !important; }`\n", | |
| " so we also need the `!important` here to be able to override the\n", | |
| " default hidden behavior on the sphinx rendered scikit-learn.org.\n", | |
| " See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n", | |
| " display: inline-block !important;\n", | |
| " position: relative;\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-text-repr-fallback {\n", | |
| " display: none;\n", | |
| "}\n", | |
| "\n", | |
| "div.sk-parallel-item,\n", | |
| "div.sk-serial,\n", | |
| "div.sk-item {\n", | |
| " /* draw centered vertical line to link estimators */\n", | |
| " background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n", | |
| " background-size: 2px 100%;\n", | |
| " background-repeat: no-repeat;\n", | |
| " background-position: center center;\n", | |
| "}\n", | |
| "\n", | |
| "/* Parallel-specific style estimator block */\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-parallel-item::after {\n", | |
| " content: \"\";\n", | |
| " width: 100%;\n", | |
| " border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n", | |
| " flex-grow: 1;\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-parallel {\n", | |
| " display: flex;\n", | |
| " align-items: stretch;\n", | |
| " justify-content: center;\n", | |
| " background-color: var(--sklearn-color-background);\n", | |
| " position: relative;\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-parallel-item {\n", | |
| " display: flex;\n", | |
| " flex-direction: column;\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n", | |
| " align-self: flex-end;\n", | |
| " width: 50%;\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n", | |
| " align-self: flex-start;\n", | |
| " width: 50%;\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n", | |
| " width: 0;\n", | |
| "}\n", | |
| "\n", | |
| "/* Serial-specific style estimator block */\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-serial {\n", | |
| " display: flex;\n", | |
| " flex-direction: column;\n", | |
| " align-items: center;\n", | |
| " background-color: var(--sklearn-color-background);\n", | |
| " padding-right: 1em;\n", | |
| " padding-left: 1em;\n", | |
| "}\n", | |
| "\n", | |
| "\n", | |
| "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n", | |
| "clickable and can be expanded/collapsed.\n", | |
| "- Pipeline and ColumnTransformer use this feature and define the default style\n", | |
| "- Estimators will overwrite some part of the style using the `sk-estimator` class\n", | |
| "*/\n", | |
| "\n", | |
| "/* Pipeline and ColumnTransformer style (default) */\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-toggleable {\n", | |
| " /* Default theme specific background. It is overwritten whether we have a\n", | |
| " specific estimator or a Pipeline/ColumnTransformer */\n", | |
| " background-color: var(--sklearn-color-background);\n", | |
| "}\n", | |
| "\n", | |
| "/* Toggleable label */\n", | |
| "#sk-container-id-1 label.sk-toggleable__label {\n", | |
| " cursor: pointer;\n", | |
| " display: flex;\n", | |
| " width: 100%;\n", | |
| " margin-bottom: 0;\n", | |
| " padding: 0.5em;\n", | |
| " box-sizing: border-box;\n", | |
| " text-align: center;\n", | |
| " align-items: start;\n", | |
| " justify-content: space-between;\n", | |
| " gap: 0.5em;\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 label.sk-toggleable__label .caption {\n", | |
| " font-size: 0.6rem;\n", | |
| " font-weight: lighter;\n", | |
| " color: var(--sklearn-color-text-muted);\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n", | |
| " /* Arrow on the left of the label */\n", | |
| " content: \"▸\";\n", | |
| " float: left;\n", | |
| " margin-right: 0.25em;\n", | |
| " color: var(--sklearn-color-icon);\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n", | |
| " color: var(--sklearn-color-text);\n", | |
| "}\n", | |
| "\n", | |
| "/* Toggleable content - dropdown */\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-toggleable__content {\n", | |
| " max-height: 0;\n", | |
| " max-width: 0;\n", | |
| " overflow: hidden;\n", | |
| " text-align: left;\n", | |
| " /* unfitted */\n", | |
| " background-color: var(--sklearn-color-unfitted-level-0);\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-toggleable__content.fitted {\n", | |
| " /* fitted */\n", | |
| " background-color: var(--sklearn-color-fitted-level-0);\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-toggleable__content pre {\n", | |
| " margin: 0.2em;\n", | |
| " border-radius: 0.25em;\n", | |
| " color: var(--sklearn-color-text);\n", | |
| " /* unfitted */\n", | |
| " background-color: var(--sklearn-color-unfitted-level-0);\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n", | |
| " /* unfitted */\n", | |
| " background-color: var(--sklearn-color-fitted-level-0);\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n", | |
| " /* Expand drop-down */\n", | |
| " max-height: 200px;\n", | |
| " max-width: 100%;\n", | |
| " overflow: auto;\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n", | |
| " content: \"▾\";\n", | |
| "}\n", | |
| "\n", | |
| "/* Pipeline/ColumnTransformer-specific style */\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n", | |
| " color: var(--sklearn-color-text);\n", | |
| " background-color: var(--sklearn-color-unfitted-level-2);\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n", | |
| " background-color: var(--sklearn-color-fitted-level-2);\n", | |
| "}\n", | |
| "\n", | |
| "/* Estimator-specific style */\n", | |
| "\n", | |
| "/* Colorize estimator box */\n", | |
| "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n", | |
| " /* unfitted */\n", | |
| " background-color: var(--sklearn-color-unfitted-level-2);\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n", | |
| " /* fitted */\n", | |
| " background-color: var(--sklearn-color-fitted-level-2);\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n", | |
| "#sk-container-id-1 div.sk-label label {\n", | |
| " /* The background is the default theme color */\n", | |
| " color: var(--sklearn-color-text-on-default-background);\n", | |
| "}\n", | |
| "\n", | |
| "/* On hover, darken the color of the background */\n", | |
| "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n", | |
| " color: var(--sklearn-color-text);\n", | |
| " background-color: var(--sklearn-color-unfitted-level-2);\n", | |
| "}\n", | |
| "\n", | |
| "/* Label box, darken color on hover, fitted */\n", | |
| "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n", | |
| " color: var(--sklearn-color-text);\n", | |
| " background-color: var(--sklearn-color-fitted-level-2);\n", | |
| "}\n", | |
| "\n", | |
| "/* Estimator label */\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-label label {\n", | |
| " font-family: monospace;\n", | |
| " font-weight: bold;\n", | |
| " display: inline-block;\n", | |
| " line-height: 1.2em;\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-label-container {\n", | |
| " text-align: center;\n", | |
| "}\n", | |
| "\n", | |
| "/* Estimator-specific */\n", | |
| "#sk-container-id-1 div.sk-estimator {\n", | |
| " font-family: monospace;\n", | |
| " border: 1px dotted var(--sklearn-color-border-box);\n", | |
| " border-radius: 0.25em;\n", | |
| " box-sizing: border-box;\n", | |
| " margin-bottom: 0.5em;\n", | |
| " /* unfitted */\n", | |
| " background-color: var(--sklearn-color-unfitted-level-0);\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-estimator.fitted {\n", | |
| " /* fitted */\n", | |
| " background-color: var(--sklearn-color-fitted-level-0);\n", | |
| "}\n", | |
| "\n", | |
| "/* on hover */\n", | |
| "#sk-container-id-1 div.sk-estimator:hover {\n", | |
| " /* unfitted */\n", | |
| " background-color: var(--sklearn-color-unfitted-level-2);\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 div.sk-estimator.fitted:hover {\n", | |
| " /* fitted */\n", | |
| " background-color: var(--sklearn-color-fitted-level-2);\n", | |
| "}\n", | |
| "\n", | |
| "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n", | |
| "\n", | |
| "/* Common style for \"i\" and \"?\" */\n", | |
| "\n", | |
| ".sk-estimator-doc-link,\n", | |
| "a:link.sk-estimator-doc-link,\n", | |
| "a:visited.sk-estimator-doc-link {\n", | |
| " float: right;\n", | |
| " font-size: smaller;\n", | |
| " line-height: 1em;\n", | |
| " font-family: monospace;\n", | |
| " background-color: var(--sklearn-color-background);\n", | |
| " border-radius: 1em;\n", | |
| " height: 1em;\n", | |
| " width: 1em;\n", | |
| " text-decoration: none !important;\n", | |
| " margin-left: 0.5em;\n", | |
| " text-align: center;\n", | |
| " /* unfitted */\n", | |
| " border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n", | |
| " color: var(--sklearn-color-unfitted-level-1);\n", | |
| "}\n", | |
| "\n", | |
| ".sk-estimator-doc-link.fitted,\n", | |
| "a:link.sk-estimator-doc-link.fitted,\n", | |
| "a:visited.sk-estimator-doc-link.fitted {\n", | |
| " /* fitted */\n", | |
| " border: var(--sklearn-color-fitted-level-1) 1pt solid;\n", | |
| " color: var(--sklearn-color-fitted-level-1);\n", | |
| "}\n", | |
| "\n", | |
| "/* On hover */\n", | |
| "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n", | |
| ".sk-estimator-doc-link:hover,\n", | |
| "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n", | |
| ".sk-estimator-doc-link:hover {\n", | |
| " /* unfitted */\n", | |
| " background-color: var(--sklearn-color-unfitted-level-3);\n", | |
| " color: var(--sklearn-color-background);\n", | |
| " text-decoration: none;\n", | |
| "}\n", | |
| "\n", | |
| "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n", | |
| ".sk-estimator-doc-link.fitted:hover,\n", | |
| "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n", | |
| ".sk-estimator-doc-link.fitted:hover {\n", | |
| " /* fitted */\n", | |
| " background-color: var(--sklearn-color-fitted-level-3);\n", | |
| " color: var(--sklearn-color-background);\n", | |
| " text-decoration: none;\n", | |
| "}\n", | |
| "\n", | |
| "/* Span, style for the box shown on hovering the info icon */\n", | |
| ".sk-estimator-doc-link span {\n", | |
| " display: none;\n", | |
| " z-index: 9999;\n", | |
| " position: relative;\n", | |
| " font-weight: normal;\n", | |
| " right: .2ex;\n", | |
| " padding: .5ex;\n", | |
| " margin: .5ex;\n", | |
| " width: min-content;\n", | |
| " min-width: 20ex;\n", | |
| " max-width: 50ex;\n", | |
| " color: var(--sklearn-color-text);\n", | |
| " box-shadow: 2pt 2pt 4pt #999;\n", | |
| " /* unfitted */\n", | |
| " background: var(--sklearn-color-unfitted-level-0);\n", | |
| " border: .5pt solid var(--sklearn-color-unfitted-level-3);\n", | |
| "}\n", | |
| "\n", | |
| ".sk-estimator-doc-link.fitted span {\n", | |
| " /* fitted */\n", | |
| " background: var(--sklearn-color-fitted-level-0);\n", | |
| " border: var(--sklearn-color-fitted-level-3);\n", | |
| "}\n", | |
| "\n", | |
| ".sk-estimator-doc-link:hover span {\n", | |
| " display: block;\n", | |
| "}\n", | |
| "\n", | |
| "/* \"?\"-specific style due to the `<a>` HTML tag */\n", | |
| "\n", | |
| "#sk-container-id-1 a.estimator_doc_link {\n", | |
| " float: right;\n", | |
| " font-size: 1rem;\n", | |
| " line-height: 1em;\n", | |
| " font-family: monospace;\n", | |
| " background-color: var(--sklearn-color-background);\n", | |
| " border-radius: 1rem;\n", | |
| " height: 1rem;\n", | |
| " width: 1rem;\n", | |
| " text-decoration: none;\n", | |
| " /* unfitted */\n", | |
| " color: var(--sklearn-color-unfitted-level-1);\n", | |
| " border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 a.estimator_doc_link.fitted {\n", | |
| " /* fitted */\n", | |
| " border: var(--sklearn-color-fitted-level-1) 1pt solid;\n", | |
| " color: var(--sklearn-color-fitted-level-1);\n", | |
| "}\n", | |
| "\n", | |
| "/* On hover */\n", | |
| "#sk-container-id-1 a.estimator_doc_link:hover {\n", | |
| " /* unfitted */\n", | |
| " background-color: var(--sklearn-color-unfitted-level-3);\n", | |
| " color: var(--sklearn-color-background);\n", | |
| " text-decoration: none;\n", | |
| "}\n", | |
| "\n", | |
| "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n", | |
| " /* fitted */\n", | |
| " background-color: var(--sklearn-color-fitted-level-3);\n", | |
| "}\n", | |
| "</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>TruncatedSVD(n_components=50)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>TruncatedSVD</div></div><div><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\"><pre>TruncatedSVD(n_components=50)</pre></div> </div></div></div></div>" | |
| ], | |
| "text/plain": [ | |
| "TruncatedSVD(n_components=50)" | |
| ] | |
| }, | |
| "execution_count": 11, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "trun_svd.fit(X)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 14, | |
| "id": "c99b69ee", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "v_trun_svd_np = trun_svd.components_\n", | |
| "s_trun_svd_np = trun_svd.singular_values_" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "9b838418", | |
| "metadata": {}, | |
| "source": [ | |
| "Obtain the left singular vectors using the `transform` method." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 15, | |
| "id": "345ec98e", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "u_trun_svd = trun_svd.transform(X)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 16, | |
| "id": "021011ed", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<table>\n", | |
| " <tr>\n", | |
| " <td>\n", | |
| " <table style=\"border-collapse: collapse;\">\n", | |
| " <thead>\n", | |
| " <tr>\n", | |
| " <td> </td>\n", | |
| " <th> Array </th>\n", | |
| " <th> Chunk </th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <th> Bytes </th>\n", | |
| " <td> 198.03 MiB </td>\n", | |
| " <td> 2.93 MiB </td>\n", | |
| " </tr>\n", | |
| " \n", | |
| " <tr>\n", | |
| " <th> Shape </th>\n", | |
| " <td> (1038240, 50) </td>\n", | |
| " <td> (15363, 50) </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th> Dask graph </th>\n", | |
| " <td colspan=\"2\"> 68 chunks in 5 graph layers </td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th> Data type </th>\n", | |
| " <td colspan=\"2\"> float32 numpy.ndarray </td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| " </table>\n", | |
| " </td>\n", | |
| " <td>\n", | |
| " <svg width=\"75\" height=\"170\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n", | |
| "\n", | |
| " <!-- Horizontal lines -->\n", | |
| " <line x1=\"0\" y1=\"0\" x2=\"25\" y2=\"0\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"0\" y1=\"5\" x2=\"25\" y2=\"5\" />\n", | |
| " <line x1=\"0\" y1=\"12\" x2=\"25\" y2=\"12\" />\n", | |
| " <line x1=\"0\" y1=\"17\" x2=\"25\" y2=\"17\" />\n", | |
| " <line x1=\"0\" y1=\"24\" x2=\"25\" y2=\"24\" />\n", | |
| " <line x1=\"0\" y1=\"30\" x2=\"25\" y2=\"30\" />\n", | |
| " <line x1=\"0\" y1=\"37\" x2=\"25\" y2=\"37\" />\n", | |
| " <line x1=\"0\" y1=\"44\" x2=\"25\" y2=\"44\" />\n", | |
| " <line x1=\"0\" y1=\"49\" x2=\"25\" y2=\"49\" />\n", | |
| " <line x1=\"0\" y1=\"56\" x2=\"25\" y2=\"56\" />\n", | |
| " <line x1=\"0\" y1=\"62\" x2=\"25\" y2=\"62\" />\n", | |
| " <line x1=\"0\" y1=\"69\" x2=\"25\" y2=\"69\" />\n", | |
| " <line x1=\"0\" y1=\"74\" x2=\"25\" y2=\"74\" />\n", | |
| " <line x1=\"0\" y1=\"81\" x2=\"25\" y2=\"81\" />\n", | |
| " <line x1=\"0\" y1=\"88\" x2=\"25\" y2=\"88\" />\n", | |
| " <line x1=\"0\" y1=\"94\" x2=\"25\" y2=\"94\" />\n", | |
| " <line x1=\"0\" y1=\"101\" x2=\"25\" y2=\"101\" />\n", | |
| " <line x1=\"0\" y1=\"106\" x2=\"25\" y2=\"106\" />\n", | |
| " <line x1=\"0\" y1=\"113\" x2=\"25\" y2=\"113\" />\n", | |
| " <line x1=\"0\" y1=\"120\" x2=\"25\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Vertical lines -->\n", | |
| " <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| " <line x1=\"25\" y1=\"0\" x2=\"25\" y2=\"120\" style=\"stroke-width:2\" />\n", | |
| "\n", | |
| " <!-- Colored Rectangle -->\n", | |
| " <polygon points=\"0.0,0.0 25.41261651458249,0.0 25.41261651458249,120.0 0.0,120.0\" style=\"fill:#8B4903A0;stroke-width:0\"/>\n", | |
| "\n", | |
| " <!-- Text -->\n", | |
| " <text x=\"12.706308\" y=\"140.000000\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >50</text>\n", | |
| " <text x=\"45.412617\" y=\"60.000000\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,45.412617,60.000000)\">1038240</text>\n", | |
| "</svg>\n", | |
| " </td>\n", | |
| " </tr>\n", | |
| "</table>" | |
| ], | |
| "text/plain": [ | |
| "dask.array<sum-aggregate, shape=(1038240, 50), dtype=float32, chunksize=(15363, 50), chunktype=numpy.ndarray>" | |
| ] | |
| }, | |
| "execution_count": 16, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "u_trun_svd" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "1ba6e63f", | |
| "metadata": {}, | |
| "source": [ | |
| "Note that these are scaled by the singular values, so they don't have unit norm." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 25, | |
| "id": "ffd2cd56", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/plain": [ | |
| "np.float32(12076215.0)" | |
| ] | |
| }, | |
| "execution_count": 25, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "u_trun_svd_np = u_trun_svd.compute()\n", | |
| "np.linalg.norm(u_trun_svd_np[:, 0])" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "8055990f", | |
| "metadata": {}, | |
| "source": [ | |
| "Make sure the left singular vectors have unit norm." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 26, | |
| "id": "96da6d87", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/plain": [ | |
| "np.float32(1.0000005)" | |
| ] | |
| }, | |
| "execution_count": 26, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "u_trun_svd_np = u_trun_svd_np/s_trun_svd_np\n", | |
| "np.linalg.norm(u_trun_svd_np[:, 0])" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "7fc89c52", | |
| "metadata": {}, | |
| "source": [ | |
| "Now compare the singular vectors and singular values obtained through truncated SVD to those obtained through the exact SVD." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 34, | |
| "id": "bed89a87", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "dot_product = u_exact_svd_np.T @ u_trun_svd_np" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 35, | |
| "id": "91cae3a4", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "image/png": "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", | |
| "text/plain": [ | |
| "<Figure size 640x480 with 2 Axes>" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "plt.imshow(dot_product, cmap=\"bwr\", interpolation=\"nearest\", vmin=-1, vmax=1)\n", | |
| "plt.colorbar(label='Dot Product Value')\n", | |
| "plt.title(\"Left singular vectors\")\n", | |
| "plt.show()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 36, | |
| "id": "ad56c83c", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "dot_product = v_exact_svd_np @ v_trun_svd_np.T" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 37, | |
| "id": "3bc3df21", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhMAAAGzCAYAAACVV5VXAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAATW5JREFUeJzt3QmcE+X5wPFnuQ+F5VxAubEcAmJBDrUeQEGkCl4Vi3KUo0VQThVUDkVF1KKiKGoFpYIoKCjWoshlVUCO4oFIxaKgsAsUd7nk3Pw/z2uTf7KbTbIzmc1M8vt+PiPuZGYymWQzzz7v+7xvms/n8wkAAIBFxazuCAAAoAgmAACALQQTAADAFoIJAABgC8EEAACwhWACAADYQjABAABsIZgAAAC2EEwAAABbCCZgy2WXXWYWq/s2b95cEqFfv35Sr149cYtJkyZJWlpaok8DACwhmECIl156ydzU/EuJEiXkrLPOMjffH3/8MSHntHv3bnOz3bx5c0KeH/Z98skn5j3Mzs5O9KkAcEAJJw4K77v//vulfv36cuzYMVm7dq0JMj766CP58ssvpUyZMoHt3n///SIJJu677z6TSWjVqlVcjvnCCy9Ibm5uXI6F2IIJfQ81KE1PT0/06QCIM4IJhNWtWzdp06aN+f+BAwdK1apVZerUqfL222/L73//+8B2pUqVEi8qWbKkJCudu0+DwLJly0oyS5XXCXgBzRyIyW9+8xvz77fffhu1z8T3338vV199tZQvX16qV68uI0eOlPfee880m6xatSrfsb/66iu5/PLLpVy5cqZJ5ZFHHgk8pttfcMEF5v/79+8faH7RTElBDh06JCNGjDCZjNKlS5tz+O1vfyubNm0qsM/Ed999Z4772GOPyfPPPy8NGzY0++pzr1+/Pt9zLFiwQJo1a2ayNNrvY9GiRfmOqece7jX7nyvSa1CzZ8+Wjh07mvPXc9Hne/bZZ/Ntp8/5u9/9zlxjDQD15vrcc8+FPeawYcPkjDPOkKNHj+Z77KabbpIaNWrI6dOnA+v+8Y9/mPde38szzzxTunfvLlu2bMm379dff22CzGrVqpnnb9y4sdxzzz3mMW3euOOOO8z/a7bL/x7qdVCnTp2SyZMnB665vp67775bjh8/HvPrXLZsmVx88cUm66GvT59fjwGgaJCZQEz8X/yVKlWKuN2RI0fMDXDPnj0yfPhwc3OaN2+erFy5Muz2P/30k1xxxRVy7bXXmpvRwoUL5a677pIWLVqY7EjTpk1Nk8uECRNk8ODBgaDmwgsvLPAc/vznP5vj6I1Tb8D//e9/TRPN1q1b5de//nXE89dz1WDkT3/6k7nhaWCj5/af//wnkM34+9//LjfeeKM5xylTppjXMGDAABMIxZMGDueee64JzLTvypIlS+TWW281zTNDhw4N2Xbbtm0mGNDzHjRokLmZhqPnPWPGDPMabrjhhsB6DS70+BoQFS9e3Kz729/+Jn379pWuXbuarJRuo+ekN+1//etfgcDp888/N++LXh99j3S9Bp16vAcffNBcv3//+9/y6quvyuOPP26yXEoDD3/m6+WXX5brr79eRo8eLevWrTPXVd8vDdKivU4NbjTIaNmypfmsaECyfft2+fjjj+P6fgCIwAcEmT17tk8/Fh988IFv3759vl27dvkWLlzoq1atmq906dLm52CXXnqpWfz+8pe/mP0XL14cWPfzzz/7mjRpYtavXLkyZF9dN2fOnMC648eP+2rUqOG77rrrAuvWr19vttNzi0XFihV9Q4cOjbhN3759fXXr1g38vGPHDvMcVapU8R04cCCw/q233jLrlyxZEljXokUL39lnn+07dOhQYN2qVavMdsHH1Nea9zUHP1fw65k4caJZF+zo0aP5zrtr166+Bg0ahKzT59R9ly5d6osmNzfXd9ZZZ4VcX/X666+bY3z44YfmZ31t6enpvkGDBoVsl5mZaa5v8PpLLrnEd+aZZ/q+//77fM/l9+ijj5rj62sPtnnzZrN+4MCBIevHjBlj1q9YsSLq63z88cfNev28AkgMmjkQVufOnc1fjrVr1zZ/MWqaW/tLnH322RH3W7p0qfkLXf+a9tOmAP0rMhxNSd98880hfTDatm1rMgFWaapb/7rVjpuFpX+5B2df/JkQ//noMb/44gvp06ePOXe/Sy+91GQq4im4L0BOTo7s37/fPI+ei/4cTJsPNIMQjWZbNCPx7rvvyuHDhwPrX3vtNfO+adbB32yglReaBdDn9S+atWjXrl0g07Rv3z758MMP5Y9//KPUqVMn33NFo+ehRo0aFbJeMxRKMyjRXqe/Q+dbb71Fp1ogQQgmEJamwvWGos0FV155pbmRaPo4Gu0voW3feW8kjRo1Cru9Bid5t9WbuTYdWKVN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", | |
| "text/plain": [ | |
| "<Figure size 640x480 with 2 Axes>" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "plt.imshow(dot_product, cmap=\"bwr\", interpolation=\"nearest\", vmin=-1, vmax=1)\n", | |
| "plt.colorbar(label='Dot Product Value')\n", | |
| "plt.title(\"Right singular vectors\")\n", | |
| "plt.show()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 38, | |
| "id": "2eadbb80", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGzCAYAAAD9pBdvAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAJZxJREFUeJzt3QucVnWdP/DfAHIxBUPkpqB0UUsSDS+RlmtiZC5/zXbV3BbSrDQsFSuhVGRLsbV1NcW8tZLbyxuuWnk30FhdFEXdvCdJwhIXqbiqoHD+r+/ZntkZGGAGZ+Y3l/f79Toyz3nOOc/v/J7HOZ/ndzlTVRRFkQAAMumQ64UBAIIwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACzez8889PVVVVWV77iSeeSB//+MfTe97znrIMzzzzTKs8j7pMmTKlLM8f/vCH1Nq0tLqE5iaM0O5VLmKVpVOnTmnnnXdOX/rSl9KCBQu26phvvPFGeYF5+OGHU0vx9ttvp7//+79Pf/7zn9O//uu/pn//939Pu+66a+5iAaROuQsALcU//dM/pUGDBqW33norPfbYY2VIeeSRR9Jzzz2Xunbt2uAwMnHixPLnv/mbv6n13DnnnJPGjRuXmtvvf//79Nprr6Vrr702nXzyye/6eLnOA2h7hBH4qyOOOCLtt99+5c9xse7Vq1f64Q9/mH75y1+mY489ttFeJ1peYmluS5YsKf/dYYcdWvV5NJcIlNtuu23uYkC7oJsGNuETn/hEdYtCxdq1a9N5552Xhg4dmnr06FGOvYjtHnrooeptYszCTjvtVP4crSOV7p/ottnU+IB33nknff/730/vf//7U5cuXdJuu+2Wvvvd76Y1a9bUq6zTp08vyxHlibBx1FFHpRdffLH6+ehyOuSQQ8qfo6smXn/DFpsNu3Si7B/84AfLVqEdd9wxHXzwwenBBx+s3qau84jHp512WrrzzjvT4MGDy3PZa6+90n333bfRa0QXVoS/OH6c99VXX73RMaMu43G0Um2oZp1uyi9+8Yt05JFHpv79+5dlideJel63bl2t7aIuoryzZ89On/zkJ8sQEvVflx/96Efla0cr04bGjx+fOnfunP7yl7+Uj//zP/+zrO+BAweWrz9gwIB05plnpjfffHOz5W7oeUd34kknnZT69OlTXef/9m//ttG+l19+eflcnN973/vesv5vvPHGzZYFmkPb/VoD71JlIGT80q5YsWJFuu6669IXvvCF9JWvfCWtXLky/fSnP00jRoxIs2bNSvvss08ZRH7yk5+kU089NX3uc59LxxxzTLnv3nvvvcnXipaYn/3sZ+nv/u7v0llnnZUef/zxNGnSpDJQ3HHHHZst569//euyVed973tfeZGKC11cdA466KD01FNPlcHma1/7WjkO5sILL0zf/OY30/77719euDYljhOvH+U64IADyvN+8skny+Mdfvjhmy1PdG3dfvvt6etf/3rafvvt049//OP0+c9/Ps2bN68MNeHpp59On/nMZ1K/fv3K0BPhILrJKiGuscTFfLvttktjx44t/43QFmEyzufiiy+ute2f/vSnsh6PP/749MUvfnGT9ROtZN/5znfSrbfemr797W/Xei7WffrTn67+zEydOrVsYYnPQpx7fEbivfmf//mf8rnGsHjx4vSxj32sOghGHd57773py1/+cnmeZ5xxRrlddM/Fex+fsdNPP73sjvztb39bftZOOOGERikLbLUC2rnrr7++iP8Vfv3rXxevv/56MX/+/OK2224rdtppp6JLly7l44p33nmnWLNmTa39//KXvxR9+vQpTjrppOp1cZw45oQJEzZ6vVhX83+9Z555pnx88skn19ruW9/6Vrl++vTpmy3/PvvsU/Tu3bv405/+VL3uv//7v4sOHToUo0aNql730EMPlcebOnXqFutkyJAhxZFHHrnZbTY8jxCPO3fuXMyZM6dWWWL95ZdfXr1u5MiRxbbbblssWLCget0rr7xSdOrUqdYx586dWz6O92hDG9Zv5X2MfSreeOONjfb72te+Vr72W2+9Vb3ukEMOKfe96qqrivoYNmxYMXTo0FrrZs2aVR7jhhtu2OzrT5o0qaiqqipee+21TdZlQ877y1/+ctGvX79i6dKltbY7/vjjix49elSX4aijjir22muvep0fNDfdNPBXw4cPL79VRlN6fHuMLo8YL7LLLrtUb9OxY8eyGT6sX7++nJkSXSzR3B2tBlvjnnvuKf+Nb+81RQtJuPvuuze578KFC8vpudEN07Nnz+r10QoTLRiVYzdUdPU8//zz6ZVXXtmqeozukJpl6d69e3r11VfLx9EKEq05Rx99dNl9UvGBD3ygbJloTN26dav+OVqx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EQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAWlcYmTFjRho5cmTq379/qqqqSnfeeWe993300UdTp06d0j777NPQlwUA2qgGh5HVq1enIUOGpMmTJzdov2XLlqVRo0alww47rKEvCQC0YZ0ausMRRxxRLg11yimnpBNOOCF17NixQa0pAEDb1ixjRq6//vr06quvpgkTJtRr+zVr1qQVK1bUWgCAtqnJw8grr7ySxo0bl37+85+X40XqY9KkSalHjx7Vy4ABA5q6mABAWwwj69atK7tmJk6cmHbfffd67zd+/Pi0fPny6mX+/PlNWUwAoDWNGWmIlStXpieffDI9/fTT6bTTTivXrV+/PhVFUbaSPPDAA+lTn/rURvt16dKlXACAtq9Jw0j37t3Ts88+W2vdlVdemaZPn55uu+22NGjQoKZ8eQCgLYaRVatWpTlz5lQ/njt3bnrmmWdSz54908CBA8sulgULFqQbbrghdejQIQ0ePLjW/r17905du3bdaD0A0D41OIxEt8uhhx5a/Xjs2LHlv6NHj05TpkxJCxcuTPPmzWvcUgIAbVZVEQM4WriY2huzamIwa3T9AAAtX32v3/42DQCQlTACAGQljAAAWQkjAEBWwggAkJUwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACAGQljAAAWQkjAEBWwggAkJUwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACAGQljAAAWQkjAEBWwggAkJUwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACAGQljAAAWQkjAEBWwggAkJUwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACAGQljAAAWQkjAEBWwggAkJUwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACAGQljAAArSuMzJgxI40cOTL1798/VVVVpTvvvHOz299+++3p8MMPTzvttFPq3r17GjZsWLr//vvfTZkBgPYcRlavXp2GDBmSJk+eXO/wEmHknnvuSbNnz06HHnpoGWaefvrprSkvANDGVBVFUWz1zlVV6Y477khHH310g/bba6+90nHHHZfOO++8em2/YsWK1KNHj7R8+fKydQUAaPnqe/3u1KylSimtX78+rVy5MvXs2XOT26xZs6Zcap4MANA2NfsA1h/96Edp1apV6dhjj93kNpMmTSqTVGUZMGBAs5YRAGijYeTGG29MEydOTLfeemvq3bv3JrcbP3582aRTWebPn9+cxQQAmlGzddPcfPPN6eSTT05Tp05Nw4cP3+y2Xbp0KRcAoO1rlpaRm266KZ144onlv0ceeWRzvCQA0FZbRmK8x5w5c6ofz507Nz3zzDPlgNSBAweWXSwLFixIN9xwQ3XXzOjRo9Nll12WDjzwwLRo0aJyfbdu3crxIABA+9bglpEnn3wy7bvvvuUSxo4dW/5cmaa7cOHCNG/evOrtr7nmmvTOO++kMWPGpH79+lUvp59+emOeBwDQHu8z0lzcZwQAWp/6Xr/9bRoAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAIKtOqZ1at75Is+b+OS1Z+VbqvX3XdMCgnqljh6oGb9OYx2rObVpimVpruVtimZS75W3TEsuk3C1vm5ZapqbWLsPIfc8tTBN/9UJauPyt6nX9enRNE0Z+OH1mcL96b9OYx2rObVpimVpruVtimZS75W3TEsuk3C1vm5ZapuZQVRRF0ZAdZsyYkS6++OI0e/bstHDhwnTHHXeko48+erP7PPzww2ns2LHp+eefTwMGDEjnnHNO+tKXvlTv11yxYkXq0aNHWr58eerevXt6N6LyT/35U2nDk67kwJ988aPlv1vaJt6oxjpWc26j3G27TMqt3Mqt3I1ZpnervtfvBoeRe++9Nz366KNp6NCh6ZhjjtliGJk7d24aPHhwOuWUU9LJJ5+cpk2bls4444x09913pxEjRjTqyWxJNEcd/MPptVLghm9C7+27lD8sXrFmk9v06d413XfGJ9KIS2dsdrv6HKs5t1Hutl0m5VZu5Vbu3o20Td8eXdMjZ3/qXXfZNFkYqbVzVdUWw8jZZ59dBo/nnnuuet3xxx+fli1blu67774691mzZk251DyZaFF5t2Fk5u//lL5w7WNbvT8AtBc3feVjadj7d2yWMNLks2lmzpyZhg8fXmtdtIjE+k2ZNGlSWfjKEkGkMcQAHQCgZV0zmzyMLFq0KPXp06fWungcaenNN9+sc5/x48eXKaqyzJ8/v1HKEiOFG8vZn9kjtUbK3bbLVB/K3byUu3kpd+NpzGtmq7zPSJcuXcrmnJpLY4gpSzFSeFM9YGU/WfcuqW/3zW8Tx/jywe9rlGM15zbK3bbLpNzKrdzK3bcRyxTXzDYTRvr27ZsWL15ca108joDRrVu31JxiIE5MWQobvgmVx+f/v73S+f9v89vEMTp36tAox2rObZS7bZdJuZVbuZX7/EYsU3Peb6TJw8iwYcPKGTQ1Pfjgg+X6HGKqUkxZipHCNcXjylSm+mzTmMdqzm2Uu22XSbmVW7mV+zONWKbm0uDZNKtWrUpz5swpf953333TJZdckg499NDUs2fPNHDgwHK8x4IFC9INN9xQa2rvmDFj0kknnZSmT5+evvnNb2aZ2tte7pan3Mqk3C1vm5ZYJuVuedu01DK1uKm9cQOzCB8bGj16dJoyZUp5M7M//OEP5XY19znzzDPTCy+8kHbZZZd07rnnZrvpGQDQPJrlPiPNRRgBgNanxdxnBABgc4QRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAaH1hZPLkyWm33XZLXbt2TQceeGCaNWvWZre/9NJL0x577JG6deuWBgwYkM4888z01ltvbW2ZAYD2HEZuueWWNHbs2DRhwoT01FNPpSFDhqQRI0akJUuW1Ln9jTfemMaNG1du/+KLL6af/vSn5TG++93vNkb5AYBWrqooiqIhO0RLyP7775+uuOKK8vH69evL1o5vfOMbZejY0GmnnVaGkGnTplWvO+uss9Ljjz+eHnnkkTpfY82aNeVSsWLFivI1li9fnrp3796Q4gIAmcT1u0ePHlu8fjeoZWTt2rVp9uzZafjw4f93gA4dysczZ86sc5+Pf/zj5T6VrpxXX3013XPPPemzn/3sJl9n0qRJZeErSwQRAKBt6tSQjZcuXZrWrVuX+vTpU2t9PH7ppZfq3OeEE04o9zv44INTNMK888476ZRTTtlsN8348ePLrqANW0YAgLanyWfTPPzww+nCCy9MV155ZTnG5Pbbb0933313+v73v7/Jfbp06VI259RcAIC2qUEtI7169UodO3ZMixcvrrU+Hvft27fOfc4999z0j//4j+nkk08uH3/kIx9Jq1evTl/96lfT9773vbKbBwBovxqUBDp37pyGDh1aazBqDGCNx8OGDatznzfeeGOjwBGBJjRw7CwA0N5bRkKM5Rg9enTab7/90gEHHFDeQyRaOk488cTy+VGjRqWdd965HIQaRo4cmS655JK07777ljNx5syZU7aWxPpKKAEA2q8Gh5Hjjjsuvf766+m8885LixYtSvvss0+67777qge1zps3r1ZLyDnnnJOqqqrKfxcsWJB22mmnMohccMEFjXsmAED7uM9IS56nDAC08fuMAAA0NmEEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQCyEkYAgKyEEQAgK2EEAGh9YWTy5Mlpt912S127dk0HHnhgmjVr1ma3X7ZsWRozZkzq169f6tKlS9p9993TPffcs7VlBgDakE4N3eGWW25JY8eOTVdddVUZRC699NI0YsSI9PLLL6fevXtvtP3atWvT4YcfXj532223pZ133jm99tpraYcddmiscwAAWrGqoiiKhuwQAWT//fdPV1xxRfl4/fr1acCAAekb3/hGGjdu3EbbR2i5+OKL00svvZS22WabrSrkihUrUo8ePdLy5ctT9+7dt+oYAEDzqu/1u0HdNNHKMXv27DR8+PD/O0CHDuXjmTNn1rnPL3/5yzRs2LCym6ZPnz5p8ODB6cILL0zr1q3b5OusWbOmPIGaCwDQNjUojCxdurQMEREqaorHixYtqnOfV199teyeif1inMi5556b/uVf/iX94Ac/2OTrTJo0qUxSlSVaXgCAtqnJZ9NEN06MF7nmmmvS0KFD03HHHZe+973vld03mzJ+/PiySaeyzJ8/v6mLCQC0hgGsvXr1Sh07dkyLFy+utT4e9+3bt859YgZNjBWJ/So+9KEPlS0p0e3TuXPnjfaJGTexAABtX4NaRiI4ROvGtGnTarV8xOMYF1KXgw46KM2ZM6fcruJ3v/tdGVLqCiIAQPvS4G6amNZ77bXXpp/97GfpxRdfTKeeempavXp1OvHEE8vnR40aVXazVMTzf/7zn9Ppp59ehpC77767HMAaA1oBABp8n5EY8/H666+n8847r+xq2WeffdJ9991XPah13rx55Qybihh8ev/996czzzwz7b333uV9RiKYnH322Y17JgBA+7jPSA7uMwIArU+T3GcEAKCxCSMAQFbCCACQlTACAGQljAAAWQkjAEBWwggAkJUwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACAGQljAAAWQkjAEBWwggAkJUwAgBkJYwAAFkJIwBAVsIIAJCVMAIAZCWMAABZCSMAQFbCCACQlTACAGQljAAAWXVKrUBRFOW/K1asyF0UAKCeKtftynW8VYeRlStXlv8OGDAgd1EAgK24jvfo0WOTz1cVW4orLcD69evTH//4x7T99tunqqqqRk1sEXDmz5+funfv3mjHpW7qu3mp7+alvpuX+m4d9R0RI4JI//79U4cOHVp3y0icwC677NJkx4+K9WFuPuq7eanv5qW+m5f6bvn1vbkWkQoDWAGArIQRACCrdh1GunTpkiZMmFD+S9NT381LfTcv9d281Hfbqu9WMYAVAGi72nXLCACQnzACAGQljAAAWQkjAEBWwggAkFW7DiOTJ09Ou+22W+ratWs68MAD06xZs3IXqU2YMWNGGjlyZHn737h9/5133lnr+ZjAdd5556V+/fqlbt26peHDh6dXXnklW3lbu0mTJqX999+//HMJvXv3TkcffXR6+eWXa23z1ltvpTFjxqQdd9wxbbfddunzn/98Wrx4cbYyt2Y/+clP0t577119J8phw4ale++9t/p5dd10LrroovJ3yhlnnFG9Tn03rvPPP7+s45rLnnvu2eT13W7DyC233JLGjh1bzpt+6qmn0pAhQ9KIESPSkiVLchet1Vu9enVZnxH26vLP//zP6cc//nG66qqr0uOPP57e8573lHUfH3Ia7je/+U35y+Gxxx5LDz74YHr77bfTpz/96fJ9qDjzzDPTr371qzR16tRy+/hbT8ccc0zWcrdW8acp4qI4e/bs9OSTT6ZPfepT6aijjkrPP/98+by6bhpPPPFEuvrqq8sgWJP6bnx77bVXWrhwYfXyyCOPNH19F+3UAQccUIwZM6b68bp164r+/fsXkyZNylqutiY+YnfccUf14/Xr1xd9+/YtLr744up1y5YtK7p06VLcdNNNmUrZtixZsqSs99/85jfV9bvNNtsUU6dOrd7mxRdfLLeZOXNmxpK2He9973uL6667Tl03kZUrVxYf/OAHiwcffLA45JBDitNPP71cr74b34QJE4ohQ4bU+VxT1ne7bBlZu3Zt+a0mugdq/jG+eDxz5sysZWvr5s6dmxYtWlSr7uOPKEU3mbpvHMuXLy//7dmzZ/lvfNajtaRmnUez68CBA9X5u7Ru3bp08803l61Q0V2jrptGtPwdeeSRteo1qO+mEd3m0c3+vve9L/3DP/xDmjdvXpPXd6v4q72NbenSpeUvkT59+tRaH49feumlbOVqDyKIhLrqvvIcW2/9+vVlf/pBBx2UBg8eXK6Leu3cuXPaYYcdam2rzrfes88+W4aP6FqMfvM77rgjffjDH07PPPOMum5kEfaiKz26aTbks9344ovhlClT0h577FF20UycODF94hOfSM8991yT1ne7DCPQlr9Bxi+Nmn28NL74RR3BI1qhbrvttjR69Oiy/5zGNX/+/HT66aeXY6FiogFN74gjjqj+OcbnRDjZdddd06233lpOOGgq7bKbplevXqljx44bjQCOx3379s1WrvagUr/qvvGddtpp6a677koPPfRQOciyIuo1uiaXLVtWa3t1vvXi2+EHPvCBNHTo0HI2UwzYvuyyy9R1I4tugZhU8NGPfjR16tSpXCL0xQD4+Dm+kavvphWtILvvvnuaM2dOk36+O7TXXyTxS2TatGm1mrfjcTS90nQGDRpUfmhr1v2KFSvKWTXqfuvEOOEIItFVMH369LKOa4rP+jbbbFOrzmPqb/QDq/PGEb8/1qxZo64b2WGHHVZ2iUUrVGXZb7/9ynEMlZ/Vd9NatWpV+v3vf1/eiqFJP99FO3XzzTeXMzimTJlSvPDCC8VXv/rVYocddigWLVqUu2htYuT7008/XS7xEbvkkkvKn1977bXy+Ysuuqis61/84hfFb3/72+Koo44qBg0aVLz55pu5i94qnXrqqUWPHj2Khx9+uFi4cGH18sYbb1Rvc8oppxQDBw4spk+fXjz55JPFsGHDyoWGGzduXDlTae7cueXnNx5XVVUVDzzwQPm8um5aNWfTBPXduM4666zyd0l8vh999NFi+PDhRa9evcpZek1Z3+02jITLL7+8rNTOnTuXU30fe+yx3EVqEx566KEyhGy4jB49unp677nnnlv06dOnDISHHXZY8fLLL+cudqtVV13Hcv3111dvE0Hv61//ejkFddttty0+97nPlYGFhjvppJOKXXfdtfy9sdNOO5Wf30oQCeq6ecOI+m5cxx13XNGvX7/y873zzjuXj+fMmdPk9V0V/3n3DTkAAFunXY4ZAQBaDmEEAMhKGAEAshJGAICshBEAICthBADIShgBALISRgCArIQRACArYQQAyEoYAQBSTv8flOvT3Je4qaUAAAAASUVORK5CYII=", | |
| "text/plain": [ | |
| "<Figure size 640x480 with 1 Axes>" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "ratio = s_exact_svd_np/s_trun_svd_np\n", | |
| "plt.plot(ratio, \"o-\")\n", | |
| "plt.title(\"Ratio of singular values\")\n", | |
| "plt.ylim([0.5, 1.5])\n", | |
| "plt.show()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "2a576786", | |
| "metadata": {}, | |
| "source": [ | |
| "Close the cluster." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 3, | |
| "id": "08679c66", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "client.cluster.close()\n", | |
| "client.close()" | |
| ] | |
| } | |
| ], | |
| "metadata": { | |
| "kernelspec": { | |
| "display_name": ".venv_dask", | |
| "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.10.14" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 5 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment