【问题标题】:Why is get_group so slow in pandas?为什么大熊猫的 get_group 这么慢?
【发布时间】:2014-08-14 13:05:19
【问题描述】:

我有一个包含 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.6s。

为了澄清,对于我的 csv 中的每一行,我必须根据前几行创建一些统计信息。我的 csv 包含足球数据,其中包含主队、客队、全场得分、每种结果的赔率等列。

一个例子是找出主队的平均进球数。

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

【问题讨论】:

  • Groupby 仅定义您是否喜欢组的描述,它不会执行任何分组。数据是否最初排序?

标签: python pandas


【解决方案1】:

您必须出示数据来证明这一点。 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

【讨论】:

  • 我注意到你提到的关于第一次迭代的完全相同的事情。基本上,我正在寻找基于某些列过滤项目的最快方法。
  • 不清楚您要做什么。请更新您的问题。
  • 获取组非常慢,不像@Jeff所说。简单地按值过滤 DataFrame 会快得多!
【解决方案2】:

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

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 倍的加速。此外,过滤是按列值而不是分组访问行的正确方法!

【讨论】:

    【解决方案3】:

    而不是使用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 函数,但计算速度更快。

    【讨论】:

      猜你喜欢
      • 2018-05-24
      • 2020-01-31
      • 1970-01-01
      • 2019-11-22
      • 1970-01-01
      • 2021-09-03
      • 2017-05-05
      • 2016-09-28
      • 2020-02-08
      相关资源
      最近更新 更多