Best way to insert values of 3D array inside of another larger array
Asked Answered
M

1

6

There must be some 'pythonic' way to do this, but I don't think np.place, np.insert, or np.put are what I'm looking for. I want to replace the values inside of a large 3D array A with those of a smaller 3D array B, starting at location [i,j,k] in the larger array. See drawing:

I want to type something like A[i+, j+, k+] = B, or np.embed(B, A, (i,j,k)) but of course those are not right.

EDIT: Oh, there is this. So I should modify the question to ask if this is the best way (where "best" means fastest for a 500x500x50 array of floats on a laptop):

s0, s1, s2 = B.shape
A[i:i+s0, j:j+s1, k:k+s2] = B

one 3D array inside another

Menace answered 8/10, 2015 at 2:2 Comment(1)
That 'edit' expression looks right. Assuming the details are correct, slice indexing is as fast as it gets.Cuffs
Y
2

Your edited answer looks fine for the 3D case.

If you want the "embed" function you mentioned in the original post, for arrays of any number of dimensions, the following should work:

def embed( small_array, big_array, big_index):
    """Overwrites values in big_array starting at big_index with those in small_array"""
    slices = [np.s_[i:i+j] for i,j in zip(big_index, small_array.shape)]
    big_array[slices]=small_array

It may be worth noting that it's not obvious how one would want "embed" to perform in cases where big_array has more dimensions than small_array does. E.g., I could imagine someone wanting a 1:1 mapping from small_array members to overwritten members of big_array (equivalent to adding extra length-1 dimensions to small_array to bring its ndim up to that of big_array), or I could imagine someone wanting small_array to broadcast out to fill the remainder of big_array for the "missing" dimensions of small_array. Anyway, you might want to avoid calling the function in those cases, or to tweak the function to ensure it will do what you want in those cases.

Yeung answered 12/4, 2016 at 6:2 Comment(2)
That's very snazzy! Thank you for both generalizing to n dimensions, and showing me "A nicer way to build up index tuples for arrays.". If small_array has fewer dimensions nS, you'd have to indicate in which dimension of the` large_array nL the broadcast needs to be. Either way if the ndim don't match you'd need to give guidance, or accept a default of "the first nS dimensions of nL" for example. Add some size checking, and an option for wrapping (if too big), and you've got yourself a great new method!Menace
I should go back and finish this np.roll() faster thing - if you look at the mode options for scipy.ndimage.filters.convolve, they may be rough model.Menace

© 2022 - 2024 — McMap. All rights reserved.