Дано 2D масив для вибірки та 2D масивіндекси (вісь 1 масиву індексів вирівнюється з осі 1 джерела та пункту призначення, а вісь 0 масиву індексу вирівнюється з віссю призначення 0 та містить індекси вихідного масиву) Як я можу створити масив призначення без ітерації над одним двох осей?
Хочете скопіювати цей результат без пітонових ітерацій:
wid = 10
hig = 5
ix_ct = 2
src = np.arange(wid*hig, dtype=float).reshape((hig, wid))
dst = np.empty((ix_ct, wid), dtype=float)
ix = np.random.random_integers(0, hig-1, (ix_ct, wid))
for i in range(ix.shape[1]):
j = ix[:,i]
dst[:,i] = src[j,i]
Відповіді:
2 для відповіді № 1Все, що вам потрібно - це дати src
2-й індексаційний масив, що відповідає (мудрому мовлення) ix
:
src[ix,np.arange(ix.shape[1])]
наприклад,
array([[ 40., 31., 42., 23., 34., 25., 6., 37., 18., 9.],
[ 40., 21., 12., 43., 4., 25., 46., 17., 38., 29.]])
Щоб пояснити, придумайте 2d-індексний масив, iy
, такої ж форми, як ix
, але з i
значення з вашої ітерації:
In [72]: iy=np.array([np.arange(10),np.arange(10)])
In [75]: iy
Out[75]:
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
In [76]: src[ix,iy]
Out[76]:
array([[ 40., 31., 42., 23., 34., 25., 6., 37., 18., 9.],
[ 40., 21., 12., 43., 4., 25., 46., 17., 38., 29.]])
http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#integer-array-indexing Документи для міжряддя "розширеного" індексування
0 для відповіді № 2
Просто індексуйте відповідним чином. Створіть матрицю i з таким же розміром, як ix та бажаною поведінкою для другого індексу, і numpy буде правильно її обробляти.
import numpy as np
wid = 10
hig = 5
ix_ct = 2
src = np.arange(wid*hig, dtype=float).reshape((hig, wid))
dst = np.empty((ix_ct, wid), dtype=float)
ix = np.random.random_integers(0, hig-1, (ix_ct, wid))
# old
for i in range(ix.shape[1]):
j = ix[:,i]
dst[:,i] = src[j,i]
# new
i = np.tile(np.arange(ix.shape[1]),(ix.shape[0],1))
dst2 = src[ix,i]
print dst
print dst2