考虑如下数据框:
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。
答案 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