python - 为什么列表理解比在熊猫中应用更快
问题描述
使用列表推导比普通的 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 中的这些物理循环有什么区别呢?
解决方案
推荐阅读
- javascript - 第三方库如何与 ES6 模块一起工作?
- javascript - 数据验证来自不同值列表的多项选择
- sql-server - 带有立即更新的事务复制 - 发布者触发器在立即更新时触发,或者不复制它们的修改
- sql-server - 由于主键约束导致的 T-SQL 存储过程异常
- neo4j - 我似乎无法缩短查询时间
- javascript - 语义 UI + 未定义数据的反应问题
- python - Python - 同一类中的函数参数类类型
- python - 比较 Pandas 中的当前行和上一行
- database - 如何从文本框保存到 WPF VB.net 中的 MSAccess 数据库记录
- c# - 这两种方法的行为是否相同?