Ваша попытка использования apply_along_axis
сбивает с толку, но я думаю, что вы пытаетесь это сделать:
Один набор сэмплов из pop
:
In [110]: pop = list('abcdefgijklm')
In [111]: np.random.choice(pop, size=7, replace=False)
Out[111]: array(['g', 'm', 'f', 'l', 'c', 'i', 'k'], dtype='<U1')
приведен как функция, котораяпринимает size
в качестве аргумента:
In [112]: f = lambda s: np.random.choice(pop, size=s, replace=False)
Простая итерация Python, генерирующая выборки разного размера:
In [113]: [f(i) for i in [3,5,4]]
Out[113]:
[array(['j', 'b', 'l'], dtype='<U1'),
array(['l', 'e', 'k', 'm', 'b'], dtype='<U1'),
array(['k', 'm', 'j', 'b'], dtype='<U1')]
Но чтобы создать массив выборок, size
необходимото же самое, поэтому мы можем сделать:
In [114]: np.array([f(7) for _ in range(3)])
Out[114]:
array([['a', 'f', 'm', 'd', 'e', 'l', 'j'],
['i', 'g', 'f', 'b', 'j', 'e', 'l'],
['j', 'm', 'k', 'i', 'l', 'a', 'b']], dtype='<U1')
Но так как вы настаиваете на использовании apply_along_axis
, вот способ:
In [122]: A = np.full((5,1), 7)
In [123]: np.apply_along_axis(f, 1, A)
Out[123]:
array([['c', 'm', 'a', 'f', 'i', 'd', 'k'],
['j', 'm', 'k', 'd', 'b', 'l', 'g'],
['b', 'f', 'i', 'm', 'c', 'l', 'k'],
['k', 'f', 'd', 'l', 'b', 'c', 'g'],
['l', 'f', 'j', 'k', 'g', 'a', 'd']], dtype='<U1')
Он передаст np.array([7])
в f
5 раз и собрать результаты в массив.Временами эта версия apply
немного медленнее, чем моя итерация [113]
.
Чтобы передать pop
в качестве параметра, мы должны определить func1d
, например:
In [135]: f = lambda s, a: np.random.choice(a, s, replace=False)
In [136]: np.apply_along_axis(f, 1, A, a=pop)
Out[136]:
array([['j', 'd', 'b', 'f', 'c', 'l', 'k'],
['d', 'c', 'e', 'j', 'm', 'k', 'i'],
['l', 'g', 'j', 'k', 'e', 'f', 'a'],
['a', 'l', 'e', 'm', 'b', 'c', 'j'],
['j', 'e', 'g', 'f', 'l', 'd', 'a']], dtype='<U1')
apply_along_axis
может быть полезно, когда A
имеет значение 3d (или больше), и вы хотите применить функцию к одной оси и выполнить итерации по другим.Проще применить, чем:
for i in range...:
for j in range ...:
res[i,j,:] = func1d(A[i,j,:])
, но вы создаете двумерный массив (n, 1), просто вы можете выполнить итерацию по первой оси, передав 2-ю ось (размер 1) функции.Итерация по массиву (n,) концептуально и вычислительно проще.