Apakah ada cara optimal untuk mengiris setiap baris matriks di Numpy (atau Theano) dengan langkah N, diberikan indeks awal untuk setiap kolom?

Misalnya, dalam matriks A di bawah ini, indeks irisan awal untuk setiap baris diberikan di kolom pertama, dan untuk baris i, saya ingin memiliki A[i, A[0]:A[0]+stride]

A = [[1,  1,  2,  3,  4, 5, 6],
     [1,  11, 12, 13, 14, 15, 16],
     [3,  22, 23, 24, 25, 26, 27]]
stride = 2
Desired output:
[[  1.   2.   3.]
 [ 11.  12.  13.]
 [ 24.  25.  26.]]

Saya mencoba kode di bawah ini:

b = [range(A.shape[0]), A[:, 0]]
c = [range(A.shape[0]), A[:, 0] + stride]
A[b:c]

Tapi saya mendapat kesalahan berikut:

IndexError: failed to coerce slice entry of type list to integer
3
csuo 14 Maret 2017, 22:49

2 jawaban

Jawaban Terbaik

Berikut adalah pendekatan vektor yang memanfaatkan broadcasting untuk mendapatkan indeks tersebut untuk pengindeksan ke dalam kolom di setiap baris dan kemudian menggunakan NumPy's advanced-indexing untuk mengekstrak elemen-elemen di sepanjang setiap baris dengan cara vektor -

idx = A[:,0,None] + np.arange(stride+1)
out = A[np.arange(idx.shape[0])[:,None], idx]

Contoh lari -

In [273]: A
Out[273]: 
array([[ 1,  1,  2,  3,  4,  5,  6],
       [ 1, 11, 12, 13, 14, 15, 16],
       [ 3, 22, 23, 24, 25, 26, 27]])

In [274]: idx = A[:,0,None] + np.arange(stride+1)

In [275]: idx
Out[275]: 
array([[1, 2, 3],
       [1, 2, 3],
       [3, 4, 5]])

In [276]: A[np.arange(idx.shape[0])[:,None], idx]
Out[276]: 
array([[ 1,  2,  3],
       [11, 12, 13],
       [24, 25, 26]])
1
Divakar 14 Maret 2017, 20:39

Tidak yakin apakah itu optimal, tetapi setidaknya tidak menimbulkan kesalahan :)

Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>> a = numpy.array([[1,  1,  2,  3,  4, 5, 6],
...                  [1,  11, 12, 13, 14, 15, 16],
...                  [3,  22, 23, 24, 25, 26, 27]])
>>> stride = 2
>>> numpy.array(map(lambda row: row[row[0]:row[0] + stride + 1], a))
array([[ 1,  2,  3],
       [11, 12, 13],
       [24, 25, 26]])
0
Andrew Che 14 Maret 2017, 20:22