Syntax:
numpy.arange([start, ]stop, [step, ]dtype=None)
Example:
import numpy as np
# Create array from 0 to 9
arr = np.arange(10)
print(arr)
# Output: [0 1 2 3 4 5 6 7 8 9]
The np.arange() function generates arrays with evenly spaced values within a specified interval. This NumPy function returns a one-dimensional ndarray containing sequential values based on the parameters you provide.
Understanding np.arange parameters
The np.arange() method accepts up to four parameters that control how your array gets generated. The start parameter defines where the sequence begins, defaulting to 0 if you don’t specify it. The stop parameter marks the end point of the interval, and this value never appears in the output array because np.arange() uses a half-open interval. The step parameter controls the spacing between consecutive values, defaulting to 1 when omitted. The optional dtype parameter lets you specify the data type for array elements.
import numpy as np
# Using only stop parameter
arr1 = np.arange(5)
print(arr1)
# Output: [0 1 2 3 4]
# Using start and stop
arr2 = np.arange(3, 8)
print(arr2)
# Output: [3 4 5 6 7]
# Using start, stop, and step
arr3 = np.arange(2, 10, 2)
print(arr3)
# Output: [2 4 6 8]
The function determines how many elements to include by calculating the number of steps needed to reach from start to stop. When you call np.arange(5), NumPy counts from 0 and stops before reaching 5, giving you exactly five elements.
Creating integer sequences with np.arange
Integer sequences form the most common use case for np.arange(). The method excels at generating ranges of whole numbers for indexing, iteration, and numerical operations.
import numpy as np
# Generate indices for a loop
indices = np.arange(0, 100, 5)
print(indices)
# Output: [ 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95]
# Create a countdown sequence
countdown = np.arange(10, 0, -1)
print(countdown)
# Output: [10 9 8 7 6 5 4 3 2 1]
The negative step value in the countdown example reverses the direction of the sequence. This technique requires your start value to exceed your stop value, otherwise np.arange() returns an empty array.
Working with floating point values in np.arange
The np.arange() function handles floating point numbers, though this capability introduces precision considerations. When you specify any parameter as a float, NumPy automatically treats the entire sequence as floating point data.
import numpy as np
# Float sequence with decimal step
arr = np.arange(0.0, 2.0, 0.3)
print(arr)
# Output: [0. 0.3 0.6 0.9 1.2 1.5 1.8]
# Integer stop with float step
arr2 = np.arange(1, 10, 1.5)
print(arr2)
# Output: [1. 2.5 4. 5.5 7. 8.5]
Floating point arithmetic introduces rounding errors that can affect array length. The actual number of elements depends on how many steps of size step fit into the interval, calculated as ceil((stop - start) / step). This calculation becomes unpredictable with very small step sizes or large value ranges.
import numpy as np
# Demonstrating floating point precision issues
arr = np.arange(0.1, 0.4, 0.1)
print(arr)
# Output: [0.1 0.2 0.3]
# This might include or exclude 0.3 depending on rounding
arr2 = np.arange(0.0, 0.3, 0.1)
print(arr2)
# Output: [0. 0.1 0.2]
For applications requiring exact numbers of elements or precise endpoint inclusion, numpy.linspace() provides a better alternative. The linspace function accepts a count parameter instead of a step size, eliminating ambiguity about array length.
Specifying data types with the dtype parameter
NumPy infers data types from your parameters when you don’t specify dtype explicitly. Providing integer arguments produces an integer array, while any floating point argument triggers float array creation.
import numpy as np
# Integer array (inferred)
int_arr = np.arange(5)
print(int_arr.dtype)
# Output: int64
# Float array (inferred from stop value)
float_arr = np.arange(5.0)
print(float_arr.dtype)
# Output: float64
# Explicitly set dtype to float32
custom_arr = np.arange(5, dtype=np.float32)
print(custom_arr)
print(custom_arr.dtype)
# Output: [0. 1. 2. 3. 4.]
# Output: float32
The dtype parameter becomes crucial when working with memory-constrained environments or when interfacing with systems that expect specific numeric types. Using float32 instead of float64 cuts memory usage in half for large arrays.
import numpy as np
# Force integer dtype with float parameters
arr = np.arange(0.5, 5.5, dtype=int)
print(arr)
# Output: [0 1 2 3 4]
Setting dtype to an integer type truncates floating point values during array creation. This truncation happens at the parameter level, not after generating float values, which can produce unexpected results.
Creating negative number ranges with np.arange
The np.arange() method handles negative numbers just like positive ones. You can create sequences that span negative to positive, stay entirely negative, or count backwards through negative values.
import numpy as np
# Negative to positive
arr1 = np.arange(-5, 5)
print(arr1)
# Output: [-5 -4 -3 -2 -1 0 1 2 3 4]
# Only negative values
arr2 = np.arange(-10, -5)
print(arr2)
# Output: [-10 -9 -8 -7 -6]
# Negative step through negative numbers
arr3 = np.arange(-2, -10, -2)
print(arr3)
# Output: [-2 -4 -6 -8]
This flexibility makes np.arange() useful for creating coordinate grids, generating test data, or working with mathematical functions that cross zero.
Understanding edge cases and empty arrays
Several parameter combinations produce empty arrays instead of errors. When start equals stop, np.arange() returns an empty array because the interval contains no values.
import numpy as np
# Equal start and stop
arr1 = np.arange(5, 5)
print(arr1)
print(arr1.shape)
# Output: []
# Output: (0,)
# Positive step with start > stop
arr2 = np.arange(10, 5, 1)
print(arr2)
# Output: []
# Negative step with start < stop
arr3 = np.arange(5, 10, -1)
print(arr3)
# Output: []
These empty arrays are valid numpy.ndarray objects with zero elements. This behavior prevents exceptions during array operations but requires careful parameter validation in production code.
Comparing np.arange with Python’s range function
The np.arange() function shares similarities with Python’s built-in range() function, but key differences affect when to use each one. The range() function creates a range object that generates values lazily, while np.arange() immediately allocates memory for all elements in the array.
import numpy as np
# Python range (lazy evaluation)
py_range = range(0, 10)
print(type(py_range))
# Output:
# NumPy arange (immediate array creation)
np_array = np.arange(0, 10)
print(type(np_array))
# Output:
Python’s range() only accepts integer arguments, making it unsuitable for generating float sequences. The np.arange() function supports any numeric type, providing flexibility for scientific computing applications.
import numpy as np
# This works with np.arange
float_seq = np.arange(0.0, 1.0, 0.1)
print(float_seq)
# Output: [0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
# This fails with range()
# float_range = range(0.0, 1.0, 0.1) # TypeError
For simple integer iteration in loops, range() performs better because it doesn’t allocate array memory. Choose np.arange() when you need array operations, mathematical transformations, or non-integer values.
Reshaping np.arange output into multidimensional arrays
Arrays created by np.arange() start as one-dimensional structures, but you can transform them into any shape using the reshape() method. This technique generates multidimensional arrays with sequential values.
import numpy as np
# Create 2D array
arr_2d = np.arange(12).reshape(3, 4)
print(arr_2d)
# Output:
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
# Create 3D array
arr_3d = np.arange(24).reshape(2, 3, 4)
print(arr_3d)
# Output:
# [[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
#
# [[12 13 14 15]
# [16 17 18 19]
# [20 21 22 23]]]
The total number of elements in the original array must match the product of dimensions in your target shape. Attempting to reshape 10 elements into a 3×4 grid fails because 3 times 4 equals 12, not 10.
Applying mathematical operations to np.arange arrays
Arrays from np.arange() integrate seamlessly with NumPy’s mathematical functions and operators. You can perform element-wise operations, apply universal functions, or use the arrays as input for complex calculations.
import numpy as np
# Element-wise arithmetic
x = np.arange(5)
print(x * 2)
# Output: [0 2 4 6 8]
print(x ** 2)
# Output: [ 0 1 4 9 16]
# Universal functions
angles = np.arange(0, 6.28, 0.5)
sines = np.sin(angles)
print(sines)
# Output: [ 0. 0.47942554 0.84147098 0.99749499 0.90929743
# 0.59847214 0.14112001 -0.35078323 -0.7568025 -0.97753012
# -0.93799998 -0.67559314]
# Combining with other arrays
y = np.arange(1, 6)
z = np.arange(5, 10)
print(y + z)
# Output: [ 6 8 10 12 14]
This capability makes np.arange() valuable for generating input data for plotting, testing mathematical functions, or creating coordinate systems.
Using np.arange for array indexing and slicing
Sequential integer arrays from np.arange() serve as indices for advanced array operations. This technique enables complex selection patterns and batch processing of array elements.
import numpy as np
# Create sample data
data = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
# Select every other element
indices = np.arange(0, 10, 2)
selected = data[indices]
print(selected)
# Output: [10 30 50 70 90]
# Reverse array using negative step
reverse_indices = np.arange(9, -1, -1)
reversed_data = data[reverse_indices]
print(reversed_data)
# Output: [100 90 80 70 60 50 40 30 20 10]
You can combine np.arange() with boolean operations to create filtered index arrays, enabling conditional selection based on position rather than value.
Performance considerations when using np.arange
The np.arange() function creates arrays immediately upon execution, allocating memory for all elements. This upfront cost makes it less efficient than range() for simple iteration, but more efficient when you need to access elements multiple times.
import numpy as np
# Memory allocated once, used multiple times
indices = np.arange(1000000)
# Fast array operations
squared = indices ** 2
doubled = indices * 2
summed = np.sum(indices)
Large arrays with small step sizes consume significant memory. A sequence from 0 to 1 million with step 0.001 requires approximately 8 megabytes for float64 values. Consider whether you truly need all values materialized or if a generator-based approach works better.
When to choose np.linspace over np.arange
The numpy.linspace() function provides an alternative for generating evenly spaced values. While np.arange() accepts a step size and calculates how many elements fit, linspace() accepts an element count and calculates the step size.
import numpy as np
# np.arange with step size
arr1 = np.arange(0, 1, 0.2)
print(arr1)
print(len(arr1))
# Output: [0. 0.2 0.4 0.6 0.8]
# Output: 5
# np.linspace with element count
arr2 = np.linspace(0, 1, 5)
print(arr2)
print(len(arr2))
# Output: [0. 0.25 0.5 0.75 1. ]
# Output: 5
Notice that linspace() includes the endpoint by default, while np.arange() always excludes it. Choose linspace() when you need a specific number of points between two values or when endpoint inclusion matters. Use np.arange() when you know the step size and endpoint inclusion would cause issues.
Common pitfalls and how to avoid them
Floating point precision creates the most frequent issues with np.arange(). The internal implementation calculates steps as dtype(start + step) - dtype(start), which can lose precision when start significantly exceeds step.
import numpy as np
# Unexpected behavior with float dtype conversion
arr1 = np.arange(0, 5, 0.5, dtype=int)
print(arr1)
# Output: [0 0 0 0 0 0 0 0 0 0] # Unexpected!
# Better approach: generate floats then convert
arr2 = np.arange(0, 5, 0.5).astype(int)
print(arr2)
# Output: [0 0 1 1 2 2 3 3 4 4]
Another common mistake involves forgetting that stop values never appear in output. When you need a sequence from 1 to 10 including 10, you must write np.arange(1, 11) rather than np.arange(1, 10).
import numpy as np
# Missing the last value
incomplete = np.arange(1, 10)
print(incomplete)
# Output: [1 2 3 4 5 6 7 8 9] # No 10!
# Including the last value
complete = np.arange(1, 11)
print(complete)
# Output: [ 1 2 3 4 5 6 7 8 9 10]
The np.arange() method provides a straightforward way to generate sequential numeric arrays for scientific computing, data analysis, and numerical simulations. Understanding its parameters, limitations, and appropriate use cases enables you to write more efficient and reliable NumPy code. Remember to use linspace() for float sequences requiring precise endpoint control, and always validate your output when working with non-integer step sizes.

