Python 熊猫性能:loc与使用排序数据的前x行中的.head(x)的对比
假设我们有一个包含100000行和3列的数据框架,其结构如下:Python 熊猫性能:loc与使用排序数据的前x行中的.head(x)的对比,python,performance,pandas,dataframe,optimization,Python,Performance,Pandas,Dataframe,Optimization,假设我们有一个包含100000行和3列的数据框架,其结构如下: | visitorId | timestamp | url | 1 | 1 | 11 | A | 2 | 1 | 12 | B | 3 | 2 | 21 | A | 4 | 3 | 31 | A | 5 | 3 | 32 | C | . . n | z
| visitorId | timestamp | url |
1 | 1 | 11 | A |
2 | 1 | 12 | B |
3 | 2 | 21 | A |
4 | 3 | 31 | A |
5 | 3 | 32 | C |
.
.
n | z | Z1 | A |
此数据帧始终被排序,并存储在名为sortedData
的变量中。首先,我们将所有唯一的访问者ID提取到一个名为visitors
的列表中,并创建一个path变量来保存该访问者访问过的所有URL
visitors = sortedData.visitorId.unique()
visitors = visitors.tolist()
paths = []
visitor_length = len(visitors)
现在,我所做的是为每个访问者进入一个循环,以查找和存储每个访问者的遍历路径、时间戳和ID,并将其作为辅助算法的输入(不相关)。
我用了两种方法来做到这一点:
A:
这使用内置的pandasloc
函数查找具有匹配的visitorId
的行,并将时间戳和路径提取到列表中,最后将它们附加在一起。然后,它继续删除前x行(等于查询结果的长度,也称为匹配数),以便在以后进行类似匹配时不会遍历它们
对于访问者
列表中的每个唯一的访问者
,重复该过程
通过计时,我发现大约需要6.31秒才能完成。在我的例子中,这是一个11.7MB的文件,10万行。在1.2GB的文件上,此文件可扩展到14小时。因此,我尝试了方法B,希望加速
方式B使用数据总是被排序的逻辑,例如visitors
中的访问者1总是sortedData
中的第一个访问者,访问者2总是第二个访问者等。因此我可以使用pandasvalue\u counts()
函数来计算当前访问者的出现次数x
,使用head(x)
从第一行x
提取数据,因为它们总是匹配的。这样,它就不必每次都迭代和搜索整个数据帧。然后像以前一样,我从数据帧中删除这些行,并为下一个访问者重复循环
B:
令我惊讶的是,这使得它的运行速度几乎是a的两倍,达到10.89
秒,而a的6.31
对loc
和value\u counts()进行计时后者似乎更快,但在循环中使用时,情况正好相反
考虑到在B中,我们知道访问者的位置,我们只需要迭代数据帧的前x行,在A中,我们每次都要搜索整个数据帧,是什么导致性能上的差异
在我之前做的优化中,删除已经遍历的行时,速度提升相当可观,每次数据帧大小减半时,速度都会翻倍,而不是保留整个数据帧。这让我怀疑它每次都以某种方式遍历整个数据帧,除非我遗漏了什么
我使用的是运行在PyCharm 2018上的MacBook Pro 2014,Python 3.6.4(Anaconda)。创建自己的访客列表,反复浏览并搜索数据框并不理想
如果我正确理解你的问题,请看一看,它可以用于你的情况
要获得与现在类似的代码,可以从以下方式开始:
grouped = sortedData.groupby('visitorId')
for visitorId, group in grouped:
print(vistorId)
# your code here
custom_url_algorithm(group)
对确切地说,您每次都在这里迭代整个数据集:sortedData['visitorId']==visitor
这就解决了它!作为参考,1.2GB文件从14小时缩短到7分钟。我使用例如time=grouped.get\u group(visitorId.timestamp.tolist()
for visitor in visitors:
x = sortedData.visitorId.value_counts()[visitor]
timestamps = sortedData.timestamp.head(x).tolist()
path = sortedData.pageUrl.head(x).tolist()
paths.append((visitor, timestamps, path))
sortedData = sortedData.iloc[x:]
grouped = sortedData.groupby('visitorId')
for visitorId, group in grouped:
print(vistorId)
# your code here
custom_url_algorithm(group)