删除列表中条目的最有效方法

时间:2015-07-21 02:00:52

标签: python performance optimization iteration

我有一个大量的4D数据集,分布在4个变量中,x_listy_listz_listi_list。每个都是N个标量的列表,X,Y和Z代表点在空间中的位置,我代表强度。

我已经有了一个功能,通过将强度设置为0来选择并标记可忽略的点(强度太低的那些点)进行删除。但是,当我在我的200万点集上运行时,删除过程需要几个小时。

目前,我使用.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

如何更有效地完成这项工作?

3 个答案:

答案 0 :(得分:5)

我认为为每个现有列表创建新的空列表会更快,如果i_list[i] != 0将项目附加到它们。查找您正在进行的操作的time complexity,您将看到删除项目为O(n),而附加项目为O(1)。目前你正在用一个相当大的n进行O(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非常快的项集。

答案 1 :(得分: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:

答案 2 :(得分:0)

这是快乐列表理解的工作!

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

使用x_listenumerate()的成员与其序号地址配对。它将所有成员x放在一个新列表中,当且仅当i_list[index]不为零时(否则它不会向列表添加任何内容。

列表推导优于您发布的等效代码的优点是循环和追加是在C中处理的,而不是需要Python来完成这些任务。