[英]How to improve the speed of splitting a list?
我只是想提高拆分列表的速度。现在我有一种拆分列表的方法,但是速度不如我预期的快。
def split_list(lines):
return [x for xs in lines for x in xs.split('-')]
import time
lst= []
for i in range(1000000):
lst.append('320000-320000')
start=time.clock()
lst_new=split_list(lst)
end=time.clock()
print('time\n',str(end-start))
例如, Input
:
lst
['320000-320000', '320000-320000']
Output
:
lst_new
['320000', '320000', '320000', '320000']
我对拆分的速度不满意,因为我的数据包含很多列表。
但是现在我不知道是否有更有效的方法来做到这一点。
根据建议,我尝试更具体地描述我的整个问题。
import pandas as pd
df = pd.DataFrame({ 'line':["320000-320000, 340000-320000, 320000-340000",
"380000-320000",
"380000-320000,380000-310000",
"370000-320000,370000-320000,320000-320000",
"320000-320000, 340000-320000, 320000-340000",
"380000-320000",
"380000-320000,380000-310000",
"370000-320000,370000-320000,320000-320000",
"320000-320000, 340000-320000, 320000-340000",
"380000-320000",
"380000-320000,380000-310000",
"370000-320000,370000-320000,320000-320000"], 'id':[1,2,3,4,5,6,7,8,9,10,11,12],})
def most_common(lst):
return max(set(lst), key=lst.count)
def split_list(lines):
return [x for xs in lines for x in xs.split('-')]
df['line']=df['line'].str.split(',')
col_ix=df['line'].index.values
df['line_start'] = pd.Series(0, index=df.index)
df['line_destination'] = pd.Series(0, index=df.index)
import time
start=time.clock()
for ix in col_ix:
col=df['line'][ix]
col_split=split_list(col)
even_col_split=col_split[0:][::2]
even_col_split_most=most_common(even_col_split)
df['line_start'][ix]=even_col_split_most
odd_col_split=col_split[1:][::2]
odd_col_split_most=most_common(odd_col_split)
df['line_destination'][ix]=odd_col_split_most
end=time.clock()
print('time\n',str(end-start))
del df['line']
print('df\n',df)
Input
:
df
id line
0 1 320000-320000, 340000-320000, 320000-340000
1 2 380000-320000
2 3 380000-320000,380000-310000
3 4 370000-320000,370000-320000,320000-320000
4 5 320000-320000, 340000-320000, 320000-340000
5 6 380000-320000
6 7 380000-320000,380000-310000
7 8 370000-320000,370000-320000,320000-320000
8 9 320000-320000, 340000-320000, 320000-340000
9 10 380000-320000
10 11 380000-320000,380000-310000
11 12 370000-320000,370000-320000,320000-320000
Output
:
df
id line_start line_destination
0 1 320000 320000
1 2 380000 320000
2 3 380000 320000
3 4 370000 320000
4 5 320000 320000
5 6 380000 320000
6 7 380000 320000
7 8 370000 320000
8 9 320000 320000
9 10 380000 320000
10 11 380000 320000
11 12 370000 320000
你可以把数量line
(如320000-32000
代表路线的出发点和归宿)。
Expected
:使代码运行更快。(我不能忍受代码的速度)
'-'.join(lst).split('-')
似乎快了很多:
>>> timeit("'-'.join(lst).split('-')", globals=globals(), number=10)
1.0838123590219766
>>> timeit("[x for xs in lst for x in xs.split('-')]", globals=globals(), number=10)
3.1370303670410067
根据您要对列表执行的操作,使用生成器可能会稍快一些。
如果需要保留输出,则列表解决方案会更快。
如果您只需要遍历单词一次,则可以使用生成器来消除一些开销。
def split_list_gen(lines):
for line in lines:
yield from line.split('-')
import time
lst = ['32000-32000'] * 10000000
start = time.clock()
for x in split_list(lst):
pass
end = time.clock()
print('list time:', str(end - start))
start = time.clock()
for y in split_list_gen(lst):
pass
end = time.clock()
print('generator time:', str(end - start))
发电机解决方案始终保持约10%的速度提高。
list time: 0.4568295369982612
generator time: 0.4020671741918084
将更多工作推到Python级别以下似乎可以提供较小的加速:
In [7]: %timeit x = split_list(lst)
407 ms ± 876 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [8]: %timeit x = list(chain.from_iterable(map(methodcaller("split", "-"), lst
...: )))
374 ms ± 2.67 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
methodcaller
创建一个为您调用该函数的函数:
methodcaller("split", "-")(x) == x.split("-")
chain.from_iterable
创建一个单个迭代器,该迭代器由一组可迭代对象的元素组成:
list(chain.from_iterable([[1,2], [3,4]])) == [1,2,3,4]
map
平安返回的功能methodcaller
到您的字符串列表产生适合于扁平化列表的迭代from_iterable
。 这种更实用方法的好处是,涉及到的功能都用C语言实现,并可以在 Python对象中的数据,而不是对 Python对象工作的Python字节码的工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.