【发布时间】:2012-10-03 17:56:56
【问题描述】:
下文中,male_trips 是大熊猫数据框,站是小熊猫数据框。对于每个车站 ID,我想知道发生了多少次男性旅行。以下内容可以完成这项工作,但需要很长时间:
mc = [ sum( male_trips['start_station_id'] == id ) for id in stations['id'] ]
我应该怎么做呢?
更新!所以有两种主要的方法:groupby(),然后是size(),以及更简单的.value_counts()。我做了一个快速的timeit,groupby 方法以相当大的优势获胜!代码如下:
from timeit import Timer
setup = "import pandas; male_trips=pandas.load('maletrips')"
a = "male_trips.start_station_id.value_counts()"
b = "male_trips.groupby('start_station_id').size()"
Timer(a,setup).timeit(100)
Timer(b,setup).timeit(100)
结果如下:
In [4]: Timer(a,setup).timeit(100) # <- this is value_counts
Out[4]: 9.709594964981079
In [5]: Timer(b,setup).timeit(100) # <- this is groupby / size
Out[5]: 1.5574288368225098
请注意,在这种速度下,键入 value_counts 会稍微快一些,并且记忆更少!
【问题讨论】:
-
数据框有多大?你有足够的内存吗?在速度方面,我认为它没有任何问题。
-
@myusuf3 只是为了比较,我上面的方法需要一分钟多的时间(我已经厌倦了数数),而下面 Dani 的解决方案将以毫秒为单位。
-
这真的很令人惊讶,因为算法.py 中有一个特定的值计数函数,我怀疑如果它不比 groupby 和 size 快,Wes 会添加这个函数。对于刚刚加载的 DataFrame,我得到了不同的结果:在 [20] 中:timeit df.groupby(df.columns[8]).size() 100 个循环,最好的 3:每个循环 13.4 毫秒在 [22]:timeit df [df.columns[8]].value_counts() 100 次循环,最好的 3 次:每次循环 5.62 毫秒。
-
确保以多个顺序(a 在 b 之前,a 在 b 之后)多次(10 次或更多)运行计时测试。如果你只做了两次测试,可能第一次运行将数据从磁盘加载到磁盘缓冲区中,第二次运行直接从缓冲区中读取数据,从而避免了磁盘访问时间。