使用内置的pandas groupby从所述指标列表中提取的指标

时间:2016-05-06 17:44:00

标签: python pandas group-by

我有一个数据框,我必须计算一系列按数据框中某些列分组的指标。我想用循环来做这个,但我似乎无法弄清楚如何(如果有正确的方法)。

所以,我正在尝试做的基本上是(半伪代码,由于显而易见的原因,这不会运行):

df = pd.DataFrame({'ID': ['A', 'B', 'A', 'C', 'B', 'C', 'A'],
                   'Score': range(7)})

group = df.groupby('ID')
for stat in ['mean', 'min', 'max']:
    group.stat()

如果我使用numpygetattr,我可以使用此功能。即:

for stat in ['mean', 'min', 'max']:
    df.groupby('ID').apply(getattr(np, stat))

这个问题是它比使用内置的.mean()等要慢得多.pandas提供了(至少对于我正在使用的大小数据帧)。

有没有更合适的方法来实现这一目标?

2 个答案:

答案 0 :(得分:0)

<强>更新

import shapeless.ops.function.FnToProduct

def oneCallback[CS <: HList, A <: HList, C](callbacks: CS)(implicit 
  ocb: OneCallback[CS, A],
  ftp: FnToProduct.Aux[C, A => Unit]
): C => Unit = c => ocb(callbacks).apply(ftp(c))

旧答案:

val cb = oneCallback(f1 _ :: f2 :: HNil)
cb { (i, s) => println(s * i) }
// f1
// f2
// foofoofoofoofoo

答案 1 :(得分:0)

这是一个自定义分组函数,它接受一个数据框,一个您想要分组的列列表,一个您想要聚合的列列表,以及一个应用于这些列的函数列表: / p>

import re
import numpy as np
import pandas as pd

# Sample data.
np.random.seed(0)
df = pd.DataFrame(np.random.randn(5, 3), columns=list('ABC'))
df['labels'] = ['a'] * 3 + ['b'] * 2
>>> df
          A         B         C labels
0  1.764052  0.400157  0.978738      a
1  2.240893  1.867558 -0.977278      a
2  0.950088 -0.151357 -0.103219      a
3  0.410599  0.144044  1.454274      b
4  0.761038  0.121675  0.443863      b

# Custom function.
def group_agg(df, groupby, columns=None, funcs=None):
    if not funcs:
        funcs = sum
    if not columns:
        columns = df.columns
    gb = df.groupby(groupby)
    dfs = []
    func_names = [re.findall(r'>?function (\w*)', str(foo))[0] for foo in funcs]
    for col in columns:
        col_names = (col + "_" + name for name in func_names)
        names_func_dict = {col_name: foo for col_name, foo in zip(col_names, funcs)}
        dfs.append(gb[col].agg(names_func_dict))
    return pd.concat(dfs, axis=1)

# Example result.
>>> group_agg(df, groupby=['labels'], funcs=[sum, np.mean], columns=['A', 'B'])
           A_sum    A_mean    B_mean     B_sum
labels                                        
a       4.955034  1.651678  0.705453  2.116358
b       1.171636  0.585818  0.132859  0.265719

有一个正则表达式语句来获取函数名称。

>>> [str(foo) for foo in funcs]
['<built-in function sum>', '<function mean at 0x108f86ed8>']

>>> [re.findall(r'>?function (\w*)', str(foo))[0] for foo in funcs]
['sum', 'mean']

然后将这些名称连接到列,字典理解将这些名称映射到函数。

例如,对于列A,这是names_func_dict

的内容
{'A_mean': <function numpy.core.fromnumeric.mean>, 
 'A_sum': <function sum>}

然后将此词典传递给groupby[coll].agg()函数。