从Numpy数组中删除列的有效方法?

时间:2013-12-14 07:23:26

标签: python arrays numpy slice

如果我有一个非常大的numpy数组和一个无用的列,我怎么能删除而不用创建原始数组的副本?

np.delete(my_np_array, 0, 1)

上面的代码将返回没有第零列的数组副本。但我想简单地从my_np_array删除该列,因为我不需要它。对于非常大的数据集,内存管理变得很重要,复制可能不是一种选择。

3 个答案:

答案 0 :(得分:4)

如果内存是主要问题,你可以做的是在数组中移动列,使得不需要的列位于数组的最末端,然后使用ndarray.resize,它就地修改了数组,将其缩小并丢弃外柱。

你不能简单地使用提供的API就地删除数组的第一列,我怀疑是因为memory layout of an ndarray将多维索引映射到连续内存块内的单维面向字节寻址。

以下示例将最后一列复制到第一列,然后删除最后一列(现在不需要),立即清除相关内存。因此,它基本上会从内存中完全删除过时的列,但代价是更改列顺序。

D1, D2 = A.shape
A[:, 0] = A[:, D2-1] 
A.resize((D1, D2-1), refcheck=False)
A.shape  
# => would be (5, 4) if the shape was initially (5, 5) for example

答案 1 :(得分:3)

如果您使用切片numpy,则不会复制;换句话说

a = numpy.array([1, 2, 3, 4, 5])
b = a[1:]  # view elements from second to last, NOT making a copy
b[0] = 12  # Change first element of `b`, i.e. second of `a`
print a

将回复[1, 12, 3, 4, 5]

如果您需要删除中间的元素,则单个切片不会起作用。

答案 2 :(得分:0)

Numpy数组是不可变的。因此,如果不创建中间副本,则无法重新调整大小。 How to remove specific elements in a numpy array 创建一个带切片的视图,并制作一份副本可能是你能做的最快的。

In [804]: a = np.ones((2,2))

In [805]: a
Out[805]:
array([[ 1.,  1.],
       [ 1.,  1.]])

In [806]: np.resize(a,(3,2))
Out[806]:
array([[ 1.,  1.],
       [ 1.,  1.],
       [ 1.,  1.]])

In [807]: a  <- a should now be resized if it was done inplace? 
Out[807]:
array([[ 1.,  1.],
       [ 1.,  1.]])