为什么get_group在熊猫中这么慢?

时间:2014-08-14 13:05:20

标签: python pandas

我有一个包含400,000行和15列的csv文件。我必须为每一行进行多次过滤操作。所以,我想用pandas和groupby来尝试提高性能。使用groupby很快但get_group似乎很慢。

import pandas as pd

filepath = 'data.csv'
df = pd.read_csv(filepath, sep=',', na_values=['', '-'], parse_dates=True)
groups = df.groupby(['Year', 'Team'])
team_matches = groups.get_group(('2014', 'Barcelona'))

groupby非常快。但get_group作为用于分组增加的列数变得非常慢。对于上面的例子,获得该组需要0.6秒。

为了澄清,对于我的csv中的每一行,我必须根据前面的行创建一些统计信息。我的csv有足球数据,包括家庭团队,客场团队,全时分数,每个结果的赔率。

一个例子是找到主队得分的平均目标。

goal_avg = np.average(df[(df['HOMETEAM'] == hometeam) & (df['LEAGUE'] == league)]['HOME_GOALS'])

3 个答案:

答案 0 :(得分:0)

您必须显示数据才能证明这一点。 get_group非常快。第一次迭代会进行一些缓存,但它很小(数据的排序无关紧要)

N = 1000000 

In [4]: df = DataFrame(dict(A = np.random.randint(0,1000,size=N),B=np.random.randint(0,1000,size=N),C=np.random.randn(N)))

In [5]: %timeit df.groupby(['A','B'])
10000 loops, best of 3: 84.2 µs per loop

In [6]: g = df.groupby(['A','B'])

In [7]: %timeit -n 1 g.get_group((100,100))
1 loops, best of 3: 2.86 ms per loop

此外,您不应重复使用get_group,而应使用cythonized函数,apply或迭代,请参阅文档here

答案 1 :(得分:0)

您应该使用过滤(例如get_group())来代替df[(df.Year == '2014') & (df.Team == 'Barcelona')]。这非常快,并且执行相同的操作。这是两者的详细比较。

In [1]: df = DataFrame(dict(A = np.random.randint(0,1000,size=N),B=np.random.randint(0,1000,size=N),C=np.random.randn(N)))

In [2]: %time df.groupby(['A','B'])
CPU times: user 0 ns, sys: 804 µs, total: 804 µs
Wall time: 802 µs

In [3]: g = df.groupby(['A','B'])

In [4]: %time g.get_group((100,100))
CPU times: user 1.47 s, sys: 93.8 ms, total: 1.56 s
Wall time: 1.57 s
        A   B   C
325601  100 100 1.547365
837535  100 100 -0.058478

In [5]: %time df[(df.A == 100) & (df.B == 100)]
CPU times: user 12.6 ms, sys: 317 µs, total: 12.9 ms
Wall time: 21.3 ms
        A   B   C
325601  100 100 1.547365
837535  100 100 -0.058478

这是70倍以上的速度。而且,过滤是按列值而不是groupby访问行的正确方法!

答案 2 :(得分:0)

而不是使用 get_group 方法,即:-

grouped = df.groupby("the_column_you_want")
grouped.get_group("the_group_you_want")

您可以使用:-

grouped = df.groupby("the_column_you_want")
for name,group in grouped:
  if name == "the_group_you_want":
    print(group)      

它将等同于 get_group 函数,但计算速度要快得多。