如何加速python执行
我有一个文本文件,有4623行,条目的形式为0和1的字符串(例如01010111)。我正在一个字符一个字符地比较它们。我有几个字符串长度为1001000和10000的数据集。计算1000需要25小时,计算10000需要60小时。有没有办法加快速度?我尝试使用多处理库,但它只是复制值。也许我用错了。代码:如何加速python执行,python,python-3.x,Python,Python 3.x,我有一个文本文件,有4623行,条目的形式为0和1的字符串(例如01010111)。我正在一个字符一个字符地比较它们。我有几个字符串长度为1001000和10000的数据集。计算1000需要25小时,计算10000需要60小时。有没有办法加快速度?我尝试使用多处理库,但它只是复制值。也许我用错了。代码: f = open("/path/to/file/file.txt", 'r') l = [s.strip('\n') for s in f] f.close() for a in range(
f = open("/path/to/file/file.txt", 'r')
l = [s.strip('\n') for s in f]
f.close()
for a in range(0, len(l)):
for b in range(0, len(l)):
if (a < b):
result = 0
if (a == b):
result = 1
else:
counter = 0
for i in range(len(l[a])):
if (int(l[a][i]) == int(l[b][i]) == 1):
counter += 1
result = counter / 10000
print((a + 1), (b + 1), result)
f=open(“/path/to/file/file.txt”,“r”)
l=[s.strip('\n')表示f中的s]
f、 关闭()
对于范围(0,len(l))内的a:
对于范围(0,len(l))内的b:
如果(a
我是python新手,所以我认为这段代码需要一些优化。任何帮助都是好的。提前感谢。基本知识
当两个字符串都是1时,您的计数方式非常慢。下面是一个简单的例子:
In [24]: a = '1010' * 2500
In [25]: b = '1100' * 2500
In [27]: def test1():
counter = 0
for i in range(len(a)):
if int(a[i]) == int(b[i]) == 1:
counter += 1
return counter
In [28]: %timeit test1()
100 loops, best of 3: 4.07 ms per loop
将其与将1和0的字符串表示为位进行比较:
In [29]: aba = bitarray(a)
In [30]: bba = bitarray(b)
In [31]: def test2():
....: return (aba & bba).count()
....:
In [32]: %timeit test2()
100000 loops, best of 3: 1.99 µs per loop
这要快2045倍。所以问题不是如何加速python,而是“我应该使用什么样的数据结构?”
较大规模
使用和一个包含10000行(100行1和0)的文件,这不是最坏的情况,但是:
In [22]: from bitarray import bitarray
In [23]: testdata = open('teststrs.txt')
In [24]: l = [bitarray(line.rstrip()) for line in testdata]
In [25]: len(l)
Out[25]: 10000
In [26]: len(l[0])
Out[26]: 100
In [27]: combs = combinations(l, 2)
In [28]: %time res = [(a & b[:len(a)]).count() for a, b in combs]
CPU times: user 1min 14s, sys: 396 ms, total: 1min 15s
Wall time: 1min 15s
或使用产品,如示例代码中所示:
In [30]: from itertools import product
In [31]: prod = product(l, repeat=2)
In [32]: %time res = [(a & b[:len(a)]).count() for a, b in prod]
CPU times: user 2min 51s, sys: 628 ms, total: 2min 52s
Wall time: 2min 51s
注意:
我跳过了您处理的结果,因为您尚未打开它,并且它包含死代码:
if a == b:
将永远不会为真
,因为在前面,如果您检查a
。我认为你有缩进或逻辑错误,意思是:
if a < b:
result = 0
elif a == b:
result = 1
else:
counter = 0
for i in range(len(l[a])):
if (int(l[a][i]) == int(l[b][i]) == 1):
counter += 1
result = counter / 10000
print((a + 1), (b + 1), result)
注意,我作弊并跳过了切片b
。移动所有内存的成本非常高,切片可以创建新的拷贝:
In [43]: %time res = [(a & b[:len(a)]).count() for a, b in prod]
CPU times: user 29min 40s, sys: 676 ms, total: 29min 41s
Wall time: 29min 40s
因此,如果您事先知道最大位宽度,或者甚至根据数据计算它,我认为用零填充较短的位数组,然后进行整个“计数1”是有益的:
这里teststrs.txt由4623个1'和0'的混合长度(100、1000或10000的随机选择)字符串组成。试图找出
如果a
实际上意味着你在寻找组合,而不是产品,这两个嵌套for循环目前正在做。因为你的字符串是1和0,尽管很长,这听起来像是位域和按位and的工作。这里的队长:pypy或threading |飞走了你到底在找什么?现在唯一真正的输出是计数器
,它的行为有点奇怪(最初我认为它是计算每对匹配的1位的数量,但它不是),而且你甚至不打印或存储。你到底想实现什么?既然你做了if(int(l[a][I])==int(l[b][I])==1:
在您的代码中,当两个字符串都包含'1'
时,这一点实际上是正确的,我假定您确实想计算1,尽管您说“逐字符比较”。因为bitarray具有更快的功能,bitdiff
。它需要以稍微不同的方式处理不同长度的输入,但仍然与当前的答案处于相同的范围内。非常感谢。这对理解我的问题很有帮助。
In [43]: %time res = [(a & b[:len(a)]).count() for a, b in prod]
CPU times: user 29min 40s, sys: 676 ms, total: 29min 41s
Wall time: 29min 40s
In [18]: def test():
with open('teststrs.txt') as testdata:
lines = [line.strip() for line in testdata]
max_len = max(map(len, lines))
l = [bitarray(line.ljust(max_len, '0')) for line in lines]
prod = product(l, repeat=2)
return [(a & b).count() for a, b in prod]
....:
In [19]: %timeit test()
1 loops, best of 3: 43.9 s per loop