2017-02-28 81 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,)阵列。

生成器在数组中使用得并不多。我们通常使用整数数组。生成器用于对列表进行懒惰评估,或者更确切地说是几层列表。