根据条件替换分组后的值。

时间:2021-08-12 04:12:11

标签: python pandas dataframe group-by pandas-groupby

所以我有一个像下面这样的数据框。

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

我已经尝试了一些东西,但是我无法使其工作。您有任何关于如何获得所需输出的想法吗?谢谢。

2 个答案:

答案 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