python 2.7 - Slicing a box of certain width along arbitrary line through 3d array -
i have big (600,600,600) numpy array filled data. extract regions given width around arbitrary line through box.
for line have x, y , z coordinates of every point in separate numpy arrays. let's line has 35 points in data box, x, y , z arrays each have lengths of 35 well. can extract points along line using indexing this
extraction = data[z,y,x] now ideally i'd extract box around doing following
extraction = data[z-3:z+3,y-3:y+3,z-3:z+3] but because x, y , z arrays, not possible. way think of of doing through for-loop each point, so
extraction = np.array([]) in range(len(x)): extraction = np.append(extraction,data[z[i]-3:z[i]+3,y[i]-3:y[i]+3,z[i]-3:z[i]+3]) and reshaping extraction array afterwards. however, slow , there overlap between each of slices in for-loop i'd prevent.
is there simple way directly without for-loop?
edit: let me rephrase question through idea came slow. have line running through datacube. have lists of x, y , z coordinates (the coordinates being indices in datacube array) points define line. example these lists this:
x_line: [345 345 345 345 342 342 342 342 342 342 342 342 342 342 342 342] y_line: [540 540 540 543 543 543 543 546 546 546 549 549 549 549 552 552] z_line: [84 84 84 87 87 87 87 87 90 90 90 90 90 93 93 93] as can see, of these coordinates identical, due lines being defined in different coordinates , binned resolution of data box. want mask cells in datacube distance larger 3 cells. single point along line (x_line[i], y_line[i], z_line[i]) relatively easy.i created meshgrid coordinates in datacube , create mask array of zeros , put satisfying condition 1:
data = np.random.rand(600,600,600) x_box,y_box,z_box = np.meshgrid(n.arange(600),n.arange(600),n.arange(600)) mask = np.zeros(np.shape(data)) in range(len(x_line)): distance = np.sqrt((x_box-x_line[i])**2 + (y_box-y_line[i])**2 + (z_box-z_line[i])**2) mask[distance <= 3] = 1. extraction = data[mask == 1.] the advantage of mask array removes problem of having duplicate extractions. however, both meshgrid , distance calculations slow. possible calculation of distance directly on entire line without having for-loop on each line point, directly masks cells within distance of 3 cells of line points?
how this?
# .shape = (n,) x, y, z = ... # offsets in [-3, 3), .shape = (6, 6, 6) xo, yo, zo = np.indices((6, 6, 6)) - 3 # box indices, .shape = (6, 6, 6, n) xb, yb, zb = x + xo[...,np.newaxis], y + yo[...,np.newaxis], z + zo[...,np.newaxis] # .shape = (6, 6, 6, n) extractions = data[xb, yb, zb] this extracts series of 6x6x6 cubes, each "centered" on coordinates in x, y, , z
this produce duplicate coordinates, , fail on cases near borders
if keep xyz in 1 array, gets little less verbose, , can remove duplicates:
# .shape = (n,3) xyz = ... # offsets in [-3, 3), .shape = (6, 6, 6, 3) xyz_offset = np.moveaxis(np.indices((6, 6, 6)) - 3, 0, -1) # box indices, .shape = (6, 6, 6, n, 3) xyz_box = xyz + xyz_offset[...,np.newaxis,:] if remove_duplicates: # shape (m, 3) xyz_box = xyz_box.reshape(-1, 3) xyz_box = np.unique(xyz_box, axis=0) xb, yb, zb = xyz_box extractions = data[xb, yb, zb]
Comments
Post a Comment