1

Could you tell me if there is any 'smart' way to generate a 3D numpy array based on provided pattern? Let me explain what I mean by this. E.g., if pattern is [1, 4, 6, 4, 1], corresponding 2D array for it would be:

[
    [1, 1, 1, 1, 1],
    [1, 4, 4, 4, 1],
    [1, 4, 6, 4, 1],
    [1, 4, 4, 4, 1],
    [1, 1, 1, 1, 1]
]

And 3D array is similar to 2D. If you imagine that 3D array as a cube: just one 6 in the center of 'cube', twenty six 4s around it in the closest neighborhood, and the rest 1s. I apologize for potentially confusing explanation, I'm not a native English speaker. Please ask if something is unclear. Thanks!

Any python library can be used.

2
  • Specifically the pattern you show? I doubt it. In general numpy indexing is powerful and a pattern is just defined using math that python can do, so implementing it yourself is not a large task if you don't need to handle an arbitrary number of dimensions. Commented Apr 4, 2022 at 15:35
  • Thank you for the comment. At least, this pattern, but ideally any pattern of 5 members. Commented Apr 5, 2022 at 7:44

2 Answers 2

1

You can use numpy.pad to add "layers" around your center number one by one (like an onion (well, a very cubic onion, actually) ):

pattern = [1,4,6]

x = np.array(pattern[-1]).reshape([1,1,1])
for p in reversed(pattern[:-1]):
    x = np.pad(x, mode='constant', constant_values=p, pad_width=1)
    
print(x)
#[[[1 1 1 1 1]
#  [1 1 1 1 1]
#  [1 1 1 1 1]
#  [1 1 1 1 1]
#  [1 1 1 1 1]]
#
# [[1 1 1 1 1]
#  [1 4 4 4 1]
#  [1 4 4 4 1]
#  [1 4 4 4 1]
#  [1 1 1 1 1]]
#
# [[1 1 1 1 1]
#  [1 4 4 4 1]
#  [1 4 6 4 1]
#  [1 4 4 4 1]
#  [1 1 1 1 1]]
#
# [[1 1 1 1 1]
#  [1 4 4 4 1]
#  [1 4 4 4 1]
#  [1 4 4 4 1]
#  [1 1 1 1 1]]
#
# [[1 1 1 1 1]
#  [1 1 1 1 1]
#  [1 1 1 1 1]
#  [1 1 1 1 1]
#  [1 1 1 1 1]]]

The code above should work with an arbitrary number of layers (in fact, it also works for an arbitrary amount of dimensions, if you adapt the reshape). However, it scales poorly with the number of layers, due to the for-loop. While it certainly is overkill to vectorize this for-loop in this application, I'd be open for suggestions if anyone has an idea.

Sign up to request clarification or add additional context in comments.

Comments

0

The tricky part is generating the indices matching the pattern. The following should work for palindromes:

a = np.array([1,4,6,4,1])
i = np.ceil((np.r_[:2, 2:-1:-1][:, None] * np.r_[:2, 2:-1:-1]) / 2).astype(int)
a[i]

output:

array([[1, 1, 1, 1, 1],
       [1, 4, 4, 4, 1],
       [1, 4, 6, 4, 1],
       [1, 4, 4, 4, 1],
       [1, 1, 1, 1, 1]])

Comments

Your Answer

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.