我有一个二维的numpy
数组。是否有一种方式可以创建一个视图,其中包括前k
行和所有列?
关键是要避免复制底层数据(该数组非常大,因此无法进行部分复制)。
当然,只需像平常一样索引即可。例如:y = x[:k, :]
这将返回原始数组的一个视图。不会复制任何数据,并且对y
所做的任何更新将反映在x
中,反之亦然。
编辑:
我通常使用超过10GB的3D uint8数组,所以我非常担心这个... 如果你记住一些要点,Numpy在内存管理方面可以非常高效。 以下是一些避免在内存中复制数组的技巧:
使用+=
、-=
、*=
等操作符避免复制数组。例如,x += 10
会就地修改数组,而x = x + 10
会复制它并进行修改。(还可以看看numexpr)
如果你确实想用x = x + 10
复制一个数组,请注意x = x + 10.0
会导致x
自动向上转换为浮点数组(如果它还不是的话)。但是,如果x
是整数数组,则x += 10.0
会将10.0
下转换为与数组相同精度的整数。
此外,许多numpy函数都可以使用out
参数,因此您可以像这样进行操作:np.abs(x, x)
就地取x
的绝对值。
第二个编辑,以下是有关numpy数组视图和副本的几个提示:
与Python列表不同,y = x [:]
不返回副本,而是返回视图。 如果您确实需要副本(这当然会将您使用的内存量加倍),请使用 y = x.copy()
。y = x[[0, 1, 2], :]
返回一个副本,而y = x[:3,:]
将返回一个视图。x [4: 100: 5,:-10:-1,None]
这样的非常规索引也是"normal indexing",并且将返回一个视图,因此不要害怕在大型数组上使用各种切片技巧。
x.astype(<dtype>)
将返回数据的新类型的副本,而x.view(<dtype>)
将返回一个视图。1.0
将被视为64位整数4607182418800017408
,如果将其视为uint8,则为[0, 0, 0, 0, 0, 0, 240, 63]
的数组。 这在需要对大型数组进行位操作时非常方便...您可以低级别地控制内存缓冲区的解释方式。
x[np.array([1, 1, 3, 1])] += 1
会修改x
感到困惑。现在我明白了! - tnq177b
是a
的一个视图(view),那么b.base is a
会返回True
。任何数组的拷贝(copy)都会使得arr_copy.base is None
成立。 - Jürg W. Spaak