【发布时间】:2019-08-12 17:10:57
【问题描述】:
我想知道是否有人可以提供有关 python 的本机数据容器与 Pandas DataFrame 的速度/性能的任何输入 - 即执行子字符串查找。
几个月前,我发布了一个与操作有关的问题 (Performing a substring lookup between one dataframe and another)。本质上,我有一个名称列表(DataFrame 中的一列,长度> 2mm),并且想“标记”那些包含来自单独的粗俗单词列表(长度> 3000)的子字符串的名称。呈现给我的解决方案效果很好,我认为它是 DataFrame 最有效的选择。
然而,从那时起,我开始创建一个包含进度条的 GUI(使用 PyQt5)。进度条的问题是我需要某种形式的迭代来确定完成的进度百分比。此时,我将代码更改为仅使用本机 python 可迭代对象(没有 Pandas DataFrame),并在 forloop 中进行操作,让我有一个确定的进度条。
我认为这会慢得多,因为知道 DataFrame 的性能优势来自于向量化操作的能力。然而,令我惊讶的是,使用 python 的迭代方法约为 15%。
这是什么原因? pandas 方法是否没有真正矢量化,并且仍在幕后执行一些循环?或者与 DataFrame 相比,列表/集合/生成器是否更轻量级和更快?
这是我的两种方法的代码:
Pandas DataFrame 实现
import pandas as pd
df = pd.read_csv(source_file, names = ['ID', 'Fullname'])
vulgars = [line for line in open(vulgar_lookup_file, 'r')]
df['Vulgar Flag'] = df['Fullname'].str.contains('|'.join(vulgars))
原生 Python 迭代方法
vulgars = set(line for line in open(vulgar_lookup_file, 'r'))
# accessing second column of comma-delimited file (containing the fullname)
source = (line.split(',')[1] for line in open(source_file, 'r'))
vulgar_flag = []
for item in source:
result = any(substr in item for substr in vulgars)
vulgar_flag.append(result)
我知道迭代方法可以进一步简化为列表推导,它产生相同的结果比上面的 forloop 快约 12%。为了便于阅读,我只是把它放在循环形式中。
谢谢!
【问题讨论】:
-
“使用 python 的迭代方法约为 15%” 你能澄清一下迭代方法比数据框方法快 15% 还是慢 15%?
-
@SidaZhou 我的意思是它快了 15%
标签: python pandas loops dataframe iterator