按列分组

时间:2015-10-19 23:22:07

标签: python pandas

考虑如下数据框:

In [11]: s = pd.date_range('2015-01', '2015-03', freq='5D')  # DatetimeIndex

In [12]: pd.Series(1, index=s).resample('M', how='count')
Out[12]:
2015-01-31    7
2015-02-28    5
2015-03-31    1
Freq: M, dtype: int64

假设我们要构建另一个数据框,对于 A B C 0 foo b1 25 1 foo b2 400 2 foo b3 75 3 bar b1 100 4 bar b2 200 6 baz b2 100 7 baz b3 100 定义的每个组,包含A的每个值C所代表的分数。

也就是说,使用上面的例子,结果将是:

B

要了解原因,请注意,对于行 A B C 0 foo b1 0.050000 1 foo b2 0.800000 2 foo b3 0.150000 3 bar b1 0.333333 4 bar b2 0.666667 6 baz b2 0.500000 7 baz b3 0.500000 ,我们有0等。

尝试:

尝试1:

(25 + 400 + 75)/500 = 0.05

我最终得到:df.groupby('A').transform(lambda x: x['C'].sum())

尝试2:当我尝试TypeError: cannot concatenate a non-NDFrame object时,我几乎得到了我需要的东西:

apply

唯一缺少的是> df.groupby('A').apply(lambda x: x['C']/x['C'].sum()).reset_index() A level_1 C 0 bar 3 0.333333 1 bar 4 0.666667 2 baz 6 0.500000 3 baz 7 0.500000 4 foo 0 0.050000 5 foo 1 0.800000 6 foo 2 0.150000 列是"丢失"。

尝试3:如果我要将B的结果分配到新列:

apply

我得到:df['D'] = df.groupby('A').apply(lambda x: x['C']/x['C'].sum())

我能做些什么来准确获得我需要的输出?这就是Python 3.5上的Pandas 0.17。

2 个答案:

答案 0 :(得分:5)

您可以使用transform,其“回放”汇总结果:

In [11]: df.groupby("A")["C"].transform("sum")
Out[11]:
0    500
1    500
2    500
3    300
4    300
6    200
7    200
dtype: int64

并除以(并将此列分配回C):

In [12]: df["C"] / df.groupby("A")["C"].transform("sum")
Out[12]:
0    0.050000
1    0.800000
2    0.150000
3    0.333333
4    0.666667
6    0.500000
7    0.500000
dtype: float64

答案 1 :(得分:1)

扩展@AndyHayden的响应,只需将结果分配给新列:

def triangle(n):  
    for i in range(n):  
        tri = n  
        for j in range(n-i):  
            tri = tri * 10 - n  
        print tri  

如果您不介意丢失原始数据,也可以覆盖原始列:

df['C_pct'] = df.C / df.groupby("A")["C"].transform("sum")

>>> df
     A   B    C     C_pct
0  foo  b1   25  0.050000
1  foo  b2  400  0.800000
2  foo  b3   75  0.150000
3  bar  b1  100  0.333333
4  bar  b2  200  0.666667
6  baz  b2  100  0.500000
7  baz  b3  100  0.500000