{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Numpy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[![colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/davemlz/spyndex/blob/main/docs/tutorials/numpy.ipynb)\n", "![level2](https://raw.githubusercontent.com/davemlz/spyndex/main/docs/_static/level2.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Welcome to the second level: `spyndex + numpy`!\n", "\n", "Remember to install `spyndex`!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!pip install -U spyndex" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, let's start!\n", "\n", "First, import `spyndex` and `numpy`:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import spyndex\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `numpy.int*`\n", "\n", "We all know the amazing world of `numpy`, right? Let's simulate some `integer` values!" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "NIR = np.int16(6578)\n", "RED = np.int16(1435)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we check the data types for each one of our variables, we will see that they are `numpy.int16`:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "NIR type: \n", "RED type: \n" ] } ], "source": [ "print(f\"NIR type: {type(NIR)}\")\n", "print(f\"RED type: {type(RED)}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And let's check what we need to compute the `DVI`:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DVI: Difference Vegetation Index (attributes = ['bands', 'contributor', 'date_of_addition', 'formula', 'long_name', 'reference', 'short_name', 'type'])" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spyndex.indices.DVI" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's see the standard names for the bands:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('N', 'R')" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spyndex.indices.DVI.bands" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With this we can create our `dict`!" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "parameters = {\"N\": NIR, \"R\": RED}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, let's compute the index!" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "idx = spyndex.computeIndex(\"DVI\",parameters)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we check the type of the result, we'll see that it is also a `numpy.int16`!" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "idx type: \n" ] } ], "source": [ "print(f\"idx type: {type(idx)}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And the value of the index:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5143" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "idx" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That's great! Now, let's exagerate a little bit... Imagine we have, for some reason, very big values and we need a different data type: `numpy.int64`\n", "\n", "> Note that using this kind of data type is not recommended for most spectral indices!" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "NIR = np.int64(657812517257537)\n", "RED = np.int64(143532873927932)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we check the types:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "NIR type: \n", "RED type: \n" ] } ], "source": [ "print(f\"NIR type: {type(NIR)}\")\n", "print(f\"RED type: {type(RED)}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And if we compute the `DVI`:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [], "source": [ "idx = spyndex.computeIndex(\"DVI\",{\"N\": NIR, \"R\": RED})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll see that the data type of the result is now `numpy.int64`!" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "idx type: \n" ] } ], "source": [ "print(f\"idx type: {type(idx)}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here the resulting index:" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "514279643329605" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "idx" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `numpy.float*`\n", "\n", "Now, let's do things as they are supposed to be: Using `floats`!" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "NIR = np.float32(0.63241)\n", "RED = np.float32(0.13641)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we check the data types, we'll see the `numpy.float32`:" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "NIR type: \n", "RED type: \n" ] } ], "source": [ "print(f\"NIR type: {type(NIR)}\")\n", "print(f\"RED type: {type(RED)}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, let's compute the `DVI` again:" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [], "source": [ "idx = spyndex.computeIndex(\"DVI\",{\"N\": NIR, \"R\": RED})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And the result is a beautiful `numpy.float32`!" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "idx type: \n" ] } ], "source": [ "print(f\"idx type: {type(idx)}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here our `DVI` value:" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.496" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "idx" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If required, different `float` datatypes, such as `numpy.float64`, can be used too!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `numpy.ndarray`\n", "\n", "Let's get spicy! We are going to work with the main data type of `numpy`: `arrays`.\n", "\n", "Let's simulate some arrays for the visible spectrum!" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "BLUE = np.random.normal(0.13,0.05,1000)\n", "GREEN = np.random.normal(0.23,0.06,1000)\n", "RED = np.random.normal(0.14,0.07,1000)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we check the data types for each one of our variables, we will see that they are `numpy.ndarray`:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "BLUE type: , shape: (1000,)\n", "GREEN type: , shape: (1000,)\n", "RED type: , shape: (1000,)\n" ] } ], "source": [ "print(f\"BLUE type: {type(BLUE)}, shape: {BLUE.shape}\")\n", "print(f\"GREEN type: {type(GREEN)}, shape: {GREEN.shape}\")\n", "print(f\"RED type: {type(RED)}, shape: {RED.shape}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Amazing! Let's compute some spectral indices with the visible spectrum: `GLI` and `VARI`!" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "GLI: Green Leaf Index (attributes = ['bands', 'contributor', 'date_of_addition', 'formula', 'long_name', 'reference', 'short_name', 'type'])" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spyndex.indices.GLI" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "VARI: Visible Atmospherically Resistant Index (attributes = ['bands', 'contributor', 'date_of_addition', 'formula', 'long_name', 'reference', 'short_name', 'type'])" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spyndex.indices.VARI" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's check the standard names!" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('G', 'R', 'B')" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spyndex.indices.GLI.bands" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('G', 'R', 'B')" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spyndex.indices.VARI.bands" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since both use the visible spectrum, we just need to create a `dict` with the `B`, `G` and `R` parameters!" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "parameters = {\"B\": BLUE, \"G\": GREEN, \"R\": RED}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we just have to compute the indices! It can be easily done with `spyndex.computeIndex()`:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "idx = spyndex.computeIndex([\"GLI\",\"VARI\"], parameters)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's check our result!" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "idx type: , shape: (2, 1000)\n" ] } ], "source": [ "print(f\"idx type: {type(idx)}, shape: {idx.shape}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Yes! It is a `numpy.ndarray`! And check the shape of it: `(2, 1000)`, why is that? Well, our initial shapes were `(1000, )` and `(1000, )`, and `spyndex` concatenates the resulting indices along the first axis, so, since we computed 2 indices, the result has the shape `(2, 1000)`. Let's try other shapes!" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "BLUE = np.random.normal(0.13,0.05,(100,100,100))\n", "GREEN = np.random.normal(0.23,0.06,(100,100,100))\n", "RED = np.random.normal(0.14,0.07,(100,100,100))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have created 3 cubes of spectral data! Let's confirm it:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "BLUE type: , shape: (100, 100, 100)\n", "GREEN type: , shape: (100, 100, 100)\n", "RED type: , shape: (100, 100, 100)\n" ] } ], "source": [ "print(f\"BLUE type: {type(BLUE)}, shape: {BLUE.shape}\")\n", "print(f\"GREEN type: {type(GREEN)}, shape: {GREEN.shape}\")\n", "print(f\"RED type: {type(RED)}, shape: {RED.shape}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Nice! Now we can define our parameters!" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "parameters = {\"B\": BLUE, \"G\": GREEN, \"R\": RED}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And let's compute the indices again!" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "idx = spyndex.computeIndex([\"GLI\",\"VARI\"], parameters)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What shape has the result?..." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "idx type: , shape: (2, 100, 100, 100)\n" ] } ], "source": [ "print(f\"idx type: {type(idx)}, shape: {idx.shape}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That's right! Now we have two cubes! `(2, 100, 100, 100)`, one for the `GLI` and another one for the `VARI`!\n", "\n", "Everything is beautiful, and so are shapes... pay attention! if your shapes are not equal, you're going to be in trouble!" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "BLUE = np.random.normal(0.13,0.05,(200,100,100))\n", "GREEN = np.random.normal(0.23,0.06,(100,300,100))\n", "RED = np.random.normal(0.14,0.07,(100,100,400))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What kind of monster creates these cubes with different shapes?" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "BLUE type: , shape: (200, 100, 100)\n", "GREEN type: , shape: (100, 300, 100)\n", "RED type: , shape: (100, 100, 400)\n" ] } ], "source": [ "print(f\"BLUE type: {type(BLUE)}, shape: {BLUE.shape}\")\n", "print(f\"GREEN type: {type(GREEN)}, shape: {GREEN.shape}\")\n", "print(f\"RED type: {type(RED)}, shape: {RED.shape}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Be careful!" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "parameters = {\"B\": BLUE, \"G\": GREEN, \"R\": RED}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Oh God, I'm scared..." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "ename": "ValueError", "evalue": "operands could not be broadcast together with shapes (100,300,100) (100,100,400) ", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/tmp/ipykernel_11829/2841937182.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0midx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mspyndex\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcomputeIndex\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"GLI\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\"VARI\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparameters\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/gh/spyndex/spyndex/spyndex.py\u001b[0m in \u001b[0;36mcomputeIndex\u001b[0;34m(index, params, online, returnOrigin, coordinate)\u001b[0m\n\u001b[1;32m 206\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 207\u001b[0m \u001b[0m_check_params\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0midx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 208\u001b[0;31m \u001b[0mresult\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0meval\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindices\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0midx\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"formula\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 209\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 210\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n", "\u001b[0;31mValueError\u001b[0m: operands could not be broadcast together with shapes (100,300,100) (100,100,400) " ] } ], "source": [ "idx = spyndex.computeIndex([\"GLI\",\"VARI\"], parameters)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![youdied](https://raw.githubusercontent.com/davemlz/spyndex/main/docs/_static/youdied.png)\n", "\n", "Of course you died! Never use parameters with different shapes! :) Unless you want to use some of the parameters as constants!" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "BLUE = np.random.normal(0.13,0.05,(100,100,100))\n", "GREEN = 0.23\n", "RED = np.random.normal(0.14,0.07,(100,100,100))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Is this going to work?" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "parameters = {\"B\": BLUE, \"G\": GREEN, \"R\": RED}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I hope so..." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "idx = spyndex.computeIndex([\"GLI\",\"VARI\"], parameters)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There you go! It did! That's because you can use constants in combination with `numpy.ndarray` objects!" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "idx type: , shape: (2, 100, 100, 100)\n" ] } ], "source": [ "print(f\"idx type: {type(idx)}, shape: {idx.shape}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And the shape will be generated according to the shape of teh input data!\n", "\n", "Wonderfuuul!" ] } ], "metadata": { "interpreter": { "hash": "ec6a25acaecf7f06cb08206f3f56e96ccaf6fbab432a979bcf67c9e0ca577c87" }, "kernelspec": { "display_name": "Python 3.9.7 64-bit ('spyndex': conda)", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.7" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }