我使用大型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之前)发生错误
答案 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)