{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "f3557a6d-106e-461c-bc75-7ddcef4f81e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "80a3b70d-fea8-4a6f-ac02-73e30abc1f66",
   "metadata": {},
   "source": [
    "### ufunc\n",
    "ufuncs are used to implement vectorization in NumPy which is way faster than iterating over elements.\n",
    "\n",
    "They also provide broadcasting and additional methods like reduce, accumulate etc. that are very helpful for computation.\n",
    "\n",
    "ufuncs also take additional arguments, like:\n",
    "\n",
    "where boolean array or condition defining where the operations should take place.\n",
    "\n",
    "dtype defining the return type of elements.\n",
    "\n",
    "out output array where the return value should be copied."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "60f2d36b-d334-4e19-9f63-36688cca1c20",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[5, 7, 9, 11]\n"
     ]
    }
   ],
   "source": [
    "# python\n",
    "x = [1, 2, 3, 4]\n",
    "y = [4, 5, 6, 7]\n",
    "z = []\n",
    "\n",
    "for i, j in zip(x, y):\n",
    "    z.append(i + j)\n",
    "print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "0272feaa-47e7-44b4-a66d-dafdffca4a7b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 5  7  9 11]\n"
     ]
    }
   ],
   "source": [
    "# numpy\n",
    "x = [1, 2, 3, 4]\n",
    "y = [4, 5, 6, 7]\n",
    "z = np.add(x, y)\n",
    "\n",
    "print(z)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5e52ad13-9186-4866-b1c7-3f8a16901c9f",
   "metadata": {},
   "source": [
    "#### Own function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "3d004fc9-f52c-42fb-93a1-f48dd0849ba9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[6 8 10 12]\n"
     ]
    }
   ],
   "source": [
    "def myadd(x, y):\n",
    "    return x+y\n",
    "\n",
    "myadd = np.frompyfunc(myadd, 2, 1)\n",
    "\n",
    "print(myadd([1, 2, 3, 4], [5, 6, 7, 8]))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c034cd44-af9c-44ff-8d74-cf0d8d34b018",
   "metadata": {},
   "source": [
    "#### Simple Arithmetic"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "428246a1-ea45-4c0b-bc94-b3f1ad27a0ac",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[30 32 34 36 38 40]\n"
     ]
    }
   ],
   "source": [
    "arr1 = np.array([10, 11, 12, 13, 14, 15])\n",
    "arr2 = np.array([20, 21, 22, 23, 24, 25])\n",
    "\n",
    "newarr = np.add(arr1, arr2)\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "ae349412-0d47-42b4-8c39-56d0839b3d34",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-10  -1   8  17  26  35]\n"
     ]
    }
   ],
   "source": [
    "arr1 = np.array([10, 20, 30, 40, 50, 60])\n",
    "arr2 = np.array([20, 21, 22, 23, 24, 25])\n",
    "\n",
    "newarr = np.subtract(arr1, arr2)\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "f61b2129-e31b-4661-a12e-d7897955d163",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 200  420  660  920 1200 1500]\n"
     ]
    }
   ],
   "source": [
    "arr1 = np.array([10, 20, 30, 40, 50, 60])\n",
    "arr2 = np.array([20, 21, 22, 23, 24, 25])\n",
    "\n",
    "newarr = np.multiply(arr1, arr2)\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "67540798-c33e-4d1e-a1d9-47c00a121b36",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 3.33333333  4.          3.          5.         25.          1.81818182]\n"
     ]
    }
   ],
   "source": [
    "arr1 = np.array([10, 20, 30, 40, 50, 60])\n",
    "arr2 = np.array([3, 5, 10, 8, 2, 33])\n",
    "\n",
    "newarr = np.divide(arr1, arr2)\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "05c10eef-8c8e-4515-9aea-402821f05a02",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[         1000       3200000     729000000 6553600000000          2500\n",
      "             0]\n"
     ]
    }
   ],
   "source": [
    "arr1 = np.array([10, 20, 30, 40, 50, 60])\n",
    "arr2 = np.array([3, 5, 6, 8, 2, 33])\n",
    "\n",
    "newarr = np.power(arr1, arr2)\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "c47b12e8-f0a0-45c9-b1e5-202fd2dfdaed",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1  6  3  0  0 27]\n"
     ]
    }
   ],
   "source": [
    "arr1 = np.array([10, 20, 30, 40, 50, 60])\n",
    "arr2 = np.array([3, 7, 9, 8, 2, 33])\n",
    "\n",
    "newarr = np.mod(arr1, arr2)\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "7626b9ec-04f0-421b-a35d-8f30bad5a136",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(array([ 3,  2,  3,  5, 25,  1]), array([ 1,  6,  3,  0,  0, 27]))\n"
     ]
    }
   ],
   "source": [
    "# Quotient and Mod\n",
    "arr1 = np.array([10, 20, 30, 40, 50, 60])\n",
    "arr2 = np.array([3, 7, 9, 8, 2, 33])\n",
    "\n",
    "newarr = np.divmod(arr1, arr2)\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "e436c31a-a796-4be1-9e7f-ddaf0f026dec",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 1 2 3 4]\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([-1, -2, 1, 2, 3, -4])\n",
    "\n",
    "newarr = np.absolute(arr)\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d55a17c4-1f67-4629-8a85-64f9faa32370",
   "metadata": {},
   "source": [
    "### Rounding Decimals\n",
    "- truncation\n",
    "- fix\n",
    "- rounding\n",
    "- floor\n",
    "- ceil"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "11395b0f-660b-4c28-a2ed-1c722b560a71",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-3.  3.]\n"
     ]
    }
   ],
   "source": [
    "# Truncation\n",
    "# Remove the decimals, and return the float number closest to zero. Use the trunc() and fix() functions.\n",
    "\n",
    "arr = np.trunc([-3.1666, 3.6667])\n",
    "\n",
    "print(arr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "9d2c024e-07ca-43cd-978b-206a391e35f1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-3.  3.]\n"
     ]
    }
   ],
   "source": [
    "arr = np.fix([-3.1666, 3.6667])\n",
    "\n",
    "print(arr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "59ca3a99-da45-4a5c-8a2f-bcb6b22a5998",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.17\n"
     ]
    }
   ],
   "source": [
    "# rounding\n",
    "arr = np.around(3.1666, 2)\n",
    "\n",
    "print(arr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "e213a874-e4b0-4a3e-831a-5e9ff93c3d94",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-4.  3.]\n"
     ]
    }
   ],
   "source": [
    "arr = np.floor([-3.1666, 3.6667])\n",
    "\n",
    "print(arr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "fbe93a72-8e92-4b36-bfab-232c1617e4f1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-3.  4.]\n"
     ]
    }
   ],
   "source": [
    "arr = np.ceil([-3.1666, 3.6667])\n",
    "\n",
    "print(arr)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "225b1cd3-85cf-492d-8f1d-b2c94eb63783",
   "metadata": {},
   "source": [
    "### Logs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "995a441d-e78e-4ace-b6fc-b497cce04268",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3 4 5 6 7 8 9]\n",
      "[0.         1.         1.5849625  2.         2.32192809 2.5849625\n",
      " 2.80735492 3.         3.169925  ]\n"
     ]
    }
   ],
   "source": [
    "# log2() function to perform log at the base 2.\n",
    "arr = np.arange(1, 10)\n",
    "print(arr)\n",
    "print(np.log2(arr))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b386fbe7-54c7-48dd-8b08-10f053e00638",
   "metadata": {},
   "source": [
    "### Summations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "16f39361-d8a9-4d9a-970e-72367f2d4685",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2 4 6]\n"
     ]
    }
   ],
   "source": [
    "arr1 = np.array([1, 2, 3])\n",
    "arr2 = np.array([1, 2, 3])\n",
    "\n",
    "newarr = np.add(arr1, arr2)\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "bd241f37-75bf-4ee5-bcb4-8c72695eb75d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "12\n"
     ]
    }
   ],
   "source": [
    "arr1 = np.array([1, 2, 3])\n",
    "arr2 = np.array([1, 2, 3])\n",
    "\n",
    "newarr = np.sum([arr1, arr2])\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "7309e9d4-c239-4c42-8389-413df30d6abc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[6 6]\n"
     ]
    }
   ],
   "source": [
    "# summation over axis\n",
    "arr1 = np.array([1, 2, 3])\n",
    "arr2 = np.array([1, 2, 3])\n",
    "\n",
    "newarr = np.sum([arr1, arr2], axis=1)\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "518cdbe0-417b-4085-9575-729595ae2a52",
   "metadata": {},
   "source": [
    "### Products"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "0211ead9-2b18-4409-a4c6-179688bdd203",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "24\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([1, 2, 3, 4])\n",
    "\n",
    "x = np.prod(arr)\n",
    "\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "207af559-db09-48f5-b462-40fd52500bb4",
   "metadata": {},
   "source": [
    "### Differences"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "5215ae9f-709b-4206-90f3-95b5dd391f68",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[  5  10 -20]\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([10, 15, 25, 5])\n",
    "\n",
    "newarr = np.diff(arr)\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "23aeea8b-3f92-490e-927d-a61a8426a365",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[  5 -30]\n"
     ]
    }
   ],
   "source": [
    "# Compute discrete difference of the following array twice\n",
    "# 15-10=5, 25-15=10, and 5-25=-20 AND 10-5=5 and -20-10=-30\n",
    "arr = np.array([10, 15, 25, 5])\n",
    "\n",
    "newarr = np.diff(arr, n=2)\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0da9fba4-7ae2-4bfe-94b8-378d3d124b57",
   "metadata": {},
   "source": [
    "#### Other"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "69a07fa4-546c-47cd-99b2-a14548b886e2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "12\n"
     ]
    }
   ],
   "source": [
    "# Finding LCM (Lowest Common Multiple)\n",
    "num1 = 4\n",
    "num2 = 6\n",
    "# (4*3=12 and 6*2=12)\n",
    "x = np.lcm(num1, num2)\n",
    "\n",
    "print(x) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "9c874e84-1ca6-44f8-871b-0c57d05ac360",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "18\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([3, 6, 9])\n",
    "\n",
    "x = np.lcm.reduce(arr)\n",
    "\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "d7f635b8-7915-452b-8ee1-e963ed5e8f54",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n"
     ]
    }
   ],
   "source": [
    "# Finding GCD (Greatest Common Denominator)\n",
    "num1 = 6\n",
    "num2 = 9\n",
    "\n",
    "x = np.gcd(num1, num2)\n",
    "\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "d39331bf-062b-41b8-b7fe-082312dd5d6f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3 4 5 6 7]\n"
     ]
    }
   ],
   "source": [
    "# unique\n",
    "arr = np.array([1, 1, 1, 2, 3, 4, 5, 5, 6, 7])\n",
    "\n",
    "x = np.unique(arr)\n",
    "\n",
    "print(x)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "126fdebd-0a45-4be7-a65d-b4e119ebef7d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3 4 5 6]\n"
     ]
    }
   ],
   "source": [
    "arr1 = np.array([1, 2, 3, 4])\n",
    "arr2 = np.array([3, 4, 5, 6])\n",
    "\n",
    "newarr = np.union1d(arr1, arr2)\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "a84475b1-15c3-4c8f-8535-2913a4b8579d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3 4]\n"
     ]
    }
   ],
   "source": [
    "arr1 = np.array([1, 2, 3, 4])\n",
    "arr2 = np.array([3, 4, 5, 6])\n",
    "\n",
    "newarr = np.intersect1d(arr1, arr2, assume_unique=True)\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "771b4dc1-78e9-4819-af4f-b2bb3bc154e5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2]\n"
     ]
    }
   ],
   "source": [
    "set1 = np.array([1, 2, 3, 4])\n",
    "set2 = np.array([3, 4, 5, 6])\n",
    "\n",
    "newarr = np.setdiff1d(set1, set2, assume_unique=True)\n",
    "\n",
    "print(newarr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "95b8cec1-8b0e-43fb-acae-428d7778c03e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.0\n"
     ]
    }
   ],
   "source": [
    "# Trigonometric Functions\n",
    "x = np.sin(np.pi/2)\n",
    "\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "e3dbac10-d7bd-45bb-974b-56f8f6082de8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1.57079633 3.14159265 4.71238898 6.28318531]\n"
     ]
    }
   ],
   "source": [
    "# and sin(), cos() and tan()\n",
    "# np.deg2rad(arr)\n",
    "# Hyperbolic: sinh(), cosh() and tanh()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "67cab045-d1ef-4de1-9aaa-5257d5ba5571",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
