Package: np-xarr
np-xarrPerform a numpy array transformation intuitively by giving simple patterns.Install$pipinstallnp-xarrUsage>>fromnpxarrimportX>>importnumpyasnp>>a=X('[1, 2, 3, ...]','[[1, 2], [2, 3], ...]')(np.r_[0,1,2,3,4,5])# sliding window[[0,1],[1,2],[2,3],[3,4],[4,5]]>>a=X('[[1, 2, ...],[3,4,...],...]', '[[1,3,...],[2,4,...],...]') # transpose>>a(np.array([[0,1],[2,3],[4,5]])[[024][135]]or a simpler form:>>a=X('[[a0, a1], [a1, a2], ...]')>>a=X('[[a00, a10, ...], [a01, a11, ...], ...]')whereadenotes the first input array, the number behind it denotes the index of the item.
For example,a01means the item in the first input array with index(0, 1).Multiple inputs or outputs are supported.>>a=X(['[1, 2, ...]','[a, b, ...]'],# multiple input in a list'[1, a, 2, b, ...]; [[a, 1], [b, 2], ...]')# or seperate by ;# or >> a = X('[a0, b0, a1, b1, ...]; [[b0, a0], [b1, a1], ...]')>>a([np.r_[1,2,3,4,5],np.r_[10,20,30]])# for incompatible input shapes, it can figure out the maximum valid output shape(array([1,10,2,20,3,30,4],dtype=int32),array([[10,1],[20,2],[30,3]],dtype=int32))>>a[1]([np.r_[1,2],np.r_[10,20,30])# or just get the transformation for second output[[101],[202]]Functions can be applied.>>a=X('[1, 2, 3, 4, ...]','[times(2), neg(1), times(4), neg(3), ...]',f={'neg':lambdax:-x,'times':lambdax:10*x})# a = X('[times(a1), neg(a0), times(a3), neg(a2), ...]')notice here the output with sequence [2, 1, 4, 3, ...]>>a(np.r_[0,1,2,3,4,5])[10,0,30,-2,50,-4]and unpacking>>a=X('1; 2','[*1, *2, *1]')([np.r_[1,2],np.r_[10,20]])# a = X('[*a, *b, *a]')[12102012]You can provide output shape by hand>>a=X('[1, 2, ...]','[[1, 1, ...], [2, 2, ...], ...]')# a = X('[[a0, a0, ...], [a1, a1, ...], ...]')>>a(np.arange(6),outShapes=(-1,3))# or outShapes=[(-1, 3)],[[000][111][222][333][444][555]]And by providing parameterextraShapes...>>a=X('[1, 2, 3, ...]','[[1, 2], [2, 3], ...]')# a = X('[[a0, a1], [a1, a2], ...]')>>a(np.r_[0,1,2,3],extraShapes=(1,0)))[[01][12][23][30]]How np-xarr doesWhen the pattern is given, e.g.,>>a=X('[a, b, c, ...]','[[a, b], [b, c], ...]')Xwill deduce the transformation equation between the input and output, and can be seen by>>ay0=|_x0_|+|_x1_|where|_x0_|meansfloor(x0).
The equationy0 = |_x0_| + |_x1_|build the relation between the output index(x0, x1)and the input index(y0,)as follows:output index (x0, x1)itemequation (x0, x1) -> (y0, )index (y0, )input item(0, 0)a0 + 0 = 0(0, )a(0, 1)b0 + 1 = 1(1, )b(1, 0)b1 + 0 = 1(1, )b(1, 1)c1 + 1 = 2(2, )cAnother example:>>a=X('[a, b, ...]','[a, a, b, b, ...]')>>ay0=|_0.50*x0_|output index (x0, )itemequation (x0, ) -> (y0, )input index (y0, )item(0, )afloor(0.5*0) = 0(0, )a(1, )afloor(0.5*1) = 0(0, )a(2, )bfloor(0.5*2) = 1(1, )b(3, )bfloor(0.5*3) = 2(1, )bNotes:It is recommended to write patterns with at least two periods, e.g. [1, 2, ...] -> [[1, 2], ...] will be inferred as [1, 2, 3, ...] -> [[1, 2], [2, 3], ...] rather than [[1, 2], [3, 4], ...]Inefficient for large arrayThe output array is built by code likenp.array([inArrays[indexConverter(index)] for index <= outShape])Only support transformation with formula$y_j = floor(a_ij*x_i) + b_j + floor(c_ij*mod(x_i, d_ij))$TodoImprove exception systemTry to deduce possible transformation using native numpy function from calculated equation