【问题标题】:Hierarchical grouping in pandaspandas 中的分层分组
【发布时间】:2016-06-14 12:48:32
【问题描述】:

如何使用 groupby 在多个级别上操作数据帧?我希望能够做类似的事情

data.groupby('col1').groupby(['col2', 'col3']).apply(foo).apply(bar)

样本数据:

    user_id year    day hour    events
0   1928375096  2015    196 0   6
1   734605009   2016    32  21  1
2   3333305045  2016    29  5   3
3   698115442   2016    30  7   11
4   685465592   2016    26  12  3
5   485945404   2016    24  10  4
6   73202588    2016    25  3   1
7   4380205067  2016    25  8   1
8   408502597   2016    32  9   1
9   584885164   2016    32  10  3

假设 col1 = user_id, col2 = 'year', col3 = 'day',所以我们每天为每个用户获取许多行(最多 24 行)。我们想首先在事件上运行 foo;例如,foo(x) = (x-x.mean())/x.std(),那么我们希望将每个用户的时间序列减少为带有bar 的标量。生成的数据框应包含每个用户一行。

【问题讨论】:

  • 相当于data.groupby(['col1', 'col2', 'col3']),不是吗?如果您发布MVCE,您将获得更多运气。
  • 函数foobar 如何输入您的公式@TomAugspurger?
  • foobar 是什么?你还没有定义它们或data
  • data是pandas DataFrame,其列包括col1、col2、col3等,foo和bar是任意函数。这个问题并不仅仅取决于这些函数的定义,因此是占位符名称。
  • 我怀疑它确实取决于功能,例如foo = bar = lambda x: return 1 :) 根据您的问题,foo 可能在其中包含 groupby。很难对一般的、模糊的问题给出一个很好的答案,而不是一次性说出所有内容然后进行操作。

标签: pandas group-by


【解决方案1】:

pandas 并没有削减它,所以我在使用 pandas 的 read_gbq 函数返回一个完整的循环之前换用了 blaze、postgres、BigQuery(数据首先来自哪里)。我不情愿地编写 SQL 查询来通过 pandas 提供 BiqQuery。我希望能够使用 DataFrame 样式的操作,但至少我跳过了中间 CSV。

【讨论】:

  • 从那以后我了解到 Google 有自己的笔记本平台,支持 BigQuery 和类似 pandas 的功能:DataLabExample notebook.
【解决方案2】:

首先,认真考虑您的问题,以确保您实际上需要嵌套 groupby。这本质上是一个嵌套的 for 循环,因此性能可能会比正常情况更快。就这样吧……

In [102]: letters = list(string.ascii_lowercase[:13])

In [103]: import string

In [104]: letters = list(string.ascii_lowercase[:13])

In [105]: N = 1000

In [106]: df = pd.DataFrame({'a': np.random.choice(letters, size=N),
                             'b': np.random.choice(letters, size=N),
                             'c': np.random.choice(letters, N),
                             'd': np.random.randn(N)})

“a”列是我们最外层的分组,即您评论中的“用户”。我们提前对其进行分组以预先计算其均值。

In [106]: means = df.groupby('a').d.mean()

然后我们处理每个组,将结果收集到一个临时列表中。

In [107]: out = []

In [108]: gr = df.groupby(['a', 'b', 'c'])

In [108]: for k, v in gr:
              demeaned = v.groupby(('b', 'c')).d.transform(lambda x: x.count() * x) - means.loc[k[0]]
              out.append(demeaned)


In [109]: df['result'] = pd.concat(out)

In [110]: df
Out[110]:
     a  b  c         d    result
0    j  a  a  0.677802  1.107368
1    d  k  e -0.538711  0.032052
2    m  m  f -0.695904 -0.644055
3    m  i  i -0.433602  1.069695
4    m  e  a -2.349382 -0.560345
..  .. .. ..       ...       ...
995  e  e  m -0.626897  1.409865
996  g  m  m  0.434375 -1.402483
997  h  g  j -0.939896  1.440304
998  j  k  m -0.473171 -0.572188
999  d  c  j  0.894530  0.392441

[1000 rows x 5 columns]

【讨论】:

    猜你喜欢
    • 2019-09-20
    • 2017-10-22
    • 1970-01-01
    • 2017-04-23
    • 2014-09-27
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    • 2015-11-01
    相关资源
    最近更新 更多