所以我有一个像下面这样的数据框。
dff = pd.DataFrame({'id':[1,1,1,1,1,2,2,2,2,2,3,3,3,3,3], 'categ':['A','A','A','B','C','A','A','A','B','C','A','A','A','B','C'],'cost':[3,1,1,3,10,1,2,3,4,10,2,2,2,4,13] })
dff
id categ cost
0 1 A 3
1 1 A 1
2 1 A 1
3 1 B 3
4 1 C 10
5 2 A 1
6 2 A 2
7 2 A 3
8 2 B 4
9 2 C 10
10 3 A 2
11 3 A 2
12 3 A 2
13 3 B 4
14 3 C 13
现在我想创建一个新的按'id'分组的数据框,并创建一个新列,如果类别 A 占成本的 50%,类别 B 占成本的 30%,则返回 True,否则返回 False。我所需的输出如下。
new
id
1 True
2 False
3 False
我已经尝试了一些东西,但是我无法使其工作。您有任何关于如何获得所需输出的想法吗?谢谢。
答案 0 :(得分:1)
首先尝试使用数据框的 pivot_table()方法,然后检查列A
, B
, C
是否满足条件:
import numpy as np
dff.pivot_table('cost', 'id', 'categ', aggfunc='sum')\
.assign(new = lambda df: np.isclose(df.A, 0.5 * df.C) & np.isclose(df.B, 0.3 * df.C))
categ A B C new
id 1 5 3 10 True
2 6 4 10 False
3 6 4 13 False
答案 1 :(得分:1)
使用 pd.crosstab
进行交叉表格操作,并应用一些数学运算。注意:由于浮点数,我们不能使用相等符号,需要使用 np.isclose
来判断是否接近。
s = pd.crosstab(df['id'], df['categ'], df['cost'],aggfunc='sum',normalize = 'index')
s['new'] = np.isclose(s.values.tolist(),[0.5/1.8,0.3/1.8,1/1.8],atol=0.0001).all(1)
s
输出结果:
categ A B C new
id
1 0.277778 0.166667 0.555556 True
2 0.300000 0.200000 0.500000 False
3 0.260870 0.173913 0.565217 False