从numpy.array中删除多个项目而不使用numpy.delete

时间:2014-10-28 15:34:36

标签: python arrays numpy

我使用大型nump.narray(11.000x3180)来开发主动学习算法(文本挖掘)。在这个算法中,我必须删除我的数据集中的每个itarecion 16样本(行向量),然后将它们集成到训练集中(每次迭代增长16个样本)。执行此过程60次(大约)后,算法再次初始化,并从头开始再次进行100次运行

要删除数据集中的16个元素集,我使用该方法 numpy.delete (dataset [ListifoIndex], axis = 0),其中[ListifoIndex]对应于要删除的所选项目的索引。

此方法适用于第一次运行(100个中的1个),但随后再次初始化算法,我有以下错误:

new = empty(newshape, arr.dtype, arr.flags.fnc)
MemoryError

显然numpy.delete metod为每个索引(16x1.2GB)创建了一个数据库副本,这超出了我在计算机上的内存量。

问题是:我如何从numpy.narray中删除项目而不是使用大量内存并且没有过多的执行时间?

PD1:我已完成了相反的过程,我在其中添加了不在索引列表中删除的元素,但过程非常慢。 PD2:有时在初始化算法之前(在迭代次数60之前)发生错误

3 个答案:

答案 0 :(得分:2)

确切了解np.delete的作用可能会有所帮助。在你的情况下

newset = np.delete(dataset, ListifoIndex, axis = 0)  # corrected

实质上它确实:

keep = np.ones(dataset.shape[0], dtype=bool) # array of True matching 1st dim
keep[ListifoIndex] = False
newset = dataset[keep, :]

换句话说,它构造了一个它想要保留的行的布尔索引。

如果我跑

dataset = np.delete(dataset, ListifoIndex, axis = 0)

在交互式shell中反复出现,没有任何中间数组的累积。暂时运行delete时,会有keep数组和dataset的新副本。但是通过作业,旧版本就会消失。

你是否确定delete增加了内存使用量,而不是增加训练集?

至于速度,你可以通过保持一个“面具”来改善它。所有'删除'行,而不是实际删除任何东西。但是,根据ListifoIndex与先前删除重叠的方式,更新该掩码可能比它值得更麻烦。它也可能更容易出错。

答案 1 :(得分:1)

我知道这是旧的,但我遇到了同样的问题,想在这里分享修复。如果您说numpy.delete保留数据库的副本,但它不是numpy,而是python本身,那么您就是正确的。

假设您从数据库中随机选择一行作为训练集的一部分。 python不是取行,而是接受行的引用,并在下次想要使用该行时保留整个数据库。这样,当您从旧数据库中删除该行时,您将创建一个新数据库,您可以在其中选择另一行。该数据库也会被保存,因为它被引用为训练集中的下一行。 100次迭代后,您最终得到100个数据库副本,每个副本的行数比最后一个少,但包含相同的数据。

我发现的解决方案不是将行附加到训练集,而是使用copy.deepcopy制作副本以从阵列中拉出行并将其放入训练集中。这样python就不需要携带旧数据库以供参考。

不好 -

database = [0,1,2,3,4,5,6]
Train = []
for i in range(len(database)):
    Train.append(database[i])

好 -

for i in range(len(database)):
    copy_of_thing = copy.deepcopy(database[i])
    Train.append(copy_of_thing)

答案 2 :(得分:0)

如果订单不满足,您可以将行交换删除到数组的末尾:

import numpy as np

n = 1000
a = np.random.rand(n, 8)
a[:, 0] = np.arange(n)
del_index = np.array([10, 100, 200, 500, 800, 995, 997, 999])
del_index2 = del_index[del_index < len(a) - len(del_index)]

copy_index = np.arange(len(a) - len(del_index), len(a))
copy_index2 = np.setdiff1d(copy_index, del_index)
a[copy_index2], a[del_index2] = a[del_index2], a[copy_index2]

然后您可以使用切片创建新视图:

    a2 = a[:-len(del_index)]

如果您想保留订单,可以使用循环和切片复制:

import numpy as np

n = 1000
a = np.random.rand(n, 8)
a[:, 0] = np.arange(n)
a2 = np.delete(a, del_index, axis=0)
del_index = np.array([100, 10, 200, 500, 800, 995, 997, 999])
del_index.sort()

for i, (start, end) in enumerate(zip(del_index[:-1], del_index[1:])):
    a[start-i:end-1-i] = a[start+1:end]

print np.all(a[:-8] == a2)