在pandas的手册中,有关于索引的示例:
In [653]: criterion = df2['a'].map(lambda x: x.startswith('t'))
In [654]: df2[criterion]
Run Code Online (Sandbox Code Playgroud)
然后韦斯写道:
**# equivalent but slower**
In [655]: df2[[x.startswith('t') for x in df2['a']]]
Run Code Online (Sandbox Code Playgroud)
谁能在这里解释一下为什么地图方法更快?这是一个python功能还是这是一个熊猫功能?
DSM*_*DSM 22
关于为什么某种"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
Run Code Online (Sandbox Code Playgroud)
让我们比较它们制作索引对象所花费的时间 - 无论是a Series还是a list- 以及使用该对象索引到索引所需的时间DataFrame.例如,可能是制作列表很快但在将其用作索引之前,需要将其内部转换为a Series或者某种ndarray东西,因此会增加额外的时间.
首先,对于一个小框架:
>>> 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
Run Code Online (Sandbox Code Playgroud)
在这种情况下,listcomp是最快的.实际上,这实际上并没有让我感到惊讶,因为通过a lambda可能比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
Run Code Online (Sandbox Code Playgroud)
现在,map当用作指数时似乎赢了,虽然差别很小.但不是那么快:如果我们手动将listcomp转换成一个array或一个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
Run Code Online (Sandbox Code Playgroud)
现在listcomp又赢了!
结论:谁知道?但是,如果没有timeit结果,永远不要相信任何事情,即使这样,你也要问你是否在测试你认为自己的样子.
| 归档时间: |
|
| 查看次数: |
5220 次 |
| 最近记录: |