NumPy provides efficient ways to justify arrays using vectorized functions, offering improved performance and code simplicity compared to traditional Python loops.
Given a NumPy array, the task is to shift its non-zero elements to the left, right, up, or down while maintaining its shape.
The following NumPy implementation performs efficient justification:
import numpy as np def justify(a, invalid_val=0, axis=1, side='left'): if invalid_val is np.nan: mask = ~np.isnan(a) else: mask = a!=invalid_val justified_mask = np.sort(mask,axis=axis) if (side=='up') | (side=='left'): justified_mask = np.flip(justified_mask,axis=axis) out = np.full(a.shape, invalid_val) if axis==1: out[justified_mask] = a[mask] else: out.T[justified_mask.T] = a.T[mask.T] return out
This function justifies a 2D array along the specified axis and side (left, right, up, down). It works by identifying non-zero elements using mask, sorting them using sort, flipping the mask if justifying upwards or leftwards, and finally overwriting the original array with the justified values.
Here's a usage example that covers non-zero elements to the left:
a = np.array([[1,0,2,0], [3,0,4,0], [5,0,6,0], [0,7,0,8]]) # Cover left covered_left = justify(a, axis=1, side='left') print("Original Array:") print(a) print("\nCovered Left:") print(covered_left)
Output:
Original Array: [[1 0 2 0] [3 0 4 0] [5 0 6 0] [0 7 0 8]] Covered Left: [[1 2 0 0] [3 4 0 0] [5 6 0 0] [7 8 0 0]]
For justifying an N-dimensional array, the following function can be used:
def justify_nd(a, invalid_val, axis, side): pushax = lambda a: np.moveaxis(a, axis, -1) if invalid_val is np.nan: mask = ~np.isnan(a) else: mask = a!=invalid_val justified_mask = np.sort(mask,axis=axis) if side=='front': justified_mask = np.flip(justified_mask,axis=axis) out = np.full(a.shape, invalid_val) if (axis==-1) or (axis==a.ndim-1): out[justified_mask] = a[mask] else: pushax(out)[pushax(justified_mask)] = pushax(a)[pushax(mask)] return out
This function supports more complex scenarios by justifying an N-dimensional array along an arbitrary axis and to either the 'front' or 'end' of the array.
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3