{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# How are numpy arrays stored?" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Numpy presents an n-dimensional abstraction that has to be fit into 1-dimensional computer memory.\n", "\n", "Even for 2 dimensions (matrices), this leads to confusion: row-major, column-major." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[0 1 2]\n", " [3 4 5]\n", " [6 7 8]]\n" ] } ], "source": [ "A = np.arange(9).reshape(3, 3)\n", "print(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Strides and in-memory representation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "How is this represented in memory?" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(24, 8)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.strides" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* `strides` stores for each axis by how many bytes one needs to jump to get from one entry to the next (in that axis)\n", "* So how is the array above stored?\n", "* This captures row-major (\"C\" order) and column-major (\"Fortran\" order), but is actually much more general." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also ask for Fortran order:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[0, 3, 6],\n", " [1, 4, 7],\n", " [2, 5, 8]])" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A2 = np.arange(9).reshape(3, 3, order=\"F\")\n", "A2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`numpy` defaults to row-major order." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(8, 24)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A2.strides" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Strides and Contiguity" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "How is the stride model more general than just saying \"row major\" or \"column major\"?" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 0, 1, 2, 3],\n", " [ 4, 5, 6, 7],\n", " [ 8, 9, 10, 11],\n", " [12, 13, 14, 15]])" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A = np.arange(16).reshape(4, 4)\n", "A" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(32, 8)" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.strides" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 0, 1, 2],\n", " [ 4, 5, 6],\n", " [ 8, 9, 10]])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Asub = A[:3, :3]\n", "Asub" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Recall that `Asub` constitutes a *view* of the original data in `A`." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(32, 8)" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Asub.strides" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now `Asub` is no longer a *contiguous* array!\n", "\n", "From the linear-memory representation (as show by the increasing numbers in `A`) 3, 7, 11 are missing.\n", "\n", "This is easy to check by a flag:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ " C_CONTIGUOUS : False\n", " F_CONTIGUOUS : False\n", " OWNDATA : False\n", " WRITEABLE : True\n", " ALIGNED : True\n", " UPDATEIFCOPY : False" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Asub.flags" ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 0 }