Reshape NumPy Array
Problem Statement
Reshape a 1D NumPy array into a 2D array with specified dimensions.
Background
Reshaping is crucial for preparing data for machine learning models. The reshape() method changes array dimensions without changing data.
Your Task
Write a function reshape_array(arr, new_shape) that:
- Reshapes the input array to new_shape
- Returns a dictionary with:
- "original_shape": Original shape as list
- "new_shape": New shape as list
- "array": Reshaped array as nested list
Output Format
Return a dictionary with exactly these three keys.
Example:
arr = np.arange(6), new_shape = (2, 3)
{'original_shape': [6], 'new_shape': [2, 3], 'array': [[0, 1, 2], [3, 4, 5]]}6 elements reshaped to 2 rows x 3 columns
Constraints:
- Use numpy reshape() method
- new_shape will be compatible with array size
- Return shapes as lists
1. Background Knowledge
NumPy arrays are the foundational data structure for numerical computing in Python, enabling efficient vectorized operations on multi-dimensional data. The shape of a NumPy array is a tuple representing its dimensions (e.g., (6,) for 1D, (2, 3) for 2D), with total elements given by the product of shape dimensions.
Reshaping reorganizes elements into a new shape without copying data or altering values, provided the total number of elements remains constant: \prod(\text{original_shape})=\prod(\text{new_shape})
This is critical in ML for:
- Converting feature vectors to matrices for models
- Preparing batch data: (\text{batch_size},\text{features})
- Image reshaping: (\text{height},\text{width},\text{channels})
2. Algorithm Approach
The core algorithm uses NumPy's reshape() method, which:
- Validates shape compatibility: arr.size==\prod(\text{new_shape})
- Creates a view (not copy) with new dimensions
- Returns row-major (C-order) contiguous memory layout by default
Key NumPy methods:
arr.reshape(new_shape) # Reshape to specified dimensions
arr.shape # Get current shape as tuple
arr.tolist() # Convert to nested Python lists
arr.size # Total number of elements
3. Step-by-Step Strategy
def reshape_array(arr, new_shape):
# Step 1: Capture original shape as list
original_shape = list(arr.shape)
# Step 2: Reshape array (guaranteed compatible per constraints)
reshaped = arr.reshape(new_shape)
# Step 3: Convert to nested list for output
array_nested = reshaped.tolist()
# Step 4: Return required dictionary
return {
"original_shape": original_shape,
"new_shape": list(new_shape),
"array": array_nested
}
Execution flow:
- list(arr.shape) →
- arr.reshape((2, 3)) → 2×3 view
- reshaped.tolist() → [[0, 1, 2], [3, 4, 5]]
- Package in dictionary
4. Common Pitfalls
| Pitfall | Problem | Fix |
|---|---|---|
| Returning NumPy array | {"array": reshaped} fails output format | Use reshaped.tolist() |
| Shape as tuple | {"new_shape": new_shape} | Convert: list(new_shape) |
| Assuming compatibility | reshape() raises ValueError | Problem guarantees compatibility |
| Data copying | reshaped = arr.reshape().copy() | Use view: reshape() alone |
| Modifying original | Changes propagate (view semantics) | Expected behavior for this problem |
Memory note: reshape() creates a zero-copy view—efficient but mutations affect original.
5. Time & Space Complexity
Time Complexity: O(1)
- reshape(): Metadata update only (no data movement)
- tolist(): O(n) where n= total elements, but minimal for output
Space Complexity: O(1) additional (excluding output)
Input: 1D array of size n
- reshape(): O(1) view
- tolist(): O(n) temporary nested list
- Dictionary: O(1) + O(n) for output array
Total extra: O(n) dominated by output
Why efficient? NumPy uses strided arrays—reshaping adjusts strides (memory step sizes) without copying data.
This solution is optimal for ML data preparation pipelines requiring frequent reshaping.