This is a useful idea certainly. I would recommended extending it to an arbitrary number of axes. You could either raise an error if the ndim of the two arrays are unequal, or allow a broadcast of a lesser ndimmed src array.
- Joe On Jun 29, 2017 20:17, "Mikhail V" <mikhail...@gmail.com> wrote: > Hello all > > I often need to copy one array into another array, given an offset. > This is how the "blit" function can be understood, i.e. in > every graphical lib there is such a function. > The common definition is like: > blit ( dest, src, offset ): > where dest is destination array, src is source array and offset is > coordinates in destination where the src should pe blitted. > Main feature of such function is that it never gives an error, > so if the source does not fit into the destination array, it is simply > trimmed. > And respectively if there is no intersection area then nothing happens. > > Hope this is clear. > So to make it work with Numpy arrays one need to calculate the > slices before copying the data. > I cannot find any Numpy or Python method to help with that so probably > it does not exist yet. > If so, my proposal is to add a Numpy method which helps with that. > Namely the proposal will be to add a method which returns > the slices for the intersection areas of two arbitrary arrays, given an > offset, > so then one can "blit" the array into another with simple assignment =. > > Here is a Python function I use for 2d arrays now: > > def interslice ( dest, src, offset ): > y,x = offset > H,W = dest.shape > h,w = src.shape > > dest_starty = max (y,0) > dest_endy = min (y+h,H) > dest_startx = max (x,0) > dest_endx = min (x+w,W) > > src_starty = 0 > src_endy = h > if y<0: src_starty = -y > by = y+h - H # Y bleed > if by>0: src_endy = h - by > > src_startx = 0 > src_endx = w > if x<0: src_startx = -x > bx = x+w - W # X bleed > if bx>0: src_endx = w - bx > > dest_sliceY = slice(dest_starty,dest_endy) > dest_sliceX = slice(dest_startx,dest_endx) > src_sliceY = slice(src_starty, src_endy) > src_sliceX = slice(src_startx, src_endx) > if dest_endy <= dest_starty: > print "No Y intersection !" > dest_sliceY = ( slice(0, 0) ) > src_sliceY = ( slice(0, 0) ) > if dest_endx <= dest_startx: > print "No X intersection !" > dest_sliceX = ( slice(0, 0) ) > src_sliceX = ( slice(0, 0) ) > dest_slice = ( dest_sliceY, dest_sliceX ) > src_slice = ( src_sliceY, src_sliceX ) > return ( dest_slice, src_slice ) > > > ------ > > I have intentionally made it expanded and without contractions > so that it is better understandable. > It returns the intersection area of two arrays given an offset. > First returned tuple element is the slice for DEST array and the > second element is the slice for SRC array. > If there is no intersection along one of the axis at all > it returns the corresponding slice as (0,0) > > With this helper function one can blit arrays easily e.g. example code: > > W = 8; H = 8 > DEST = numpy.ones([H,W], dtype = "uint8") > w = 4; h = 1 > SRC = numpy.zeros([h,w], dtype = "uint8") > SRC[:]=8 > offset = (0,9) > ds, ss = interslice (DEST, SRC, offset ) > > # blit SRC into DEST > DEST[ds] = SRC[ss] > > So changing the offset one can observe how the > SRC array is trimmed if it is crosses the DEST boundaries. > I think it is very useful function in general and it has > well defined behaviour. It has usage not only for graphics, > but actually any data copying-pasting between arrays. > > So I am looking forward to comments on this proposal. > > > Mikhail > _______________________________________________ > NumPy-Discussion mailing list > NumPy-Discussion@python.org > https://mail.python.org/mailman/listinfo/numpy-discussion >
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion