Czy jest lepszy sposób w numpy
do płytek tablicę liczbę niecałkowitą liczbę razy? To załatwia sprawę, ale jest niezgrabne i nie łatwo uogólnić na n-wymiarach:numpy.tile Niecałkowitą liczbę razy
import numpy as np
arr = np.arange(6).reshape((2, 3))
desired_shape = (5, 8)
reps = tuple([x // y for x, y in zip(desired_shape, arr.shape)])
left = tuple([x % y for x, y in zip(desired_shape, arr.shape)])
tmp = np.tile(arr, reps)
tmp = np.r_[tmp, tmp[slice(left[0]), :]]
tmp = np.c_[tmp, tmp[:, slice(left[1])]]
Daje:
array([[0, 1, 2, 0, 1, 2, 0, 1],
[3, 4, 5, 3, 4, 5, 3, 4],
[0, 1, 2, 0, 1, 2, 0, 1],
[3, 4, 5, 3, 4, 5, 3, 4],
[0, 1, 2, 0, 1, 2, 0, 1]])
EDIT: WYNIKI
Niektóre testy trzech odpowiedzi uogólnionych na n-wymiary. Definicje te zostały wprowadzone w pliku newtile.py
:
import numpy as np
def tile_pad(a, dims):
return np.pad(a, tuple((0, i) for i in (np.array(dims) - a.shape)),
mode='wrap')
def tile_meshgrid(a, dims):
return a[np.meshgrid(*[np.arange(j) % k for j, k in zip(dims, a.shape)],
sparse=True, indexing='ij')]
def tile_rav_mult_idx(a, dims):
return a.flat[np.ravel_multi_index(np.indices(dims), a.shape, mode='wrap')]
są tu linie atakujących:
python -m timeit -s 'import numpy as np' 'import newtile' 'newtile.tile_pad(np.arange(30).reshape(2, 3, 5), (3, 5, 7))'
python -m timeit -s 'import numpy as np' 'import newtile' 'newtile.tile_meshgrid(np.arange(30).reshape(2, 3, 5), (3, 5, 7))'
python -m timeit -s 'import numpy as np' 'import newtile' 'newtile.tile_rav_mult_idx(np.arange(30).reshape(2, 3, 5), (3, 5, 7))'
python -m timeit -s 'import numpy as np' 'import newtile' 'newtile.tile_pad(np.arange(2310).reshape(2, 3, 5, 7, 11), (13, 17, 19, 23, 29))'
python -m timeit -s 'import numpy as np' 'import newtile' 'newtile.tile_meshgrid(np.arange(2310).reshape(2, 3, 5, 7, 11), (13, 17, 19, 23, 29))'
python -m timeit -s 'import numpy as np' 'import newtile' 'newtile.tile_rav_mult_idx(np.arange(2310).reshape(2, 3, 5, 7, 11), (13, 17, 19, 23, 29))'
Wybrane wyniki z małych tablic (2 x 3 x 5):
pad: 10000 loops, best of 3: 106 usec per loop
meshgrid: 10000 loops, best of 3: 56.4 usec per loop
ravel_multi_index: 10000 loops, best of 3: 50.2 usec per loop
Oto wyniki z większymi tablicami (2 x 3 x 5 x 7 x 11):
pad: 10 loops, best of 3: 25.2 msec per loop
meshgrid: 10 loops, best of 3: 300 msec per loop
ravel_multi_index: 10 loops, best of 3: 218 msec per loop
Metoda z użyciem np.pad
jest prawdopodobnie najbardziej wydajnym wyborem.
Jak powinno być zachowanie podczas używania 'np.tile()' z liczbami niecałkowitymi? –
@SaulloCastro: Być może mój tytuł jest trochę mylący. Moim zdaniem 'np.tile' powinno * nie * przyjmować niecałkowite argumenty do' reps'. Co chcę osiągnąć to * analogiczne * do tego, co by się stało, gdyby 'np.tile' wziął niecałkowite argumenty do' reps' ** i ** jeśli przekazana liczba niecałkowita daje liczbę całkowitą wierszy/kolumn/etc w macierzy wyjściowej. Najbliższym analogicznym przykładem, jaki znam, jest argument "length.out" funkcji 'rep()' w języku 'R'. – drammock