如何加快熊猫数据框迭代
Posted
技术标签:
【中文标题】如何加快熊猫数据框迭代【英文标题】:How to speed up pandas dataframe iteration 【发布时间】:2021-09-17 14:51:01 【问题描述】:我们在项目中使用了 pandas 数据框,我们意识到由于 pandas 数据框的计算速度很慢,我们的程序非常慢。我与你分享了我们的代码。
df_item_in_desc = pd.DataFrame(columns = df.columns) # to hold all satisfied results
for index in df.shape[0]:
s1 = set(df.iloc[index]['desc_words_short'])
if item_number in s1:
df_item_in_desc = df_item_in_desc.append(df.iloc[index])
我们检查项目名称是否在另一列 desc_words_short
中,然后我们将该行附加到另一个数据框 (df_item_in_desc
)。这是一个简单的逻辑,但要获得这样的行,我们应该遍历所有数据帧并检查该条件。我们的数据框有点大,运行此代码需要更多时间。我们怎样才能加快这个过程,我们可以在这个任务中使用Cpu parallelization
,还是别的什么?
注意:我们实际上尝试过 Cpu 并行化,但不会成功。
【问题讨论】:
你运行它的机器的内存是多少,你最大的数据集的大小是多少? Ram 为 8 GB,我们的数据集中有大约 100000 个样本。实际上我们的数据集的大小不到 100 MB,并没有那么大。 你能举一个你的数据的例子吗?项目有多多样化?您可以尝试首先为每列构建一组项目,以避免在每次迭代时必须遍历所有行。但请注意,实现目标的各种策略的效率会因数据的性质而有很大差异。 @mozway 感谢您的回复。实际上变量item_number
保存项目的名称,列 desc_words_short
保存字符串列表,我们想检查项目名称是否在列 desc_words_short
中。
好的,但这并没有解决关于数据类型的问题。根据您是否有很多不同的项目、许多相似的项目、重复项目等,将改变尝试解决问题的方式。由于您的目标是优化速度,我认为如果不提供数据集,您将无法获得体面的响应。
【参考方案1】:
所以看起来您正在遍历每一行并查看desc_words_short
列的值。对于每个值,如果该值(可能是一个列表)包含item_number
,那么您希望将该行添加到df_item_in_desc
。
如果这是目标,您可以像这样加快速度:
import pandas as pd
item_number = 'a'
df = pd.DataFrame('desc_words_short':[['a','a','b'],['b','d'],['c','c']])
print(df)
desc_words_short
0 [a, a, b]
1 [b, d]
2 [c, c]
mask = df['desc_words_short'].apply(lambda x: item_number in x)
df_item_in_desc = df.loc[mask]
print(df_item_in_desc)
desc_words_short
0 [a, a, b]
我不确定set
的意义是什么,因为item_number
会在完整列表或集合中,所以这是一个毫无意义的额外计算
【讨论】:
不用担心.. 很想知道实施后的速度 实际上花了几秒钟,但现在需要 0.08 s【参考方案2】:您也可以使用列表推导。我们应该避免使用df.apply
,并将其作为最后的手段。
在较大的数据集上,列表理解会更快。此处回答的基准:link。答案本身就是智慧的结晶。
引用基准:
%timeit df[df.apply(lambda x: x['Name'].lower() in x['Title'].lower(), axis=1)] %timeit df[[y.lower() in x.lower() for x, y in zip(df['Title'], df['Name'])]] 2.85 ms ± 38.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 788 µs ± 16.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
import pandas as pd
item_number = 'a'
df = pd.DataFrame('desc_words_short':[['a','a','b'],['b','d'],['c','c']])
df[[ item_number in x for x in df['desc_words_short']]]
数据框:
desc_words_short
0 [a, a, b]
1 [b, d]
2 [c, c]
输出:
desc_words_short
0 [a, a, b]
参考: https://***.com/a/54432584/6741053
【讨论】:
我认为这确实是您触摸的好点。我也会用这种方式检查。非常感谢@รยקคгรђשค的回答 @Ali 乐于助人。如果您可以比较这两种方法并在单独的答案中提供基准,那就太好了,这将对未来的访问者有所帮助。以上是关于如何加快熊猫数据框迭代的主要内容,如果未能解决你的问题,请参考以下文章