2017-02-28 82 views
0

我想要使用numpy.ix_和來自生成器表達式的索引序列獲取NumPy ndarray的子矩陣。在下面的玩具例子,爲什麼這不工作:使用生成器表達式獲取NumPyndarray的子​​矩陣

import numpy as np 

m = np.arange(25).reshape((5, 5)) 
ind = (i for i in range(0, 6, 2)) 
m[np.ix_(ind, ind)] 

ValueError: Cross index must be 1 dimensional,反之,使用列表理解:

ind = [i for i in range(0, 6, 2)] 
m[np.ix_(ind, ind)] 

產生預期的結果:

array([[ 0, 2, 4], 
     [10, 12, 14], 
     [20, 22, 24]]) 
+0

因爲'np.ix_'不接受生成器。你可以簡單地使用'np.arange()'來產生你的索引。 – Kasramvd

+0

我明白了。我不能使用'np.arange',因爲我的索引需要理解語法,所以我只需要使用列表理解 – harryscholes

+0

只是切片? 'm [:6:2,:6:2]' – f5r5e5d

回答

1

焦點僅在ix_步驟;這裏是完整的錯誤信息:

In [255]: ind = (i for i in range(0, 6, 2)) 
In [256]: np.ix_(ind, ind) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-256-920b314f7f36> in <module>() 
----> 1 np.ix_(ind, ind) 

/usr/local/lib/python3.5/dist-packages/numpy/lib/index_tricks.py in ix_(*args) 
    75   new = asarray(new) 
    76   if new.ndim != 1: 
---> 77    raise ValueError("Cross index must be 1 dimensional") 
    78   if new.size == 0: 
    79    # Explicitly type empty arrays to avoid float default 

ValueError: Cross index must be 1 dimensional 

它將每個輸入對象變成一個數組。這與工作很好,輸入已經是一個數組,或者是一個列表。但用發生器表達式:

In [257]: np.asarray(ind) 
Out[257]: array(<generator object <genexpr> at 0xae9e28fc>, dtype=object) 

我們得到一個0d對象數組。它不會將生成器擴展到列表中。這是你的工作。

In [258]: np.ix_(list(ind), list(ind)) 
Out[258]: 
(array([[0], 
     [2], 
     [4]]), array([], shape=(1, 0), dtype=int32)) 

糟糕 - 第二個索引是空的,形狀(1,0)!任何猜測爲什麼?

ix_的主要目的是爲輸入添加適當的尺寸,以便它們正確播出。

In [259]: np.ix_([0,2,4],[1,2,3]) 
Out[259]: 
(array([[0], 
     [2], 
     [4]]), array([[1, 2, 3]])) 

索引與將從索引完全不同與

x[[0,2,4], [1,2,3]] 

一個返回一個(3,3)陣列,另一個是(3,)陣列。

生成器在數組中使用得並不多。我們通常使用整數數組。生成器用於對列表進行懶惰評估,或者更確切地說是幾層列表。