我有一个大量的4D数据集,分布在4个变量中,x_list
,y_list
,z_list
和i_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
如何更有效地完成这项工作?
答案 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_list
将enumerate()
的成员与其序号地址配对。它将所有成员x
放在一个新列表中,当且仅当i_list[index]
不为零时(否则它不会向列表添加任何内容。
列表推导优于您发布的等效代码的优点是循环和追加是在C中处理的,而不是需要Python来完成这些任务。