2015-07-21 4 views
1

У меня массивный набор данных 4D, распределенный по 4 переменным, x_list, y_list, z_list и i_list. Каждый из них представляет собой список N скаляров с X, Y и Z, представляющими положение точки в пространстве, и я представляю интенсивность.Самый эффективный способ удаления записей в списке

У меня уже есть функция, которая выбирает и отмечает незначительные точки (те, чья интенсивность слишком низкая) для удаления, путем установки их интенсивности на 0. Однако, когда я запускаю это на своем 2-миллионном наборе точек, удаление процесс занимает несколько часов.

В настоящее время я использую команду .pop (index) для удаления точек данных, потому что это делает это очень чисто. Вот код:

counter = 0 
i = 0 
for entry in i_list 
    if (i_list[i] == 0): 
     x_list.pop(i) 
     y_list.pop(i) 
     z_list.pop(i) 
     i_list.pop(i) 
     counter += 1 
     print (counter, "points removed") 
    else 
     i += 1 

Как я могу сделать это более эффективно?

+0

Прежде всего, как вы перебираете списки? – NightShadeQueen

+2

Вторая вещь вторая. Не используйте 'print', пока цикл через 2 миллиона точек установлен. , что 80% этого времени потребляется при печати. ​​И поп - не лучшее решение. Почему бы не '.remove()' или просто 'del x_list [i]'? – Laszlowaty

+1

Возможно, вам стоит подумать о NumPy. обработка больших двухмерных матриц, что и есть то, что вы действительно h пр. –

ответ

5

Я думаю, что будет быстрее создавать новые пустые списки для каждого существующего списка и добавлять элементы к ним, если i_list[i] != 0. Просмотрите time complexity операций, которые вы делаете, и вы увидите, что удаление элементов - O (n), а добавление - O (1). В настоящее время вы делаете лот из O (n) удаляет с довольно большим n, который будет очень медленным.

Так что-то вроде:

new_x = [] 
new_y = [] 
new_y = [] 
new_i = [] 

for index in range(len(i_list)): 
    if i_list[index] != 0: 
     new_x.append(x_list[index]) 
     new_y.append(y_list[index]) 
     # Etc. 

Идя дальше, вы должны смотреть на numpy массивы, где Подменю найти множество элементов, где i_list != 0 бы очень быстро.

+0

Я писал точно такой же ответ. Удаление элемента - '' 'O (n)' '', поэтому удаление элемента в цикле - '' 'O (n ** 2)' '' – mrorno

1

Вы должны использовать del:

array = [1, 2, 3] 
del array[0] 

дает: [2, 3]

И самое главное, используя print() в то время как перекручивание через большой файл самоубийство. Большая часть времени используется при печати. Вот пример:

>>> from time import time 
>>> def test1(n): 
...  for i in range(n): 
...    print(i) 
... 
>>> def test2(n): 
...  for i in range(n): 
...    i += 1 
... 
>>> def wraper(): 
...  t1 = time() 
...  test1(1000) 
...  t2 = time() 
...  test2(1000) 
...  t3 = time() 
...  print("Test1: %s\ntest2: %s: " % (t2-t1, t3-t2)) 

И выход:

(lots of numbers) 
Test1: 0.46030712127685547 
test2: 0.0: 
+0

'del' может быть немного быстрее, чем' pop', но оба по-прежнему собираются O (n) - с 2 миллионами предметов, которые будут очень медленными. Вероятно, вы правы, что печать немного замедляет работу. – Marius

0

Это работа для счастливого списка понимания!

x_prime_list = [x for (index, x) in enumerate(x_list) 
        if i_list[index] != 0] 

Какие пары вверх члены x_list с их порядковым адрес с помощью enumerate(). Это ставит все членам x в новом списке, тогда и только тогда, когда i_list[index] не равен нуль (в противном случае он ничего не добавляет к списку.

преимущества, что списковые имеет более эквивалентный код вы публикуемый в том, что перекручивание и добавление обрабатывается на C, а не требуется Python для выполнения этих задач.

Смежные вопросы