2014-10-28 3 views
0

Я использую большой nump.narray (11.000x3180) для разработки активного алгоритма обучения (Text mining). В этом алгоритме я должен удалить каждый из них 16 образцов (векторы строк) в моем наборе данных, а затем интегрировать их в набор тренировок (он увеличивается на 16 выборок на итерацию). После выполнения этого процесса в течение 60 итераций (приблизительно), алгоритм инициализируется снова и снова тот же самый процесс с самого начала для 100 пробеговУдалите несколько элементов из numy.narray без numpy.delete

Чтобы удалить набор из 16 элементов в моем наборе данных, я использую метод numpy.delete (dataset [ListifoIndex], axis = 0), где [ListifoIndex] соответствует индексам выбранных элементов для удаления.

Этот метод работает для первого запуска (1 из 100), а затем инициализировать алгоритм снова, я следующее сообщение об ошибке:

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

Видимо numpy.delete Metod создает копию моей базы данных для каждого из индексы (16x1,2 ГБ), что превышает объем памяти, который у меня есть на моем компьютере.

вопрос: как я могу удалить элементы из numpy.narray, чтобы не использовать много памяти и без чрезмерного времени выполнения?

PD1: Я выполнил обратный процесс, где я добавляю элементы, которые не находятся в списке индексов для удаления, но процесс выполняется очень медленно. PD2: Иногда ошибка происходит до инициализации алгоритма (до итерации числа 60)

+0

@ редактировать matsjoyce был изменить язык названия с французского языка на английский. Вот политика по неанглийским вопросам: http://blog.stackoverflow.com/2009/07/non-english-question-policy/ –

+0

@BenFulton Ах, наконец! Я искал этот пост на мета. Я хочу, чтобы эти вещи были легче найти, например, в разделе справки ... – matsjoyce

ответ

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) 
+0

Я думаю, что переупорядочение строк включает в себя столько же копирования данных, сколько и их удаление. – hpaulj

+0

Я сделал это развертывание раньше, но у меня была такая же проблема с памятью. – Space

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) 

раз в интерактивной оболочке, нет каких-либо накопление промежуточных массивов. Временно во время работы delete будет этот массив keep и новая копия dataset. Но с назначением старая копия исчезает.

У вас есть delete, что увеличивает использование памяти, в отличие от растущего набора тренировок?

Что касается скорости, вы можете улучшить это, сохранив «маску» всех строк «удалить», а не фактически удаляя что-либо.Но в зависимости от того, как ListifoIndex перекрывается с предыдущими удалениями, обновление этой маски может быть больше проблем, чем того стоит. Это также, вероятно, будет более склонным к ошибкам.

+0

Что для увеличения использования памяти, я думаю, это было бы в том месте в моем коде, так как именно там всегда происходит ошибка «Ошибка памяти». Как вы указали выше, в моем случае гораздо лучше использовать только индексы для создания нового набора данных. Теперь, чтобы сделать это таким образом, среда выполнения немного увеличилась, но я определил вышеупомянутую ошибку. Теперь я реализую «маску», чтобы уменьшить время выполнения. Большое спасибо за ваши ответы. приветствует – Space

1

Я знаю, что это старый, но я столкнулся с той же проблемой и хотел поделиться этим исправлением. Вы считаете правильным, когда numpy.delete хранит копию базы данных, но это не numpy, ее python.

Скажите, что вы случайно выбираете строку из базы данных, чтобы быть частью набора для обучения. Вместо того, чтобы брать строку, python возьмет ссылку на строку и сохранит всю базу данных, когда вы захотите использовать эту строку. Таким образом, когда вы удаляете строку из старой базы данных, вы создаете новую базу данных, в которой вы можете выбрать другую строку. Эта база данных также сохраняется, потому что на нее ссылается следующая строка в наборе обучения. 100 итераций позже вы получите 100 копий базы данных, каждая из которых имеет 1 меньшую строку, чем предыдущая, но содержащую те же данные.

Решение, которое я нашел вместо добавления строки в учебный комплект, сделав копию с использованием copy.deepcopy, чтобы вытащить строку из массива и поместить ее в набор для обучения. Таким образом, python не должен переносить старую базу данных для справочных целей.

Bad -

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) 
Смежные вопросы