2015-05-14 142 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'的數據結構對於它們上的快速線性代數運算是理想的。這意味着你需要從一個元素到下一個元素的不斷跨步(這可以通過基本的分片來實現)。藉助高級索引,您可以從一個元素到下一個元素都有一個非常量的步幅。 –