首页 > 解决方案 > 为什么列表理解比在熊猫中应用更快

问题描述

使用列表推导比普通的 for 循环快得多。为此给出的原因是在列表推导中不需要追加,这是可以理解的。但是我在各个地方发现列表比较比应用要快。我也经历过。但无法理解是什么内部工作使它比应用快得多?

我知道这与 numpy 中的矢量化有关,这是 pandas 数据帧的基本实现。但是导致列表推导比应用更好的原因并不是很容易理解,因为在列表推导中,我们在列表中给出了 for 循环,而在 apply 中,我们甚至不提供任何 for 循环(我也假设在那里,向量化需要地方)

编辑:添加代码:这正在处理泰坦尼克数据集,其中标题是从名称中提取的: https ://www.kaggle.com/c/titanic/data

%timeit train['NameTitle'] = train['Name'].apply(lambda x: 'Mrs.' if 'Mrs' in x else \
                                         ('Mr' if 'Mr' in x else ('Miss' if 'Miss' in x else\
                                                ('Master' if 'Master' in x else 'None'))))

%timeit train['NameTitle'] = ['Mrs.' if 'Mrs' in x else 'Mr' if 'Mr' in x else ('Miss' if 'Miss' in x else ('Master' if 'Master' in x else 'None')) for x in train['Name']]

结果:每个循环 782 µs ± 6.36 µs(平均值 ± 标准偏差,7 次运行,每次 1000 个循环)

每个循环 499 µs ± 5.76 µs(7 次运行的平均值 ± 标准偏差,每次 1000 个循环)

Edit2:要为 SO 添加代码,正在创建一个简单的代码,令人惊讶的是,对于下面的代码,结果相反:

import pandas as pd
import timeit
df_test = pd.DataFrame()
tlist = []
tlist2 = []
for i in range (0,5000000):
  tlist.append(i)
  tlist2.append(i+5)
df_test['A'] = tlist
df_test['B'] = tlist2

display(df_test.head(5))


%timeit df_test['C'] = df_test['B'].apply(lambda x: x*2 if x%5==0 else x)
display(df_test.head(5))
%timeit df_test['C'] = [ x*2 if x%5==0 else x for x in df_test['B']]

display(df_test.head(5))

1 个循环,最好的 3 个:每个循环 2.14 秒

1 个循环,最好的 3 个:每个循环 2.24 秒

Edit3:正如一些人所建议的那样,apply 本质上是一个 for 循环,情况并非如此,就像我用 for 循环运行这段代码一样,它几乎永远不会结束,我不得不在 3-4 分钟后手动停止它并且它从未完成在这段时间。:

for row in df_test.itertuples():
  x = row.B
  if x%5==0:
    df_test.at[row.Index,'B'] = x*2

运行上面的代码大约需要 23 秒,但应用只需要 1.8 秒。那么,itertuples 和 apply 中的这些物理循环有什么区别呢?

标签: pythonpandaslist-comprehension

解决方案


推荐阅读