Skip to content

ravel vs flatten

Both methods flatten arrays to 1D, but differ in memory behavior.

Mental Model

ravel returns a view when the array is already contiguous (free), but falls back to a copy when it must rearrange data. flatten always returns a copy, guaranteeing independence. Choose ravel for speed when you just need a flat view, and flatten when you need a safe, modifiable 1D copy.

Decision Rule

Need Use Why
Speed, read-only flat view ravel() Returns a view when contiguous — O(1)
Safe, independent 1D copy flatten() Always copies — O(n) but mutation-safe
Flat view, guaranteed no copy a.reshape(-1) Raises error if copy needed (unlike ravel, which silently copies)

If you are unsure whether ravel returned a view or a copy, check result.base is a.

Method ravel

The ravel() method returns a view when possible.

1. Basic Usage

```python import numpy as np

def main(): x = np.arange(6).reshape((3, 2)) print(f"{x.shape = }")

y = x.ravel()  # returns view
print(f"{y.shape = }")

if name == "main": main() ```

Output:

x.shape = (3, 2) y.shape = (6,)

2. Memory Sharing

```python import numpy as np

def main(): x = np.arange(6).reshape((3, 2)) y = x.ravel() y[0] = -1 print(f"{x[0, 0] = }") # -1

if name == "main": main() ```

3. View Behavior

Modifying the raveled array modifies the original.

Method flatten

The flatten() method always returns a copy.

1. Basic Usage

```python import numpy as np

def main(): x = np.arange(6).reshape((3, 2)) print(f"{x.shape = }")

y = x.flatten()  # returns copy
print(f"{y.shape = }")

if name == "main": main() ```

Output:

x.shape = (3, 2) y.shape = (6,)

2. Memory Independence

```python import numpy as np

def main(): x = np.arange(6).reshape((3, 2)) y = x.flatten() y[0] = -1 print(f"{x[0, 0] = }") # 0

if name == "main": main() ```

3. Copy Behavior

Modifying the flattened array does not affect the original.

Side-by-Side Compare

Direct comparison of the two methods.

1. Comparison Code

```python import numpy as np

def main(): x = np.arange(6).reshape((3, 2))

# ravel returns view
r = x.ravel()
r[0] = 99
print(f"After ravel modification: x[0,0] = {x[0, 0]}")

# Reset
x = np.arange(6).reshape((3, 2))

# flatten returns copy
f = x.flatten()
f[0] = 99
print(f"After flatten modification: x[0,0] = {x[0, 0]}")

if name == "main": main() ```

Output:

After ravel modification: x[0,0] = 99 After flatten modification: x[0,0] = 0

2. Key Difference

ravel shares memory; flatten does not.

When to Use Each

Choose based on your memory requirements.

1. Use ravel When

  • Memory efficiency matters
  • You want changes to reflect in original
  • Working with large arrays

2. Use flatten When

  • You need data isolation
  • Original must remain unchanged
  • Returning from functions

3. Performance Note

ravel is faster because it avoids memory allocation.

Order Parameter

Both methods support different flattening orders.

1. C Order (Default)

```python import numpy as np

x = np.array([[1, 2], [3, 4]]) print(x.ravel(order='C')) # [1 2 3 4] ```

Row-major order (C-style).

2. Fortran Order

```python import numpy as np

x = np.array([[1, 2], [3, 4]]) print(x.ravel(order='F')) # [1 3 2 4] ```

Column-major order (Fortran-style).


Exercises

Exercise 1. Create a = np.arange(12).reshape(3, 4). Flatten it using both a.ravel() and a.flatten(). Modify the first element of each result and check which modification affects the original array a.

Solution to Exercise 1
import numpy as np

a = np.arange(12).reshape(3, 4)
r = a.ravel()
f = a.flatten()

r[0] = 99
print(f"After ravel mod: a[0,0] = {a[0, 0]}")  # 99 (view)

a2 = np.arange(12).reshape(3, 4)
f = a2.flatten()
f[0] = 88
print(f"After flatten mod: a2[0,0] = {a2[0, 0]}")  # 0 (copy)

Exercise 2. Test np.ravel with both order='C' (row-major) and order='F' (column-major) on a 2x3 matrix. Print both results and explain why the element order differs.

Solution to Exercise 2
import numpy as np

a = np.array([[1, 2, 3], [4, 5, 6]])
print(f"C order: {np.ravel(a, order='C')}")  # [1 2 3 4 5 6]
print(f"F order: {np.ravel(a, order='F')}")  # [1 4 2 5 3 6]
# C order reads row by row, F order reads column by column.

Exercise 3. Create a non-contiguous array b = np.arange(20).reshape(4, 5)[:, ::2]. Show that b.ravel() returns a copy (not a view) by checking b.ravel().base. Explain why ravel cannot return a view for non-contiguous arrays.

Solution to Exercise 3
import numpy as np

b = np.arange(20).reshape(4, 5)[:, ::2]
r = b.ravel()
print(f"Is view: {r.base is b}")  # False (copy)
# ravel cannot return a view for non-contiguous arrays
# because the elements are not in a single contiguous
# memory block.