- Notifications
You must be signed in to change notification settings - Fork 50
100 narray exercises
This is Ruby/Numo::NArray version of 100 numpy exercises (Repository)
# 100 numpy exercises This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow and in the numpy documentation. I've also created some to reach the 100 limit. The goal of this collection is to offer a quick reference for both old and new users but also to provide a set of exercices for those who teach. If you find an error or think you've a better way to solve some of them, feel free to open an issue at <https://github.com/rougier/numpy-100> Python:
import numpy as npRuby:
require "numo/narray"Python:
print(np.__version__) np.show_config()Ruby:
p Numo::NArray::VERSIONPython:
Z = np.zeros(10) print(Z)Ruby:
z = Numo::DFloat.zeros(10) p zPython:
Z = np.zeros((10,10)) print("%d bytes" % (Z.size * Z.itemsize))Ruby:
z = Numo::DFloat.zeros(10,10) printf "%d bytes", z.byte_sizePython:
$ python -c "import numpy; numpy.info(numpy.add)"
Ruby:
$ ri 'Numo::DFloat#+'
Python:
Z = np.zeros(10) Z[4] = 1 print(Z)Ruby:
z = Numo::DFloat.zeros(10) z[4] = 1 p zPython:
Z = np.arange(10,50) print(Z)Ruby:
z = Numo::DFloat[10..49] p zPython:
Z = np.arange(50) Z = Z[::-1] print(Z)Ruby:
z = Numo::Int32.new(50).seq z = z.reverse # or z = z[(-1..0).step(-1)]Python:
Z = np.arange(9).reshape(3,3) print(Z)Ruby:
z = Numo::Int32.new(3,3).seq p zPython:
nz = np.nonzero([1,2,0,0,4,0]) print(nz)Ruby:
nz = Numo::NArray[1,2,0,0,4,0].ne(0).where p nzPython:
Z = np.eye(3) print(Z)Ruby:
z = Numo::DFloat.eye(3) p zPython:
Z = np.random.random((3,3,3)) print(Z)Ruby:
z = Numo::DFloat.new(3,3,3).rand p zPython:
Z = np.random.random((10,10)) Zmin, Zmax = Z.min(), Z.max() print(Zmin, Zmax)Ruby:
z = Numo::DFloat.new(10,10).rand zmin, zmax = z.minmax p zmin, zmaxPython:
Z = np.random.random(30) m = Z.mean() print(m)Ruby:
z = Numo::DFloat.new(30).rand m = z.mean p mPython:
Z = np.ones((10,10)) Z[1:-1,1:-1] = 0 print(Z)Ruby:
z = Numo::DFloat.ones(10,10) z[1..-2,1..-2] = 0 p zPython:
Z = np.ones((5,5)) Z = np.pad(Z, pad_width=1, mode='constant', constant_values=0) print(Z)Ruby:
# todo: padPython:
print(0 * np.nan) print(np.nan == np.nan) print(np.inf > np.nan) print(np.nan - np.nan) print(0.3 == 3 * 0.1)Ruby:
0 * Float::NAN Float::NAN == Float::NAN Float::INFINITY > Float::NAN Float::NAN - Float::NAN 0.3 == 3 * 0.1Python:
Z = np.diag(1+np.arange(4),k=-1) print(Z)Ruby:
z = Numo::Int32.zeros(5,5) z.diagonal(-1)[] = Numo::Int32[1..4] p zPython:
Z = np.zeros((8,8),dtype=int) Z[1::2,::2] = 1 Z[::2,1::2] = 1 print(Z)Ruby:
z = Numo::Int32.zeros(8,8) z[(1..-1).step(2),(0..-1).step(2)] = 1 z[(0..-1).step(2),(1..-1).step(2)] = 1 p z # z = (Numo::Int32.new(1,8).seq + Numo::Int32.new(8,1).seq) % 2 # p zPython:
print(np.unravel_index(100,(6,7,8)))Ruby:
# NArray allows unraveled index access z = Numo::Int32.new(6,7,8).seq p z[100]Python:
Z = np.tile( np.array([[0,1],[1,0]]), (4,4)) print(Z)Ruby:
z = Numo::NArray[[0,1],[1,0]].tile(4,4) p zPython:
Z = np.random.random((5,5)) Zmax, Zmin = Z.max(), Z.min() Z = (Z - Zmin)/(Zmax - Zmin) print(Z)Ruby:
z = Numo::DFloat.new(5,5).rand zmin, zmax = z.minmax z = (z - zmin)/(zmax - zmin) p zPython:
color = np.dtype([("r", np.ubyte, 1), ("g", np.ubyte, 1), ("b", np.ubyte, 1), ("a", np.ubyte, 1)])Ruby:
# todo: record color = Numo::Struct.new do uint8 "r" uint8 "g" uint8 "b" uint8 "a" endPython:
Z = np.dot(np.ones((5,3)), np.ones((3,2))) print(Z)Ruby:
x = Numo::DFloat.ones(5,3) y = Numo::DFloat.ones(3,2) z = x.dot y p zPython:
# Author: Evgeni Burovski Z = np.arange(11) Z[(3 < Z) & (Z <= 8)] *= -1 print(Z)Ruby:
z = Numo::Int32.new(11).seq z[(3 < z) & (z <= 8)] *= -1 p zPython:
# Author: Jake VanderPlas print(sum(range(5),-1)) from numpy import * print(sum(range(5),-1))Ruby:
p [*0...5,-1].inject(:+) p Numo::Int32[0...5].sum(-1)Python:
Z = np.arange(5) Z**Z 2 << Z >> 2 Z <- Z 1j*Z Z/1/1 Z<Z>ZRuby:
z = Numo::Int32.new(5).seq z**z 2 << z >> 2 z <- z 1i*z z/1/1 z<z>zPython:
print(np.array(0) / np.array(0)) print(np.array(0) // np.array(0)) print(np.array([np.nan]).astype(int).astype(float))Ruby:
p Numo::Int32[0] / Numo::Int32[0] p Numo::DFloat[Float::NAN].cast_to(Numo::Int32).cast_to(Numo::DFloat)Python:
# Author: Charles R Harris Z = np.random.uniform(-10,+10,10) print (np.trunc(Z + np.copysign(0.5, Z)))Ruby:
z = Numo::DFloat.new(10).seq(-10,2.1) #rand(-10,+10) p (z + Numo::DFloat[0.5].copysign(z)).truncPython:
Z1 = np.random.randint(0,10,10) Z2 = np.random.randint(0,10,10) print(np.intersect1d(Z1,Z2))Ruby:
# todo: intersect1dPython:
# Suicide mode on defaults = np.seterr(all="ignore") Z = np.ones(1)/0 # Back to sanity _ = np.seterr(**defaults)Ruby:
# ?Python:
np.sqrt(-1) == np.emath.sqrt(-1)Ruby:
# NAPython:
yesterday = np.datetime64('today', 'D') - np.timedelta64(1, 'D') today = np.datetime64('today', 'D') tomorrow = np.datetime64('today', 'D') + np.timedelta64(1, 'D')Ruby:
# use built-in class require "date" yesterday = Date.today - 1 today = Date.today tomorrow = Date.today + 1Python:
Z = np.arange('2016-07', '2016-08', dtype='datetime64[D]') print(Z)Ruby:
# use built-in class require "date" z = *Date.new(2016,7)..Date.new(2016,8) p zPython:
A = np.ones(3)*1 B = np.ones(3)*2 np.add(A,B,out=B) np.divide(A,2,out=A) np.negative(A,out=A) np.multiply(A,B,out=A)Ruby:
a = Numo::DFloat.new(3).fill(1) b = Numo::DFloat.new(3).fill(2) p (a+b)*(-a/2) (a+b.inplace)*(-a.inplace/2) p bPython:
Z = np.random.uniform(0,10,10) print (Z - Z%1) print (np.floor(Z)) print (np.ceil(Z)-1) print (Z.astype(int)) print (np.trunc(Z))Ruby:
z = Numo::DFloat.new(10).rand(10) p z - z%1 p z.floor p z.ceil - 1 p z.cast_to(Numo::Int32) p z.truncPython:
Z = np.zeros((5,5)) Z += np.arange(5) print(Z)Ruby:
z = Numo::DFloat.zeros(5,5) z += Numo::Int32.new(5).seq p zPython:
def generate(): for x in range(10): yield x Z = np.fromiter(generate(),dtype=float,count=-1) print(Z)Ruby:
# no method: fromiter generate = Enumerator.new do |y| 10.times{|x| y << x} end z = Numo::DFloat[*generate] p zPython:
Z = np.linspace(0,1,12,endpoint=True)[1:-1] print(Z)Ruby:
z = Numo::DFloat.linspace(0,1,12)[1..-2] p zPython:
Z = np.random.random(10) Z.sort() print(Z)Ruby:
z = Numo::DFloat.new(10).rand z = z.sort p zPython:
# Author: Evgeni Burovski Z = np.arange(10) np.add.reduce(Z)Ruby:
z = Numo::Int32.new(10).seq z.sum # speed?Python:
A = np.random.randint(0,2,5) B = np.random.randint(0,2,5) equal = np.allclose(A,B) print(equal)Ruby:
a = Numo::Int32.new(5).rand(2) b = Numo::Int32.new(5).rand(2) equal = a.eq(b).all? p equalPython:
Z = np.zeros(10) Z.flags.writeable = False Z[0] = 1Ruby:
z = Numo::DFloat.zeros(10) z.freeze z[0] = 144. Consider a random 10x2 matrix representing cartesian coordinates, convert them to polar coordinates (★★☆)
Python:
Z = np.random.random((10,2)) X,Y = Z[:,0], Z[:,1] R = np.sqrt(X**2+Y**2) T = np.arctan2(Y,X) print(R) print(T)Ruby:
z = Numo::DFloat.new(10,2).rand x,y = z[true,0], z[true,1] r = Numo::NMath.sqrt(x**2+y**2) t = Numo::NMath.atan2(y,x) p r p tPython:
Z = np.random.random(10) Z[Z.argmax()] = 0 print(Z)Ruby:
z = Numo::DFloat.new(10).rand z[z.max_index] = 0 p zPython:
Z = np.zeros((5,5), [('x',float),('y',float)]) Z['x'], Z['y'] = np.meshgrid(np.linspace(0,1,5), np.linspace(0,1,5)) print(Z)Ruby:
# todo: meshgridPython:
# Author: Evgeni Burovski X = np.arange(8) Y = X + 0.5 C = 1.0 / np.subtract.outer(X, Y) print(np.linalg.det(C))Ruby:
# todo: linalg.detPython:
for dtype in [np.int8, np.int32, np.int64]: print(np.iinfo(dtype).min) print(np.iinfo(dtype).max) for dtype in [np.float32, np.float64]: print(np.finfo(dtype).min) print(np.finfo(dtype).max) print(np.finfo(dtype).eps)Ruby:
# todo: Int32::MIN/MAX, etcPython:
np.set_printoptions(threshold=np.nan) Z = np.zeros((16,16)) print(Z)Ruby:
Numo::NArray.inspect_cols = nil Numo::NArray.inspect_rows = nil z = Numo::DFloat.zeros(25,25) p zPython:
Z = np.arange(100) v = np.random.uniform(0,100) index = (np.abs(Z-v)).argmin() print(Z[index])Ruby:
z = Numo::Int32.new(100).seq v = rand*100 index = (z-v).abs.min_index p z[index]Python:
Z = np.zeros(10, [ ('position', [ ('x', float, 1), ('y', float, 1)]), ('color', [ ('r', float, 1), ('g', float, 1), ('b', float, 1)])]) print(Z)Ruby:
# todo: record52. Consider a random vector with shape (100,2) representing coordinates, find point by point distances (★★☆)
Python:
Z = np.random.random((10,2)) X,Y = np.atleast_2d(Z[:,0]), np.atleast_2d(Z[:,1]) D = np.sqrt( (X-X.T)**2 + (Y-Y.T)**2) print(D) # Much faster with scipy import scipy # Thanks Gavin Heverly-Coulson (#issue 1) import scipy.spatial Z = np.random.random((10,2)) D = scipy.spatial.distance.cdist(Z,Z) print(D)Ruby:
# todo: cdistPython:
Z = np.arange(10, dtype=np.int32) Z = Z.astype(np.float32, copy=False) print(Z)Ruby:
# NArray does not support in-place type conversionPython:
from io import StringIO # Fake file s = StringIO("""1, 2, 3, 4, 5\n 6, , , 7, 8\n , , 9,10,11\n""") Z = np.genfromtxt(s, delimiter=",", dtype=np.int) print(Z)Ruby:
require "stringio" s = StringIO.new("1, 2, 3, 4, 5 6, , , 7, 8 , , 9,10,11") z = Numo::NArray[*s.readlines.map{|l| l.split(",").map{|x| x.strip.empty? ? Float::NAN : x.to_f}}]Python:
Z = np.arange(9).reshape(3,3) for index, value in np.ndenumerate(Z): print(index, value) for index in np.ndindex(Z.shape): print(index, Z[index])Ruby:
z = Numo::Int32.new(3,3).seq z.each_with_index{|x,*i| p [i,x]}Python:
X, Y = np.meshgrid(np.linspace(-1,1,10), np.linspace(-1,1,10)) D = np.sqrt(X*X+Y*Y) sigma, mu = 1.0, 0.0 G = np.exp(-( (D-mu)**2 / ( 2.0 * sigma**2 ) ) ) print(G)Ruby:
x = Numo::DFloat.linspace(-1,1,10) y = Numo::DFloat.linspace(-1,1,10).expand_dims(1) d = Numo::NMath.sqrt(x*x+y*y) sigma, mu = 1.0, 0.0 g = Numo::NMath.exp(-( (d-mu)**2 / ( 2.0 * sigma**2 ) ) ) p gPython:
# Author: Divakar n = 10 p = 3 Z = np.zeros((n,n)) np.put(Z, np.random.choice(range(n*n), p, replace=False),1) print(Z)Ruby:
# todo: choisePython:
# Author: Warren Weckesser X = np.random.rand(5, 10) # Recent versions of numpy Y = X - X.mean(axis=1, keepdims=True) # Older versions of numpy Y = X - X.mean(axis=1).reshape(-1, 1) print(Y)Ruby:
x = Numo::DFloat.new(5, 10).rand y = x - x.mean(1).expand_dims(1)Python:
# Author: Steve Tjoa Z = np.random.randint(0,10,(3,3)) print(Z) print(Z[Z[:,1].argsort()])Ruby:
z = Numo::Int32.new(3,3).rand(10) p z p z[z[true,1].sort_index,true]Python:
# Author: Warren Weckesser Z = np.random.randint(0,3,(3,10)) print((~Z.any(axis=0)).any())Ruby:
z = Numo::Int32.new(3,10).rand(3) (~z.ne(0).any?(0)).any?Python:
Z = np.random.uniform(0,1,10) z = 0.5 m = Z.flat[np.abs(Z - z).argmin()] print(m)Ruby:
z = Numo::DFloat.new(10).rand x = 0.5 m = z[(z - x).abs.min_index] p m62. Considering two arrays with shape (1,3) and (3,1), how to compute their sum using an iterator? (★★☆)
Python:
A = np.arange(3).reshape(3,1) B = np.arange(3).reshape(1,3) it = np.nditer([A,B,None]) for x,y,z in it: z[...] = x + y print(it.operands[2])Ruby:
# no iteratorPython:
class NamedArray(np.ndarray): def __new__(cls, array, name="no name"): obj = np.asarray(array).view(cls) obj.name = name return obj def __array_finalize__(self, obj): if obj is None: return self.info = getattr(obj, 'name', "no name") Z = NamedArray(np.arange(10), "range_10") print (Z.name)Ruby:
module NamedArray attr_accessor :name end def NamedArray(array,name) obj = array.extend(NamedArray) obj.name = name return obj end z = NamedArray(Numo::NArray[0...10], "range_10") p z.name # todo: asarray64. Consider a given vector, how to add 1 to each element indexed by a second vector (be careful with repeated indices)? (★★★)
Python:
# Author: Brett Olsen Z = np.ones(10) I = np.random.randint(0,len(Z),20) Z += np.bincount(I, minlength=len(Z)) print(Z)Ruby:
z = Numo::Int32.ones(10) i = Numo::Int32.new(20).rand(0,z.size) z += i.bincount(minlength:z.size)Python:
# Author: Alan G Isaac X = [1,2,3,4,5,6] I = [1,3,9,3,4,1] F = np.bincount(I,X) print(F)Ruby:
x = [1,2,3,4,5,6] i = [1,3,9,3,4,1] f = Numo::NArray[*i].bincount(x) p fPython:
# Author: Nadav Horesh w,h = 16,16 I = np.random.randint(0,2,(h,w,3)).astype(np.ubyte) F = I[...,0]*256*256 + I[...,1]*256 +I[...,2] n = len(np.unique(F)) print(np.unique(I))Ruby:
# todo: unique w,h = 16,16 i = Numo::UInt32.new(h,w,3).rand(2) f = i[false,0]*256*256 + i[false,1]*256 +i[false,2] p f.flatten.sort.to_a.uniqPython:
A = np.random.randint(0,10,(3,4,3,4)) sum = A.reshape(A.shape[:-2] + (-1,)).sum(axis=-1) print(sum)Ruby:
a = Numo::Int32.new(3,4,3,4).rand(10) sum = a.sum(-2,-1) p sum68. Considering a one-dimensional vector D, how to compute means of subsets of D using a vector S of same size describing subset indices? (★★★)
Python:
# Author: Jaime Fernández del Río D = np.random.uniform(0,1,100) S = np.random.randint(0,10,100) D_sums = np.bincount(S, weights=D) D_counts = np.bincount(S) D_means = D_sums / D_counts print(D_means)Ruby:
d = Numo::DFloat.new(100).rand(0,1) s = Numo::Int32.new(100).rand(0,10) d_sums = s.bincount(d) d_counts = s.bincount d_means = d_sums / d_counts p d_meansPython:
# Author: Mathieu Blondel A = np.random.uniform(0,1,(5,5)) B = np.random.uniform(0,1,(5,5)) # Slow version np.diag(np.dot(A, B)) # Fast version np.sum(A * B.T, axis=1) # Faster version np.einsum("ij,ji->i", A, B)Ruby:
a = Numo::DFloat.new(3,3).seq b = Numo::DFloat.new(3,3).seq p a.mulsum(b.transpose,1) # speed?70. Consider the vector [1, 2, 3, 4, 5], how to build a new vector with 3 consecutive zeros interleaved between each value? (★★★)
Python:
# Author: Warren Weckesser Z = np.array([1,2,3,4,5]) nz = 3 Z0 = np.zeros(len(Z) + (len(Z)-1)*(nz)) Z0[::nz+1] = Z print(Z0)Ruby:
z = Numo::NArray[1,2,3,4,5] nz = 3 z0 = Numo::Int32.zeros(z.size + (z.size-1)*(nz)) z0[(0..-1).step(nz+1)] = z p z071. Consider an array of dimension (5,5,3), how to mulitply it by an array with dimensions (5,5)? (★★★)
Python:
A = np.ones((5,5,3)) B = 2*np.ones((5,5)) print(A * B[:,:,None])Ruby:
a = Numo::Int32.ones(5,5,3) b = Numo::Int32.new(5,5).fill(2) p a * b[:*,:*,:-]Python:
# Author: Eelco Hoogendoorn A = np.arange(25).reshape(5,5) A[[0,1]] = A[[1,0]] print(A)Ruby:
a = Numo::Int32.new(5,5).seq a[[0,1],true] = a[[1,0],true].copy p a # todo: identity check between read/write array73. Consider a set of 10 triplets describing 10 triangles (with shared vertices), find the set of unique line segments composing all the triangles (★★★)
Python:
# Author: Nicolas P. Rougier faces = np.random.randint(0,100,(10,3)) F = np.roll(faces.repeat(2,axis=1),-1,axis=1) F = F.reshape(len(F)*3,2) F = np.sort(F,axis=1) G = F.view( dtype=[('p0',F.dtype),('p1',F.dtype)] ) G = np.unique(G) print(G)Ruby:
# todo: roll74. Given an array C that is a bincount, how to produce an array A such that np.bincount(A) == C? (★★★)
Python:
# Author: Jaime Fernández del Río C = np.bincount([1,1,2,3,4,4,6]) A = np.repeat(np.arange(len(C)), C) print(A)Ruby:
a = Numo::NArray[1,1,2,3,4,4,6] c = a.bincount a = a.seq.repeat(c) p aPython:
# Author: Jaime Fernández del Río def moving_average(a, n=3) : ret = np.cumsum(a, dtype=float) ret[n:] = ret[n:] - ret[:-n] return ret[n - 1:] / n Z = np.arange(20) print(moving_average(Z, n=3))Ruby:
def moving_average(a, n=3) ret = a.cumsum ret[n..-1] = ret[n..-1] - ret[0..-n-1] ret[n-1..-1] / n end z = Numo::DFloat.new(20).seq p moving_average(z, 3)76. Consider a one-dimensional array Z, build a two-dimensional array whose first row is (Z[0],Z[1],Z[2]) and each subsequent row is shifted by 1 (last row should be (Z[-3],Z[-2],Z[-1]) (★★★)
Python:
# Author: Joe Kington / Erik Rigtorp from numpy.lib import stride_tricks def rolling(a, window): shape = (a.size - window + 1, window) strides = (a.itemsize, a.itemsize) return stride_tricks.as_strided(a, shape=shape, strides=strides) Z = rolling(np.arange(10), 3) print(Z)Ruby:
# no module: stride_tricksPython:
# Author: Nathaniel J. Smith Z = np.random.randint(0,2,100) np.logical_not(Z, out=Z) Z = np.random.uniform(-1.0,1.0,100) np.negative(Z, out=Z)Ruby:
# todo: logical_not z = Numo::Int32.new(100).rand(2) p z z.inplace ^ 1 p z z = Numo::DFloat.new(100).rand(-1,1) p z -z.inplace p z78. Consider 2 sets of points P0,P1 describing lines (2d) and a point p, how to compute distance from p to each line i (P0[i],P1[i])? (★★★)
Python:
def distance(P0, P1, p): T = P1 - P0 L = (T**2).sum(axis=1) U = -((P0[:,0]-p[...,0])*T[:,0] + (P0[:,1]-p[...,1])*T[:,1]) / L U = U.reshape(len(U),1) D = P0 + U*T - p return np.sqrt((D**2).sum(axis=1)) P0 = np.random.uniform(-10,10,(10,2)) P1 = np.random.uniform(-10,10,(10,2)) p = np.random.uniform(-10,10,( 1,2)) print(distance(P0, P1, p))Ruby:
def distance(p0, p1, p) t = p1 - p0 l = (t**2).sum(1) u = -((p0[true,0]-p[false,0])*t[true,0] + (p0[true,1]-p[false,1])*t[true,1]) / l u = u.reshape(u.size,1) d = p0 + u*t - p return Numo::NMath.sqrt((d**2).sum(1)) end p0 = Numo::DFloat.new(10,2).rand(-10,10) p1 = Numo::DFloat.new(10,2).rand(-10,10) p = Numo::DFloat.new( 1,2).rand(-10,10) p distance(p0, p1, p)79. Consider 2 sets of points P0,P1 describing lines (2d) and a set of points P, how to compute distance from each point j (P[j]) to each line i (P0[i],P1[i])? (★★★)
Python:
# Author: Italmassov Kuanysh # based on distance function from previous question P0 = np.random.uniform(-10, 10, (10,2)) P1 = np.random.uniform(-10,10,(10,2)) p = np.random.uniform(-10, 10, (10,2)) print(np.array([distance(P0,P1,p_i) for p_i in p]))Ruby:
p0 = Numo::DFloat.new(10,2).rand(-10,10) p1 = Numo::DFloat.new(10,2).rand(-10,10) p = Numo::DFloat.new(10,2).rand(-10,10) p Numo::NArray[*(0...p.shape[0]).map{|i| distance(p0, p1, p[i,true])}]80. Consider an arbitrary array, write a function that extract a subpart with a fixed shape and centered on a given element (pad with a fill value when necessary) (★★★)
Python:
# Author: Nicolas Rougier Z = np.random.randint(0,10,(10,10)) shape = (5,5) fill = 0 position = (1,1) R = np.ones(shape, dtype=Z.dtype)*fill P = np.array(list(position)).astype(int) Rs = np.array(list(R.shape)).astype(int) Zs = np.array(list(Z.shape)).astype(int) R_start = np.zeros((len(shape),)).astype(int) R_stop = np.array(list(shape)).astype(int) Z_start = (P-Rs//2) Z_stop = (P+Rs//2)+Rs%2 R_start = (R_start - np.minimum(Z_start,0)).tolist() Z_start = (np.maximum(Z_start,0)).tolist() R_stop = np.maximum(R_start, (R_stop - np.maximum(Z_stop-Zs,0))).tolist() Z_stop = (np.minimum(Z_stop,Zs)).tolist() r = [slice(start,stop) for start,stop in zip(R_start,R_stop)] z = [slice(start,stop) for start,stop in zip(Z_start,Z_stop)] R[r] = Z[z] print(Z) print(R)Ruby:
# todo: minimum, maximum81. Consider an array Z = [1,2,3,4,5,6,7,8,9,10,11,12,13,14], how to generate an array R = 1,2,3,4], [2,3,4,5], [3,4,5,6], ..., [11,12,13,14? (★★★)
Python:
# Author: Stefan van der Walt Z = np.arange(1,15,dtype=np.uint32) R = stride_tricks.as_strided(Z,(11,4),(4,4)) print(R)Ruby:
# no moudle: stride_tricksPython:
# Author: Stefan van der Walt Z = np.random.uniform(0,1,(10,10)) U, S, V = np.linalg.svd(Z) # Singular Value Decomposition rank = np.sum(S > 1e-10) print(rank)Ruby:
# todo: svdPython:
Z = np.random.randint(0,10,50) print(np.bincount(Z).argmax())Ruby:
z = Numo::Int32.new(50).rand(0,10) z.bincount.max_indexPython:
# Author: Chris Barker Z = np.random.randint(0,5,(10,10)) n = 3 i = 1 + (Z.shape[0]-3) j = 1 + (Z.shape[1]-3) C = stride_tricks.as_strided(Z, shape=(i, j, n, n), strides=Z.strides + Z.strides) print(C)Ruby:
# no module: stride_tricksPython:
# Author: Eric O. Lebigot # Note: only works for 2d array and value setting using indices class Symetric(np.ndarray): def __setitem__(self, index, value): i,j = index super(Symetric, self).__setitem__((i,j), value) super(Symetric, self).__setitem__((j,i), value) def symetric(Z): return np.asarray(Z + Z.T - np.diag(Z.diagonal())).view(Symetric) S = symetric(np.random.randint(0,10,(5,5))) S[2,3] = 42 print(S)Ruby:
module Symetric def []=(i,j,value) super(i,j,value) super(j,i,value) if i != j end end def symetric(z) y = z + z.transpose y.diagonal.store(z.diagonal) y.extend(Symetric) end s = symetric(Numo::Int32.new(5,5).rand(10)) s[2,3] = 42 p s86. Consider a set of p matrices wich shape (n,n) and a set of p vectors with shape (n,1). How to compute the sum of of the p matrix products at once? (result has shape (n,1)) (★★★)
Python:
# Author: Stefan van der Walt p, n = 10, 20 M = np.ones((p,n,n)) V = np.ones((p,n,1)) S = np.tensordot(M, V, axes=[[0, 2], [0, 1]]) print(S) # It works, because: # M is (p,n,n) # V is (p,n,1) # Thus, summing over the paired axes 0 and 0 (of M and V independently), # and 2 and 1, to remain with a (n,1) vector.Ruby:
p, n = 10, 20 m = Numo::DFloat.ones(p,n,n) v = Numo::DFloat.ones(p,n,1) s = m.transpose(0,2,1).mulsum(v,0,1) p s # todo: tensordot?Python:
# Author: Robert Kern Z = np.ones((16,16)) k = 4 S = np.add.reduceat(np.add.reduceat(Z, np.arange(0, Z.shape[0], k), axis=0), np.arange(0, Z.shape[1], k), axis=1) print(S)Ruby:
n, k = 16, 4 z = Numo::DFloat.ones(n,n) s = z.reshape(n/k,k,n/k,k).sum(1,3) # todo: reduceat?Python:
# Author: Nicolas Rougier def iterate(Z): # Count neighbours N = (Z[0:-2,0:-2] + Z[0:-2,1:-1] + Z[0:-2,2:] + Z[1:-1,0:-2] + Z[1:-1,2:] + Z[2: ,0:-2] + Z[2: ,1:-1] + Z[2: ,2:]) # Apply rules birth = (N==3) & (Z[1:-1,1:-1]==0) survive = ((N==2) | (N==3)) & (Z[1:-1,1:-1]==1) Z[...] = 0 Z[1:-1,1:-1][birth | survive] = 1 return Z Z = np.random.randint(0,2,(50,50)) for i in range(100): Z = iterate(Z) print(Z)Ruby:
def iterate(z) # Count neighbours n = z[0..-3,0..-3] + z[0..-3,1..-2] + z[0..-3,2..-1] + z[1..-2,0..-3] + z[1..-2,2..-1] + z[2..-1,0..-3] + z[2..-1,1..-2] + z[2..-1,2..-1] # Apply rules birth = n.eq(3) & z[1..-2,1..-2].eq(0) survive = (n.eq(2) | n.eq(3)) & z[1..-2,1..-2].eq(1) z[] = 0 #z[1..-2,1..-2][birth | survive] = 1 y = z[0..-3,0..-3].copy y[birth | survive] = 1 z[1..-2,1..-2] = y end z = Numo::Int32.new(50,50).rand(2) 100.times{ iterate(z) } p zPython:
Z = np.arange(10000) np.random.shuffle(Z) n = 5 # Slow print (Z[np.argsort(Z)[-n:]]) # Fast print (Z[np.argpartition(-Z,n)[:n]])Ruby:
z = Numo::DFloat.new(10000).rand n = 5 p z[z.sort_index[-n..-1]] # todo: shuffle, argpartition90. Given an arbitrary number of vectors, build the cartesian product (every combinations of every item) (★★★)
Python:
# Author: Stefan Van der Walt def cartesian(arrays): arrays = [np.asarray(a) for a in arrays] shape = (len(x) for x in arrays) ix = np.indices(shape, dtype=int) ix = ix.reshape(len(arrays), -1).T for n, arr in enumerate(arrays): ix[:, n] = arrays[n][ix[:, n]] return ix print (cartesian(([1, 2, 3], [4, 5], [6, 7])))Ruby:
def cartesian(*arrays) arrays = arrays.map{|a| Numo::Int32.cast(a)} shape = arrays.map{|x| x.size} asz = arrays.size ix = Numo::Int32.zeros(*shape, asz) arrays.each_with_index do |arr,n| s = [1]*asz s[n] = arr.size ix[false,n] = arr.reshape(*s) end return ix.reshape(ix.size/asz,asz) end p cartesian([1, 2, 3], [4, 5], [6, 7])Python:
Z = np.array([("Hello", 2.5, 3), ("World", 3.6, 2)]) R = np.core.records.fromarrays(Z.T, names='col1, col2, col3', formats = 'S8, f8, i8') print(R)Ruby:
# todo: recordPython:
# Author: Ryan G. x = np.random.rand(5e7) %timeit np.power(x,3) %timeit x*x*x %timeit np.einsum('i,i,i->i',x,x,x)Ruby:
x = Numo::DFloat.new(5e7).rand x**3 # probably fast93. Consider two arrays A and B of shape (8,3) and (2,2). How to find rows of A that contain elements of each row of B regardless of the order of the elements in B? (★★★)
Python:
# Author: Gabe Schwartz A = np.random.randint(0,5,(8,3)) B = np.random.randint(0,5,(2,2)) C = (A[..., np.newaxis, np.newaxis] == B) rows = (C.sum(axis=(1,2,3)) >= B.shape[1]).nonzero()[0] print(rows)Ruby:
a = Numo::Int32.new(8,3).rand(5) b = Numo::Int32.new(2,2).rand(5) c = a[false,:new,:new].eq b rows = (c.count_true(1,2,3) >= b.shape[1]).where p rowsPython:
# Author: Robert Kern Z = np.random.randint(0,5,(10,3)) E = np.logical_and.reduce(Z[:,1:] == Z[:,:-1], axis=1) U = Z[~E] print(Z) print(U)Ruby:
z = Numo::Int32.new(10,3).rand(5) e = (z[true,1..-1].eq z[true,0..-2]).all?(1) u = z[(~e).where,true] p z p uPython:
# Author: Warren Weckesser I = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128]) B = ((I.reshape(-1,1) & (2**np.arange(8))) != 0).astype(int) print(B[:,::-1]) # Author: Daniel T. McDonald I = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128], dtype=np.uint8) print(np.unpackbits(I[:, np.newaxis], axis=1))Ruby:
i = Numo::NArray[0, 1, 2, 3, 15, 16, 32, 64, 128] b = Numo::Int32.cast((i[true,:new] & (2**Numo::Int32.new(8).seq)).ne 0) p b.reverse(1) i = Numo::UInt8[0, 1, 2, 3, 15, 16, 32, 64, 128] p Numo::Bit.from_binary(i.to_binary,[i.size,8]).reverse(1)Python:
# Author: Jaime Fernández del Río Z = np.random.randint(0,2,(6,3)) T = np.ascontiguousarray(Z).view(np.dtype((np.void, Z.dtype.itemsize * Z.shape[1]))) _, idx = np.unique(T, return_index=True) uZ = Z[idx] print(uZ)Ruby:
# todo: unique row97. Considering 2 vectors A & B, write the einsum equivalent of inner, outer, sum, and mul function (★★★)
Python:
# Author: Alex Riley # Make sure to read: http://ajcr.net/Basic-guide-to-einsum/ A = np.random.uniform(0,1,10) B = np.random.uniform(0,1,10) np.einsum('i->', A) # np.sum(A) np.einsum('i,i->i', A, B) # A * B np.einsum('i,i', A, B) # np.inner(A, B) np.einsum('i,j', A, B) # np.outer(A, B)Ruby:
# no method: einsum a = Numo::DFloat.new(10).rand(0,1) b = Numo::DFloat.new(10).rand(0,1) a.sum # np.sum(A) a*b # A * B a.mulsum(b) # np.inner(A, B) a[false,:new]*b # np.outer(A, B)98. Considering a path described by two vectors (X,Y), how to sample it using equidistant samples (★★★)?
Python:
# Author: Bas Swinckels phi = np.arange(0, 10*np.pi, 0.1) a = 1 x = a*phi*np.cos(phi) y = a*phi*np.sin(phi) dr = (np.diff(x)**2 + np.diff(y)**2)**.5 # segment lengths r = np.zeros_like(x) r[1:] = np.cumsum(dr) # integrate path r_int = np.linspace(0, r.max(), 200) # regular spaced path x_int = np.interp(r_int, r, x) # integrate path y_int = np.interp(r_int, r, y)Ruby:
# todo: interp99. Given an integer n and a 2D array X, select from X the rows which can be interpreted as draws from a multinomial distribution with n degrees, i.e., the rows which only contain integers and which sum to n. (★★★)
Python:
# Author: Evgeni Burovski X = np.asarray([[1.0, 0.0, 3.0, 8.0], [2.0, 0.0, 1.0, 1.0], [1.5, 2.5, 1.0, 0.0]]) n = 4 M = np.logical_and.reduce(np.mod(X, 1) == 0, axis=-1) M &= (X.sum(axis=-1) == n) print(X[M])Ruby:
x = Numo::NArray[[1.0, 0.0, 3.0, 8.0], [2.0, 0.0, 1.0, 1.0], [1.5, 2.5, 1.0, 0.0]] n = 4 m = (x%1).eq(0).all?(-1) m &= x.sum(-1).eq(n) p x[m.where,true]100. Compute bootstrapped 95% confidence intervals for the mean of a 1D array X (i.e., resample the elements of an array with replacement N times, compute the mean of each sample, and then compute percentiles over the means). (★★★)
Python:
# Author: Jessica B. Hamrick X = np.random.randn(100) # random 1D array N = 1000 # number of bootstrap samples idx = np.random.randint(0, X.size, (N, X.size)) means = X[idx].mean(1) confint = np.percentile(means, [2.5, 97.5]) print(confint)Ruby:
x = Numo::DFloat.new(100).rand_norm n = 1000 # number of bootstrap samples idx = Numo::Int32.new(n, x.size).rand(x.size) means = x[idx].mean(1) confint = means[means.sort_index[means.size/100.0*Numo::DFloat[2.5, 97.5]]] p confint # todo: percentile