Add runnable scripts to numpy-reshape materials by realpython-bot · Pull Request #788 · realpython/materials · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions numpy-reshape/README.md
8 changes: 8 additions & 0 deletions numpy-reshape/array_shape.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Inspect the shape and number of dimensions of a NumPy array."""

import numpy as np

numbers = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
print(numbers)
print(f"Shape: {numbers.shape}")
print(f"Number of dimensions: {numbers.ndim}")
19 changes: 19 additions & 0 deletions numpy-reshape/change_shape.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""Change an array's shape with reshape() without changing its data.

The random generator is seeded so that the output is reproducible.
"""

import numpy as np

rng = np.random.default_rng(seed=42)
results = rng.integers(0, 100, size=(5, 10))
print(f"Original results, shape {results.shape}:")
print(results)

# Reshape the five classes of ten scores into a single row
year_results = results.reshape((1, 50))
print(f"\nReshaped to one row, shape {year_results.shape}:")
print(year_results)

# year_results is still 2D, so you index it with both a row and a column
print(f"\nFirst score: {year_results[0, 0]}")
23 changes: 23 additions & 0 deletions numpy-reshape/color_image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Reshape a 3D color image into a 2D triptych of its color channels.

Run this script from the folder that contains poppy.jpg. Each reshaped
image opens in your default image viewer.
"""

import numpy as np
from PIL import Image

with Image.open("poppy.jpg") as photo:
image_array = np.array(photo)

print(f"Image shape: {image_array.shape}")
height, width, _ = image_array.shape

# The default order="C" interleaves each pixel's color channels
triptych_c = image_array.reshape((height, 3 * width))
print(f"Reshaped shape: {triptych_c.shape}")
Image.fromarray(triptych_c).show()

# order="F" places the red, green, and blue channels side by side
triptych_f = image_array.reshape((height, 3 * width), order="F")
Image.fromarray(triptych_f).show()
34 changes: 34 additions & 0 deletions numpy-reshape/compatible_shapes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Reshape into compatible shapes by trimming or extending the data."""

import numpy as np

rng = np.random.default_rng(seed=42)
temperatures = rng.normal(18, 1, size=200)

# An incompatible shape raises a ValueError
try:
temperatures.reshape((3, 7, 8))
except ValueError as error:
print(f"ValueError: {error}")

days_per_week = 7
readings_per_day = 8
number_of_weeks = len(temperatures) // (days_per_week * readings_per_day)
trimmed_length = number_of_weeks * days_per_week * readings_per_day

# Option 1: trim the data so that it fits a whole number of weeks
temperatures_week = temperatures[:trimmed_length].reshape(
(number_of_weeks, days_per_week, readings_per_day)
)
print(f"Trimmed shape: {temperatures_week.shape}")

# Option 2: extend the data with np.nan filler values
extended_length = (number_of_weeks + 1) * (days_per_week * readings_per_day)
additional_length = extended_length - len(temperatures)
temperatures_extended = np.append(
temperatures, np.full(additional_length, np.nan)
)
temperatures_week = temperatures_extended.reshape(
(number_of_weeks + 1, days_per_week, readings_per_day)
)
print(f"Extended shape: {temperatures_week.shape}")
13 changes: 13 additions & 0 deletions numpy-reshape/increase_dimensions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""Increase the number of dimensions of an array with reshape()."""

import numpy as np

rng = np.random.default_rng(seed=42)
temperatures = rng.normal(18, 1, size=200)
print(f"Original shape: {temperatures.shape}")

# 200 readings, eight per day, gives 25 rows of eight columns
temperatures_day = temperatures.reshape((25, 8))
print(f"Reshaped into days, shape: {temperatures_day.shape}")
print("Second day's readings:")
print(temperatures_day[1])
13 changes: 13 additions & 0 deletions numpy-reshape/order_parameter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""Control how reshape() rearranges data with the order parameter."""

import numpy as np

numbers = np.array([1, 2, 3, 4, 5, 6, 7, 8])

# Row-major (C) order fills each row before moving to the next
print('order="C":')
print(numbers.reshape((2, 4), order="C"))

# Column-major (F) order fills each column before moving to the next
print('order="F":')
print(numbers.reshape((2, 4), order="F"))
15 changes: 15 additions & 0 deletions numpy-reshape/reduce_dimensions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""Reduce the number of dimensions of an array with reshape()."""

import numpy as np

rng = np.random.default_rng(seed=42)
results = rng.integers(0, 100, size=(5, 10))

# Pass a one-element tuple to reshape the 2D array into a 1D array
year_results = results.reshape((50,))
print(f"Shape: {year_results.shape}, dimensions: {year_results.ndim}")
print(f"First score: {year_results[0]}")

# Passing a single integer gives the same 1D result
same_results = results.reshape(50)
print(f"Integer argument gives the same shape: {same_results.shape}")
2 changes: 2 additions & 0 deletions numpy-reshape/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
numpy==2.5.0
Pillow==12.2.0
16 changes: 16 additions & 0 deletions numpy-reshape/wildcard.py
Loading