【问题标题】:Pandas: Difference to previous value熊猫:与先前值的差异
【发布时间】:2016-10-21 21:31:06
【问题描述】:

给定一个看起来像这样的 Pandas 数据框

GROUP   VALUE    MASK
  1        5     false
  2       10     false
  2       20     false
  1        7     true
  3        17    false
  3        18    false
  1        100   false
  1        200   true

对于 MASK 为真的每一行,我想获得与该组中前一个值的差异,即结果应该是

VALUE DIFF
  7      2
  200  100

如何在 Pandas 中计算?

对于具有大约 200 万行和 100 万组的大型数据框,我如何才能快速计算?

【问题讨论】:

  • 回应下面的速度评论:确保您使用的是更新版本的 pandas,因为 groupby 的速度已经有了很大的改进。除此之外,如果您要对同一子集进行重复计算,您可能会考虑对数据进行子集化。

标签: python pandas


【解决方案1】:

其实瓶颈是groupby。对于这个特定问题,您实际上不需要使用groupby。通过GROUPsort 数据帧执行diff 对排序后的数据帧执行filter MASK 应该没问题。我们必须使用kind='mergesort'来保持组内排序前后顺序不变,

假设每组的第一个元素的MASK总是False(因为第一个元素对差分运算没有意义),你可以使用这个

pd.concat([df.VALUE, df.sort_values(by="GROUP", kind='mergesort').VALUE.diff()], axis=1, keys=['VALUE', 'DIFF'])[df.MASK]

性能测试:

MAXN = 200000
GROUPS = 10000
df = pd.DataFrame({"GROUP": np.ceil(np.random.rand(MAXN)*GROUPS), "VALUE": np.ceil(np.random.rand(MAXN)*10000), "MASK":np.floor(np.random.rand(MAXN)*2).astype("bool")})

%timeit t1 = pd.concat([df.VALUE, df.groupby('GROUP').VALUE.diff()], axis=1, keys=['VALUE', 'DIFF'])[df.MASK]
# 1 loop, best of 3: 1.28 s per loop

%timeit t2 = pd.concat([df.VALUE, df.sort_values(by="GROUP", kind='mergesort').VALUE.diff()], axis=1, keys=['VALUE', 'DIFF'])[df.MASK]
#10 loops, best of 3: 63.1 ms per loop

#MAXN = 2000000
#GROUPS = 1000000
%timeit t2 = pd.concat([df.VALUE, df.sort_values(by="GROUP", kind='mergesort').VALUE.diff()], axis=1, keys=['VALUE', 'DIFF'])[df.MASK]
#1 loop, best of 3: 1.24 s per loop

【讨论】:

  • 这需要超过 10 秒,所以我没有等待结果:P.
  • 很公平,我看到您只是在显示问题中指定的行数和组数的时间。好答案!
【解决方案2】:

使用groupbydiff'MASK'

pd.concat([df.VALUE, df.groupby('GROUP').VALUE.diff()],
          axis=1, keys=['VALUE', 'DIFF'])[df.MASK]

【讨论】:

  • df.groupby('GROUP').VALUE.diff() 这一步似乎真的很慢。有没有办法加快速度?
猜你喜欢
  • 1970-01-01
  • 2016-11-14
  • 1970-01-01
  • 2013-08-13
  • 1970-01-01
  • 1970-01-01
  • 2017-12-30
  • 2015-03-26
相关资源
最近更新 更多