2010-12-06 89 views
77

我有一个2D numpy数组。有没有办法创建一个视图,其中包括第一个k行和所有列?查看一个numpy数组?

要点是避免复制的基础数据(数组是如此之大,使得部分拷贝是不可行的。)

回答

188

当然,只是索引它象通常那样。例如。 y = x[:k, :]这将返回原始数组的视图。没有数据将被复制,并且对y进行的任何更新都将反映在x之间,反之亦然。


编辑:

我通常与UINT8年代> 10GB 3D阵列工作,所以我不用担心这个了很多......如果你把一个几件事情与NumPy可以在内存管理非常有效。 这里是避免存储阵列的复印一些提示:

使用+=-=*=等,以避免使数组的一个副本。例如。 x += 10将修改阵列到位,而x = x + 10将复制并修改它。 (也,看看numexpr

如果你想使一个副本x = x + 10,要知道,x = x + 10.0会导致x自动进行上浇铸为浮点阵列,如果它是不是已经。但是,x += 10.0(其中x是一个整数数组)将导致10.0向下转换为与数组具有相同精度的int值。

此外,许多numpy函数需要参数out,因此您可以执行诸如np.abs(x, x)之类的操作,以取得原地的绝对值x


作为第二个编辑,这里的一对意见副本与numpy的阵列更多提示:

与Python列表,y = x[:]不返回副本,它返回一个视图。如果你确实需要一个副本(当然这会使你使用的内存量增加一倍),使用y = x.copy()

你会经常听到关于numpy数组的“花哨索引”。使用列表(或整数数组)作为索引是“幻想索引”。它可能非常有用,但可以复制数据。

作为一个例子:y = x[[0, 1, 2], :]返回一个副本,而y = x[:3,:]将返回一个视图。

即使像x[4:100:5, :-10:-1, None]这样非常疯狂的索引是“普通”索引,并且会返回一个视图,所以不要害怕在大型数组上使用各种切片技巧。

x.astype(<dtype>)将返回数据的一个副本作为新类型,而x.view(<dtype>)将返回一个视图。

但要小心,但是...它非常强大和有用,但您需要了解底层数据如何存储在内存中。如果您有一组浮点数,并将它们视为整数(反之亦然),numpy会将数组的解释为整数。

例如,这意味着1.0作为一个64位的浮动小端系统上会4607182418800017408作为64位INT观察时,如果作为UINT8观察的[ 0, 0, 0, 0, 0, 0, 240, 63]阵列。当你需要在大型数组上进行某种操作时,这是非常好的,但是......对于如何解释内存缓冲区,您有低级别的控制权。

+0

感谢您的非常好的提示!我正在阅读Numpy的用户指南,并且为什么`x [np.array([1,1,3,1])] + = 1`修改了`x`。现在明白了! – tnq177 2015-07-11 04:20:56