删除列表中条目的最有效方法
Most efficient way to remove entries in a list
我有一个庞大的 4D 数据集,分布在 4 个变量中,x_list
、y_list
、z_list
和 i_list
。每个都是 N 个标量的列表,X、Y 和 Z 代表点在 space 中的位置,I 代表强度。
我已经有一个功能可以通过将强度设置为 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
我怎样才能更有效地做到这一点?
我认为为每个现有列表创建新的空列表并在 i_list[i] != 0
中附加项目会更快。查找您正在执行的操作的 time complexity,您会发现删除项目是 O(n),而追加是 O(1)。当前,您正在执行 lot 的 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
所在的项目集会非常快。
你应该使用 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:
这是一个快乐列表理解的工作!
x_prime_list = [x for (index, x) in enumerate(x_list)
if i_list[index] != 0]
使用 enumerate()
将 x_list
的成员与其序号地址配对。当且仅当 i_list[index]
不为零时,它将所有成员 x
放入新列表(否则它不会向列表添加任何内容。
与您发布的等效代码相比,列表理解的优势在于循环和追加是在 C 中处理的,而不需要 Python 来完成这些任务。
我有一个庞大的 4D 数据集,分布在 4 个变量中,x_list
、y_list
、z_list
和 i_list
。每个都是 N 个标量的列表,X、Y 和 Z 代表点在 space 中的位置,I 代表强度。
我已经有一个功能可以通过将强度设置为 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
我怎样才能更有效地做到这一点?
我认为为每个现有列表创建新的空列表并在 i_list[i] != 0
中附加项目会更快。查找您正在执行的操作的 time complexity,您会发现删除项目是 O(n),而追加是 O(1)。当前,您正在执行 lot 的 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
所在的项目集会非常快。
你应该使用 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:
这是一个快乐列表理解的工作!
x_prime_list = [x for (index, x) in enumerate(x_list)
if i_list[index] != 0]
使用 enumerate()
将 x_list
的成员与其序号地址配对。当且仅当 i_list[index]
不为零时,它将所有成员 x
放入新列表(否则它不会向列表添加任何内容。
与您发布的等效代码相比,列表理解的优势在于循环和追加是在 C 中处理的,而不需要 Python 来完成这些任务。