озадачен тем, как нарезать массив - PullRequest
4 голосов
/ 31 января 2012

m - это ndarray с формой (12, 21, 21), теперь я хочу взять только его разреженный фрагмент, чтобы сформировать новый 2D-массив, с

sliceid = 0
indx    = np.array([0, 2, 4, 6, 8, 10])

, чтобы sparse_slice это, интуитивно,

sparse_slice = m[sliceid, indx, indx]

, но, очевидно, вышеописанная операция не работает, в настоящее время я использую

sparse_slice = m[sliceid,indx,:][:, indx]

, почему не работает первый "интуитивный" способ?и есть ли более компактный способ, чем мое текущее решение?все мои предыдущие испытания нарезки ndarray были основаны только на интуиции, может быть, сейчас я перейду к чтению какого-нибудь серьезного руководства ...

Ответы [ 2 ]

5 голосов
/ 31 января 2012

Более компактный способ сделать new = m[0, :12:2, :12:2]. Это то, что в numy docs называется «базовое индексирование», что означает, что вы срезаете с целым числом или объектом среза (то есть 0: 12: 2). При использовании базовой индексации Numpy возвращает представление исходного массива. Например:

In [3]: a = np.zeros((2, 3, 4))

In [4]: b = a[0, 1, ::2]

In [5]: b
Out[5]: array([ 0.,  0.])

In [6]: b[:] = 7

In [7]: a
Out[7]: 
array([[[ 0.,  0.,  0.,  0.],
        [ 7.,  0.,  7.,  0.],
        [ 0.,  0.,  0.,  0.]],

       [[ 0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.]]])

В вашем "интуитивном" подходе вы индексируете массив другим массивом. Когда вы индексируете пустой массив с другим массивом, массивы должны быть одинакового размера (или они должны транслироваться друг против друга, подробнее об этом за секунду). В документах это называется необычной индексацией или расширенной индексацией. Например:

In [10]: a = np.arange(9).reshape(3,3)

In [11]: a
Out[11]: 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

In [12]: index = np.array([0,1,2])

In [13]: b = a[index, index]

In [14]: b
Out[14]: array([0, 4, 8])

Вы видите, что я получаю [0,0], a [1,1] и a [2,2], а не [0,0], a [0,1] ... Если вы хотите «Внешнее произведение» индекса с индексом вы можете сделать следующим образом.

In [22]: index1 = np.array([[0,0],[1,1]])

In [23]: index2 = np.array([[0,1],[0,1]])

In [24]: b = a[index1, index2]

In [25]: b
Out[25]: 
array([[0, 1],
       [3, 4]])

Существует сокращение для выполнения вышесказанного, например:

In [28]: index = np.array([0,1])

In [29]: index1, index2 = np.ix_(index, index)

In [31]: index1
Out[31]: 
array([[0],
       [1]])

In [32]: index2
Out[32]: array([[0, 1]])

In [33]: a[index1, index2]
Out[33]: 
array([[0, 1],
       [3, 4]])

In [34]: a[np.ix_(index, index)]
Out[34]: 
array([[0, 1],
       [3, 4]])

Вы заметите, что index1 это (2, 1), а index2 это (1, 2), а не (2, 2). Это потому, что два массива транслируются друг против друга, вы можете узнать больше о трансляции здесь . Помните, что когда вы используете необычную индексацию, вы получаете копию исходных данных, а не представление. Иногда это лучше (если вы хотите оставить исходные данные без изменений), а иногда это просто занимает больше памяти. Подробнее об индексировании здесь .

2 голосов
/ 31 января 2012

Если я не ошибаюсь, для ввода m = np.array(range(5292)).reshape(12,21,21) вы ожидаете вывод sparse_slice = m[sliceid,indx,:][:, indx] из

array([[  0,   2,   4,   6,   8,  10],
       [ 42,  44,  46,  48,  50,  52],
       [ 84,  86,  88,  90,  92,  94],
       [126, 128, 130, 132, 134, 136],
       [168, 170, 172, 174, 176, 178],
       [210, 212, 214, 216, 218, 220]])

В этом случае вы можете получить его, используя step часть среза:

m[0, :12:2, :12:2]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...