3
\$\begingroup\$

I want to create a function that takes a numpy array, an axis and an index of that axis and returns the array with the index on the specified axis fixed. What I thought is to create a string that change dynamically and then is evaluated as an index slicing in the array (as showed in this answer). I came up with the following function:

import numpy as np
def select_slc_ax(arr, slc, axs):
 dim = len(arr.shape)-1
 slc = str(slc)
 slice_str = ":,"*axs+slc+",:"*(dim-axs)
 print(slice_str)
 slice_obj = eval(f'np.s_[{slice_str}]')
 return arr[slice_obj]

Example

>>> arr = np.array([[[0, 0, 0],
 [0, 0, 0],
 [0, 0, 0]],
 [[0, 1, 0],
 [1, 1, 1],
 [0, 1, 0]],
 [[0, 0, 0],
 [0, 0, 0], 
 [0, 0, 0]]], dtype='uint8')
>>> select_slc_ax(arr, 2, 1)
:,2,:
array([[0, 0, 0],
 [0, 1, 0],
 [0, 0, 0]], dtype=uint8)

I was wondering if there is a better method to do this.

asked Jul 30, 2021 at 14:35
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$
  • Avoid eval at all costs
  • Use the slice built-in for your : components, or the numeric index at the selected axis
  • Do not abbreviate your variable names
  • Type-hint your function signature
  • Turn your example into something resembling a unit test with an assert
  • Modify the data in your example to add more non-zero entries making it clearer what's happening
  • Prefer immutable tuples over mutable lists when passing initialization constants to Numpy
  • Prefer the symbolic constants for Numpy types rather than strings

Suggested

import numpy as np
def select_slice_axis(array: np.ndarray, index: int, axis: int) -> np.ndarray:
 slices = tuple(
 index if a == axis else slice(None)
 for a in range(len(array.shape))
 )
 return array[slices]
arr = np.array(
 (
 ((0, 0, 0),
 (0, 0, 0),
 (0, 0, 9)),
 ((0, 1, 0),
 (2, 3, 4),
 (0, 5, 0)),
 ((0, 0, 0),
 (0, 0, 0),
 (8, 0, 0)),
 ),
 dtype=np.uint8,
)
actual = select_slice_axis(arr, 2, 1)
expected = np.array(
 (
 (0, 0, 9),
 (0, 5, 0),
 (8, 0, 0),
 ), dtype=np.uint8
)
assert np.all(expected == actual)
answered Aug 1, 2021 at 16:23
\$\endgroup\$
2
  • \$\begingroup\$ Thank you very much, this is really helpful! Just one more clarification: why eval is so bad? Thank you \$\endgroup\$ Commented Aug 9, 2021 at 7:51
  • 1
    \$\begingroup\$ It greatly increases the surface area for bugs and security flaws. \$\endgroup\$ Commented Aug 9, 2021 at 12:51

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.