{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Understanding Data Types in Python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A Python List Is More Than Just a List\n", "\n", "Let's consider now what happens when we use a Python data structure that holds many Python objects.\n", "The standard mutable multielement container in Python is the list.\n", "We can create a list of integers as follows:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "L = list(range(10))\n", "L" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "type(L[0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or, similarly, a list of strings:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "L2 = [str(c) for c in L]\n", "L2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "type(L2[0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Because of Python's dynamic typing, we can even create heterogeneous lists:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "L3 = [True, \"2\", 3.0, 4]\n", "[type(item) for item in L3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fixed-Type Arrays in Python" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "import array\n", "L = list(range(10))\n", "A = array.array('i', L)\n", "A" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here, `'i'` is a type code indicating the contents are integers.\n", "\n", "Much more useful, however, is the `ndarray` object of the NumPy package.\n", "While Python's `array` object provides efficient storage of array-based data, NumPy adds to this efficient *operations* on that data.\n", "We will explore these operations in later chapters; next, I'll show you a few different ways of creating a NumPy array." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Creating Arrays from Python Lists\n", "\n", "We'll start with the standard NumPy import, under the alias `np`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can use `np.array` to create arrays from Python lists:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Integer array\n", "np.array([1, 4, 2, 5, 3])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remember that unlike Python lists, NumPy arrays can only contain data of the same type.\n", "If the types do not match, NumPy will upcast them according to its type promotion rules; here, integers are upcast to floating point:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "np.array([3.14, 4, 2, 3])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we want to explicitly set the data type of the resulting array, we can use the `dtype` keyword:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "np.array([1, 2, 3, 4], dtype=np.float32)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, unlike Python lists, which are always one-dimensional sequences, NumPy arrays can be multidimensional. Here's one way of initializing a multidimensional array using a list of lists:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Nested lists result in multidimensional arrays\n", "np.array([range(i, i + 3) for i in [2, 4, 6]])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The inner lists are treated as rows of the resulting two-dimensional array." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Creating Arrays from Scratch\n", "\n", "Especially for larger arrays, it is more efficient to create arrays from scratch using routines built into NumPy.\n", "Here are several examples:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Create a length-10 integer array filled with 0s\n", "np.zeros(10, dtype=int)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Create a 3x5 floating-point array filled with 1s\n", "np.ones((3, 5), dtype=float)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Create a 3x5 array filled with 3.14\n", "np.full((3, 5), 3.14)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Create an array filled with a linear sequence\n", "# starting at 0, ending at 20, stepping by 2\n", "# (this is similar to the built-in range function)\n", "np.arange(0, 20, 2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Create an array of five values evenly spaced between 0 and 1\n", "np.linspace(0, 1, 5)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Create a 3x3 array of uniformly distributed\n", "# pseudorandom values between 0 and 1\n", "np.random.random((3, 3))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Create a 3x3 array of normally distributed pseudorandom\n", "# values with mean 0 and standard deviation 1\n", "np.random.normal(0, 1, (3, 3))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Create a 3x3 array of pseudorandom integers in the interval [0, 10)\n", "np.random.randint(0, 10, (3, 3))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Create a 3x3 identity matrix\n", "np.eye(3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "# Create an uninitialized array of three integers; the values will be\n", "# whatever happens to already exist at that memory location\n", "np.empty(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## NumPy Standard Data Types\n", "\n", "NumPy arrays contain values of a single type, so it is important to have detailed knowledge of those types and their limitations.\n", "Because NumPy is built in C, the types will be familiar to users of C, Fortran, and other related languages.\n", "\n", "The standard NumPy data types are listed in the following table.\n", "Note that when constructing an array, they can be specified using a string:\n", "\n", "```python\n", "np.zeros(10, dtype='int16')\n", "```\n", "\n", "Or using the associated NumPy object:\n", "\n", "```python\n", "np.zeros(10, dtype=np.int16)\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "| Data type\t | Description |\n", "|-------------|-------------|\n", "| `bool_` | Boolean (True or False) stored as a byte |\n", "| `int_` | Default integer type (same as C `long`; normally either `int64` or `int32`)| \n", "| `intc` | Identical to C `int` (normally `int32` or `int64`)| \n", "| `intp` | Integer used for indexing (same as C `ssize_t`; normally either `int32` or `int64`)| \n", "| `int8` | Byte (–128 to 127)| \n", "| `int16` | Integer (–32768 to 32767)|\n", "| `int32` | Integer (–2147483648 to 2147483647)|\n", "| `int64` | Integer (–9223372036854775808 to 9223372036854775807)| \n", "| `uint8` | Unsigned integer (0 to 255)| \n", "| `uint16` | Unsigned integer (0 to 65535)| \n", "| `uint32` | Unsigned integer (0 to 4294967295)| \n", "| `uint64` | Unsigned integer (0 to 18446744073709551615)| \n", "| `float_` | Shorthand for `float64`| \n", "| `float16` | Half-precision float: sign bit, 5 bits exponent, 10 bits mantissa| \n", "| `float32` | Single-precision float: sign bit, 8 bits exponent, 23 bits mantissa| \n", "| `float64` | Double-precision float: sign bit, 11 bits exponent, 52 bits mantissa| \n", "| `complex_` | Shorthand for `complex128`| \n", "| `complex64` | Complex number, represented by two 32-bit floats| \n", "| `complex128`| Complex number, represented by two 64-bit floats| " ] } ], "metadata": { "anaconda-cloud": {}, "jupytext": { "formats": "ipynb,md" }, "kernelspec": { "display_name": "Python 3", "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.8.8" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 4 }