我的代码大约需要两个小时来处理。瓶颈在for循环中,如果 语句(参见代码中的注释)。 我是python的初学者:)有人能推荐一种高效的python方法来替换嵌套的for和if语句吗?在
我有大约3000万行的表格,每行都有(x,y,z)值:
20.0 11.3 7
21.0 11.3 0
22.0 11.3 3
...
我想要的输出是一个表格,格式为x,y,min(z),count(min(z))。最后 列是(x,y)处最少z值的最终计数。例如:
20.0 11.3 7 7
21.0 11.3 0 10
22.0 11.3 3 1
...
只有大约600个唯一的坐标,所以输出表将是600x4。 我的代码:
import numpy as np
file = open('input.txt','r');
coordset = set()
data = np.zeros((600,4))*np.nan
irow = 0
ctr = 0
for row in file:
item = row.split()
x = float(item[0])
y = float(item[1])
z = float(item[2])
# build unique grid of coords
if ((x,y)) not in coordset:
data[irow][0] = x
data[irow][1] = y
data[irow][2] = z
irow = irow + 1 # grows up to 599
# lookup table of unique coords
coordset.add((x,y))
# BOTTLENECK. replace ifs? for?
for i in range(0, irow):
if data[i][0]==x and data[i][1]==y:
if z > data[i][2]:
continue
elif z==data[i][2]:
ctr = ctr + 1
data[i][3]=ctr
if z < data[i][2]:
data[i][2] = z
ctr = 1
data[i][3]=ctr
编辑:作为参考,@Joowani的方法在1m26s内计算。我原来的方法,相同的计算机,相同的数据文件,106m23s。 编辑2:@Ophion和@Sibster感谢您的建议,我没有足够的信用度来提供+1个有用的答案。在
要在numpy中执行此操作,请使用
np.unique
。在首先让我们检查一个小数组:
^{pr2}$看起来不错!现在让我们检查一个大数组:
在我的机器上需要大约33秒的时间和3GB的内存,在内存中为大型阵列执行这些操作可能是您的瓶颈。作为参考,@Joowani的解决方案花费了大约130秒,尽管这有点像苹果和橘子的比较,因为我们从一个numpy数组开始。你的身份可能不同。在
要以numpy数组的形式读入数据,我将查看问题here,但它应该类似于以下内容:
从一个txt文件加载那么多的数据,我真的推荐使用这个链接中的
pandas
示例。在您的解决方案看起来很慢,因为它会在每次更新时迭代列表(即数据)。更好的方法是使用字典,它在每次更新时取O(1)而不是O(n)。在
以下是我使用字典的解决方案:
为什么不把最后一个if改成elif呢?在
与现在一样,您将在循环的每个迭代中计算
z < data[i][2]:
。在您甚至可以用else替换它,因为您已经选中了},所以剩下的唯一可能就是
if z>data[i][2]
和{z < data[i][2]:
因此,下面的代码也可以做到这一点,而且速度应该更快:
相关问题 更多 >
编程相关推荐