2012-08-12 67 views
3

这是使用numpy。这里有趣的是接近需要的东西;更新子矩阵视图d可以更新在背衬基质:如何制定一个numpy子矩阵视图数组d作为1D矩阵而不是2D

a = array([[0, 0, 0, 0, 0], 
[0, 0, 1, 0, 0], 
[0, 1, 0, 0, 0], 
[0, 0, 0, 0, 0], 
[0, 0, 0, 0, 0]]) 

print a 

array([[0, 0, 0, 0, 0], 
[0, 0, 1, 0, 0], 
[0, 1, 0, 0, 0], 
[0, 0, 0, 0, 0], 
[0, 0, 0, 0, 0]]) 

d = a[1:4,1:4] 

print d 

array([[0, 1, 0], 
[1, 0, 0], 
[0, 0, 0]]) 

d[1,1]=9 

print a 

array([[0, 0, 0, 0, 0], 
[0, 0, 1, 0, 0], 
[0, 1, 9, 0, 0], 
[0, 0, 0, 0, 0], 
[0, 0, 0, 0, 0]]) 

这大时,出现9所述背衬阵列中,正如我所希望的。

确定这里是蹭 - 现在如果需要,而不是一个二维,而是一个一维矩阵视图数组d或d的一些视图dd,形成一维矩阵,你怎么做?以下没有做到这一点。

dd = d.reshape(9) 

print dd 

array([0, 1, 0, 1, 9, 0, 0, 0, 0]) 

dd[7]=7 

print dd 

array([0, 1, 0, 1, 9, 0, 0, 7, 0]) 

print a 

array([[0, 0, 0, 0, 0], 
[0, 0, 1, 0, 0], 
[0, 1, 9, 0, 0], 
[0, 0, 0, 0, 0], 
[0, 0, 0, 0, 0]]) 

我曾希望看到7出现在支持数组a。 请注意,没有要求将d子矩阵视图限制为2D - 首先将d子矩阵视图的1D定义为完美精细公式 (如果存在这种情况)。

回答

3

我想你可能会发现flat方法有用。由于jterrace已经指出,d使用的内存不是连续的,所以d不能以通常的方式重新定型。但是,flat方法不返回数组 - 它返回一个numpy.flatiter对象,它有点像Python迭代器,但它允许索引访问和赋值,就像常规数组一样。

>>> d = a[1:4,1:4] 
>>> dd = d.flat 
>>> dd[7] = 7 
>>> a 
array([[0, 0, 0, 0, 0], 
     [0, 0, 1, 0, 0], 
     [0, 1, 0, 0, 0], 
     [0, 0, 7, 0, 0], 
     [0, 0, 0, 0, 0]]) 
+0

工程很好。完美解决方案感谢您的帮助!我的下一个研究领域是否是numpy.flatiter继续操作,就好像它是向量数学表达式中的真正的一维数组一样。 – 2012-08-13 11:21:46

3

如果你想创建一个视图,你应该分配给.shape属性而不是调用.reshape。如果您阅读numpy.reshape的注释部分,您将会看到,在不复制的情况下创建数组视图并非总是可行。看会发生什么,当我与.shape,而不是运行代码:

>>> import numpy as np 
>>> a = np.array([[0, 0, 0, 0, 0], 
... [0, 0, 1, 0, 0], 
... [0, 1, 0, 0, 0], 
... [0, 0, 0, 0, 0], 
... [0, 0, 0, 0, 0]]) 
>>> d = a[1:4,1:4] 
>>> d.shape 
>>> d.shape = (9,) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: incompatible shape for a non-contiguous array 

这不工作的原因是因为你创建的视图片是不连续的。如果numpy无法有效地维护其底层存储机制中的给定数据,则.reshape函数会创建一个副本。

2

你的问题是dd = d.reshape(9) - 创造一个复制d,而不是重新形鉴于d

尝试:

d = a[1:4, 1:4] # updates reflected in a 
d[1, 1] = 9  # updates reflected in a 
d.itemset(7, 7) # 7th element regardless of dimensions 
# or for multiple updates 
np.put(d, [7, 3], [7, 9999]) 
print a