关于为什么在 Python 中以某种方式“应该”更快的争论不能太认真,因为您经常测量在某些情况下可能表现不同的实现细节。结果,当人们猜测什么应该更快时,他们通常(通常?)是错误的。例如,我发现这map
实际上可能会更慢。使用此设置代码:
import numpy as np, pandas as pd
import random, string
def make_test(num, width):
s = [''.join(random.sample(string.ascii_lowercase, width)) for i in range(num)]
df = pd.DataFrame({"a": s})
return df
让我们比较一下它们创建索引对象(无论是 aSeries
还是 a list
)所花费的时间,以及使用该对象索引到DataFrame
. 例如,制作列表可能很快,但在将其用作索引之前,需要在内部将其转换为 aSeries
或 anndarray
或其他东西,因此在那里增加了额外的时间。
首先,对于一个小框架:
>>> df = make_test(10, 10)
>>> %timeit df['a'].map(lambda x: x.startswith('t'))
10000 loops, best of 3: 85.8 µs per loop
>>> %timeit [x.startswith('t') for x in df['a']]
100000 loops, best of 3: 15.6 µs per loop
>>> %timeit df['a'].str.startswith("t")
10000 loops, best of 3: 118 µs per loop
>>> %timeit df[df['a'].map(lambda x: x.startswith('t'))]
1000 loops, best of 3: 304 µs per loop
>>> %timeit df[[x.startswith('t') for x in df['a']]]
10000 loops, best of 3: 194 µs per loop
>>> %timeit df[df['a'].str.startswith("t")]
1000 loops, best of 3: 348 µs per loop
在这种情况下,listcomp 是最快的。老实说,这实际上并没有让我感到惊讶,因为通过 alambda
可能比str.startswith
直接使用要慢,但真的很难猜到。10 足够小,我们可能仍在测量诸如设置成本之类的东西Series
;在更大的框架中会发生什么?
>>> df = make_test(10**5, 10)
>>> %timeit df['a'].map(lambda x: x.startswith('t'))
10 loops, best of 3: 46.6 ms per loop
>>> %timeit [x.startswith('t') for x in df['a']]
10 loops, best of 3: 27.8 ms per loop
>>> %timeit df['a'].str.startswith("t")
10 loops, best of 3: 48.5 ms per loop
>>> %timeit df[df['a'].map(lambda x: x.startswith('t'))]
10 loops, best of 3: 47.1 ms per loop
>>> %timeit df[[x.startswith('t') for x in df['a']]]
10 loops, best of 3: 52.8 ms per loop
>>> %timeit df[df['a'].str.startswith("t")]
10 loops, best of 3: 49.6 ms per loop
现在看来,map
当用作索引时,它正在获胜,尽管差异很小。但不是那么快:如果我们手动将 listcomp 变成 anarray
或 a会Series
怎样?
>>> %timeit df[np.array([x.startswith('t') for x in df['a']])]
10 loops, best of 3: 40.7 ms per loop
>>> %timeit df[pd.Series([x.startswith('t') for x in df['a']])]
10 loops, best of 3: 37.5 ms per loop
现在 listcomp 再次获胜!
结论:谁知道?但是永远不要相信任何没有timeit
结果的事情,即使那样你也必须问你是否在测试你认为自己是什么。