104

我有一个二维numpy数组。有没有办法在它上面创建一个包含第一k行和所有列的视图?

关键是要避免复制底层数据(数组太大以至于无法进行部分复制。)

4

1 回答 1

251

当然,只需像往常一样索引它。例如y = x[:k, :] ,这会将视图返回到原始数组中。不会复制任何数据,所做的任何更新都y将反映在x其中,反之亦然。


编辑:

我通常使用大于 10GB 的 uint8 3D 数组,所以我很担心这个问题……如果你记住一些事情,Numpy 在内存管理方面会非常有效。以下是避免在内存中复制数组的一些技巧:

使用+=, -=,*=等来避免复制数组。例如x += 10,将就地修改数组,同时x = x + 10复制并修改它。(另外,看看numexpr

如果您确实想使用 制作副本,请x = x + 10注意这x = x + 10.0将导致x自动向上转换为浮点数组(如果还没有的话)。但是,x += 10.0, wherex是一个整数数组,将导致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在 little-endian 系统上的 64 位浮点数在被视为 64 位 int 时将被视为 64 位 int,而如果被视为 uint8 则为4607182418800017408数组。[ 0, 0, 0, 0, 0, 0, 240, 63]但是,当您需要对大型数组进行某种位旋转时,这非常好……您可以对内存缓冲区的解释方式进行低级控制。

于 2010-12-06T21:17:52.887 回答