Skip to content

    Chapter 6, Basic

    Anatomy of an array

    Before transforming an array, learn to read what it says about itself. All the important information is in half a dozen attributes.

    Code for this chapter: básico/cap06_anatomia.py

    The attributes

    básico/cap06_anatomia.pylinhas 10 a 16
    import numpy as np
    
    arr = np.array([[1, 2, 3], [4, 5, 6]])
    print(arr.shape, arr.ndim, arr.size)
    print(arr.dtype, arr.itemsize, arr.nbytes)
    print(arr.T)
    print(arr.strides)
    
    Output
    (2, 3) 2 6
    int64 8 48
    [[1 4]
     [2 5]
     [3 6]]
    (24, 8)
    
    AttributeMeansIn the example
    shapeThe dimensions, as a tuple(2, 3): 2 rows and 3 columns
    ndimHow many dimensions2
    sizeHow many elements in total6
    dtypeThe type of all the elementsint64
    itemsizeBytes per element8
    nbytesBytes in total (size * itemsize)48
    TThe transpose (rows become columns)A view, without copying
    stridesBytes to skip to go to the next element in each axis(24, 8)

    The strides is the internal detail that makes slicing so fast: to move one row, NumPy skips 24 bytes (3 elements of 8 bytes), and to move one column, it skips 8. You don't need to calculate it, but chapter 29 shows how it allows creating "views" without copying data.

    Shape is not size

    The most frequent mistake of beginners is to swap shape for size. They answer different questions: the shape tells how the elements are organized, and the size tells how many there are. An array of shape (4, 5) has size 20.

    A one-dimensional array has shape of a element, and the comma is needed in the tuple. And there are zero-dimensional arrays (scalars), whose shape is the empty tuple:

    básico/cap06_anatomia.pylinha 21
    print(len(arr), np.array([1, 2, 3]).shape, np.array(5).shape, np.array(5).ndim)
    
    Output
    2 (3,) () 0
    

    The len(arr) returns only the size of the first dimension (2 rows). For the total number of elements, use size.

    Why dtype matters more than it seems

    A million of float64 takes up double the memory of the same million in float32. In a toy dataset this is irrelevant, but when the dataset grows to hundreds of millions of values, choosing the right type decides whether it fits in memory. The next chapter deals with this.

    Exercise 1

    A summary of any array

    Write resumo(a) that returns a dictionary with forma, dimensoes, tamanho and bytes of an array. Test with np.zeros((4, 5)).