2015-05-14 144 views
4

我有一个大的数据矩阵x我需要分析一些子矩阵。numpy切片阵列没有复制它

我使用下面的代码来选择子矩阵:

>>> import numpy as np 
>>> x = np.random.normal(0,1,(20,2)) 
>>> x 
array([[-1.03266826, 0.04646684], 
     [ 0.05898304, 0.31834926], 
     [-0.1916809 , -0.97929025], 
     [-0.48837085, -0.62295003], 
     [-0.50731017, 0.50305894], 
     [ 0.06457385, -0.10670002], 
     [-0.72573604, 1.10026385], 
     [-0.90893845, 0.99827162], 
     [ 0.20714399, -0.56965615], 
     [ 0.8041371 , 0.21910274], 
     [-0.65882317, 0.2657183 ], 
     [-1.1214074 , -0.39886425], 
     [ 0.0784783 , -0.21630006], 
     [-0.91802557, -0.20178683], 
     [ 0.88268539, -0.66470235], 
     [-0.03652459, 1.49798484], 
     [ 1.76329838, -0.26554555], 
     [-0.97546845, -2.41823586], 
     [ 0.32335103, -1.35091711], 
     [-0.12981597, 0.27591674]]) 
>>> index = x[:,1] > 0 
>>> index 
array([ True, True, False, False, True, False, True, True, False, 
     True, True, False, False, False, False, True, False, False, 
     False, True], dtype=bool) 
>>> x1 = x[index, :] #x1 is a copy of the submatrix 
>>> x1 
array([[-1.03266826, 0.04646684], 
     [ 0.05898304, 0.31834926], 
     [-0.50731017, 0.50305894], 
     [-0.72573604, 1.10026385], 
     [-0.90893845, 0.99827162], 
     [ 0.8041371 , 0.21910274], 
     [-0.65882317, 0.2657183 ], 
     [-0.03652459, 1.49798484], 
     [-0.12981597, 0.27591674]]) 
>>> x1[0,0] = 1000 
>>> x1 
array([[ 1.00000000e+03, 4.64668400e-02], 
     [ 5.89830401e-02, 3.18349259e-01], 
     [ -5.07310170e-01, 5.03058935e-01], 
     [ -7.25736045e-01, 1.10026385e+00], 
     [ -9.08938455e-01, 9.98271624e-01], 
     [ 8.04137104e-01, 2.19102741e-01], 
     [ -6.58823174e-01, 2.65718300e-01], 
     [ -3.65245877e-02, 1.49798484e+00], 
     [ -1.29815968e-01, 2.75916735e-01]]) 
>>> x 
array([[-1.03266826, 0.04646684], 
     [ 0.05898304, 0.31834926], 
     [-0.1916809 , -0.97929025], 
     [-0.48837085, -0.62295003], 
     [-0.50731017, 0.50305894], 
     [ 0.06457385, -0.10670002], 
     [-0.72573604, 1.10026385], 
     [-0.90893845, 0.99827162], 
     [ 0.20714399, -0.56965615], 
     [ 0.8041371 , 0.21910274], 
     [-0.65882317, 0.2657183 ], 
     [-1.1214074 , -0.39886425], 
     [ 0.0784783 , -0.21630006], 
     [-0.91802557, -0.20178683], 
     [ 0.88268539, -0.66470235], 
     [-0.03652459, 1.49798484], 
     [ 1.76329838, -0.26554555], 
     [-0.97546845, -2.41823586], 
     [ 0.32335103, -1.35091711], 
     [-0.12981597, 0.27591674]]) 
>>> 

但我想X1是唯一一个指针或类似这样的东西。每次需要复制数据时,我都需要一个子矩阵。 我该怎么做?

编辑: 显然没有任何解决方案与numpy阵列。从这个角度来看,熊猫数据框架是否更好?

+0

你会'x1'成为'x'的[* view *](http://docs.scipy.org/doc/numpy-1.6.0/glossary.html#term-view),但是这个[*高级索引*]是不可能的(http://docs.scipy.org/doc/numpy-1.6.0/reference/arrays.indexing.html#advanced-indexing)。 numpy手册在[关于索引的部分]中很清楚(http://docs.scipy.org/doc/numpy-1.6.0/reference/arrays.indexing.html#advanced-indexing)。 –

+0

在评论中,您声明您正在递归地将数据传递给函数。为什么不将数据单独留在全局中并通过栈上的索引? –

+0

我认为这仍然需要一个相当于复制数据的高级索引。 – Donbeo

回答

1

的信息与您的阵列x中总结.__array_interface__财产

In [433]: x.__array_interface__ 
Out[433]: 
{'descr': [('', '<f8')], 
'strides': None, 
'data': (171396104, False), 
'typestr': '<f8', 
'version': 3, 
'shape': (20, 2)} 

它具有阵列shapestrides(默认位置),并指向数据缓冲区。 A view可指向相同的数据缓冲区(可能更远),并具有其自己的shapestrides

但是用你的布尔值建立索引不能在这几个数字中总结。要么必须一直传送index阵列,要么复制x数据缓冲区中的选定项目。 numpy选择复制。您可以选择何时应用index,现在或者下一步调用堆栈。

0

如果你可以用传统的片管理,如

x1 = x[3:8] 

那么这将是只是一个指针。

你看过使用蒙面数组吗?你可能能够做到你想要的。

x = np.array([0.12, 0.23], 
      [1.23, 3.32], 
       ... 
      [0.75, 1.23]]) 

data = np.array([[False, False], 
       [True, True], 
       ... 
       [True, True]]) 

x1 = np.ma.array(x, mask=data) 
## x1 can be worked on and only includes elements of x where data==False 
+0

我递归地将数据的子矩阵传递给一个不修改它的函数。这就是为什么我只想通过一个视图或类似的东西。 – Donbeo

+0

关键是'x [index,:]'*是一个副本。即使你没有存储对它的引用,它已经在消耗你的记忆。 –

+0

是的,我怀疑掩码会使用一些索引等复制和维护。 – paddyg

0

由于indexbool类型的数组,你正在做的高级索引。 docs说:“高级索引总是返回数据的副本。”

这很有道理。与只需要知道启动,停止和步骤的普通索引相比,高级索引可以使用原始数组中的任何值,而无需这么简单的规则。这意味着有大量额外的元信息,其中被引用的索引指向可能使用更多内存而不是副本。

+0

如果我使用'index = np.argwhere(x [:,1]> 0).ravel()'怎么办?这不是布尔值 – Donbeo

+0

它仍然是高级索引,不幸的是 – paddyg

+0

'ndarray'的数据结构对于它们上的快速线性代数运算是理想的。这意味着你需要从一个元素到下一个元素的不断跨步(这可以通过基本的分片来实现)。借助高级索引,您可以从一个元素到下一个元素都有一个非常量的步幅。 –