Skip to content

NumPy - Array Attributes

NumPy arrays (ndarray objects) have several useful attributes that provide information about the array’s structure and data without needing to inspect the data itself. These attributes are essential for understanding and manipulating arrays effectively.

Returns a tuple indicating the size of the array along each dimension. For a 2D array (matrix), it gives (rows, columns). For a 1D array, it gives (n,).

You can also set the shape attribute to resize the array in-place, but the total number of elements must remain the same. This operation creates a view if possible, modifying how the existing data is interpreted.

import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]])
print(f"Array:\n{a}")
print(f"Shape: {a.shape}")
b = np.array([10, 20, 30])
print(f"\nArray:\n{b}")
print(f"Shape: {b.shape}")

Output:

Array:
[[1 2 3]
[4 5 6]]
Shape: (2, 3)
Array:
[10 20 30]
Shape: (3,)

Example 2: Setting Shape (In-place Reshape)

Section titled “Example 2: Setting Shape (In-place Reshape)”
# Reshape the array by assigning to the shape attribute
import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]]) # Total 6 elements
print(f"Original array (shape {a.shape}):\n{a}\n")
# Reshape in-place to 3 rows, 2 columns (still 6 elements)
try:
a.shape = (3, 2)
print(f"Reshaped array (shape {a.shape}):\n{a}")
except ValueError as e:
print(f"Error reshaping: {e}")
# Attempting incompatible shape
try:
print("\nAttempting to reshape to (3, 3) (9 elements)")
a.shape = (3, 3) # This will fail
except ValueError as e:
print(f"Error: {e}")

Output:

Original array (shape (2, 3)):
[[1 2 3]
[4 5 6]]
Reshaped array (shape (3, 2)):
[[1 2]
[3 4]
[5 6]]
Attempting to reshape to (3, 3) (9 elements)
Error: cannot reshape array of size 6 into shape (3,3)

NumPy also provides the reshape() method, which returns a new array (often a view, but sometimes a copy) with the specified shape. The original array is unchanged.

import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]])
print(f"Original array 'a' (shape {a.shape}):\n{a}\n")
# Create a new array 'b' with shape (3, 2)
b = a.reshape(3, 2)
print(f"New array 'b' (shape {b.shape}):\n{b}\n")
print(f"Original array 'a' remains unchanged:\n{a}")

Output:

Original array 'a' (shape (2, 3)):
[[1 2 3]
[4 5 6]]
New array 'b' (shape (3, 2)):
[[1 2]
[3 4]
[5 6]]
Original array 'a' remains unchanged:
[[1 2 3]
[4 5 6]]

Returns the number of array dimensions (axes). For example, a 1D array has ndim=1, a 2D array has ndim=2.

import numpy as np
# Create an array of numbers from 0 to 23
a = np.arange(24)
print(f"Array 'a':\n{a}")
print(f"Number of dimensions (a.ndim): {a.ndim}\n")
# Reshape 'a' into a 3D array (2 layers, 4 rows, 3 columns)
b = a.reshape(2, 4, 3)
print(f"Reshaped array 'b':\n{b}")
print(f"Number of dimensions (b.ndim): {b.ndim}")

Output:

Array 'a':
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
Number of dimensions (a.ndim): 1
Reshaped array 'b':
[[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
[[12 13 14]
[15 16 17]
[18 19 20]
[21 22 23]]]
Number of dimensions (b.ndim): 3

Returns the total number of elements in the array. This is equal to the product of the elements in the shape tuple.

import numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]])
print(f"Array:\n{a}")
print(f"Shape: {a.shape}")
print(f"Size (total elements): {a.size}") # 2 * 3 = 6

Output:

Array:
[[1 2 3]
[4 5 6]]
Shape: (2, 3)
Size (total elements): 6

Returns an object describing the data type of the elements in the array. Examples include int64, float64, bool, complex128, object, etc.

import numpy as np
# Array of integers (defaults to int64 on most systems)
a = np.array([1, 2, 3])
print(f"Array 'a': {a}, dtype: {a.dtype}\n")
# Array of floats (defaults to float64)
b = np.array([1.0, 2.5, 3.14])
print(f"Array 'b': {b}, dtype: {b.dtype}\n")
# Array with specified dtype
c = np.array([1, 0, 1], dtype=bool)
print(f"Array 'c': {c}, dtype: {c.dtype}")

Output:

Array 'a': [1 2 3], dtype: int64
Array 'b': [1. 2.5 3.14], dtype: float64
Array 'c': [ True False True], dtype: bool

Returns the size (in bytes) of each element in the array. For example, a float64 array has an itemsize of 8 (since 64 bits = 8 bytes).

import numpy as np
# Array with int8 (1 byte per element)
x = np.array([1, 2, 3], dtype=np.int8)
print(f"Array 'x': {x}, dtype: {x.dtype}, itemsize: {x.itemsize} bytes\n")
# Array with float32 (4 bytes per element)
y = np.array([1.0, 2.0, 3.0], dtype=np.float32)
print(f"Array 'y': {y}, dtype: {y.dtype}, itemsize: {y.itemsize} bytes\n")
# Array with default float64 (8 bytes per element)
z = np.array([1.0, 2.0, 3.0])
print(f"Array 'z': {z}, dtype: {z.dtype}, itemsize: {z.itemsize} bytes")

Output:

Array 'x': [1 2 3], dtype: int8, itemsize: 1 bytes
Array 'y': [1. 2. 3.], dtype: float32, itemsize: 4 bytes
Array 'z': [1. 2. 3.], dtype: float64, itemsize: 8 bytes

Returns an object containing information about the memory layout and properties of the array data. Key flags include:

FlagDescription
C_CONTIGUOUS (C)The data is stored in row-major (C-style) contiguous memory block.
F_CONTIGUOUS (F)The data is stored in column-major (Fortran-style) contiguous memory block.
OWNDATA (O)Indicates if the array owns the memory it uses. False for views.
WRITEABLE (W)Indicates if the data area can be modified. Can be set to False to make an array read-only.
ALIGNED (A)Indicates if the data is appropriately aligned in memory for the hardware, which can affect performance.
WRITEBACKIFCOPY (X)Formerly UPDATEIFCOPY (U). Relates to temporary copies used internally; less commonly interacted with directly.

Contiguity (C or F) can significantly impact performance for certain operations, as accessing elements sequentially in memory is generally faster.

Displaying the flags of a standard array:

import numpy as np
x = np.array([1, 2, 3, 4, 5])
print(f"Array 'x': {x}")
print(f"Flags for 'x':\n{x.flags}\n")
# Example of a non-contiguous array (from slicing)
y = x[::2] # Elements 1, 3, 5 (indices 0, 2, 4)
print(f"Array 'y' (a slice): {y}")
print(f"Flags for 'y':\n{y.flags}\n")
# Example of a Fortran-contiguous array
z = np.array([[1,2],[3,4]], order='F')
print(f"Array 'z' (Fortran order):\n{z}")
print(f"Flags for 'z':\n{z.flags}")

Output (may vary slightly based on NumPy version and system):

Array 'x': [1 2 3 4 5]
Flags for 'x':
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
Array 'y' (a slice): [1 3 5]
Flags for 'y':
C_CONTIGUOUS : False
F_CONTIGUOUS : False
OWNDATA : False
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
Array 'z' (Fortran order):
[[1 2]
[3 4]]
Flags for 'z':
C_CONTIGUOUS : False
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False