Pandas按条件分组后进行减法运算

5

我想基于条件减法创建一个新列。我希望首先根据A列对数据框进行分组,然后取B值最小的行的C值,并从C列中的所有值中减去该值。

import pandas as pd

data = [
["R", 1, 2],
["R", 2, 4],
["R", 3, 6],
["R", 4, 8],
["S", 0, 5],
["S", 1, 4],
["S", 2, 1],
["S", 3, 3]]
df = pd.DataFrame(data=data, columns=["a", "b", "c"])
df

Out[1]:
    a   b   c
0   R   1   2
1   R   2   4
2   R   3   6
3   R   4   8
4   S   0   5
5   S   1   4
6   S   2   1
7   S   3   3

我希望您能返回列“d”的值,该列来自以下内容:
Out[2]:
    a   b   c    d
0   R   1   2    0
1   R   2   4    2
2   R   3   6    4
3   R   4   8    6
4   S   0   5    0
5   S   1   4   -1
6   S   2   1   -4
7   S   3   3   -2

有没有一些优雅的Python方式来做这件事?

谢谢。

3个回答

5

使用

In [591]: df['d'] = df['c'] - df.loc[df.groupby('a')['b'].transform('idxmin'), 'c'].values

In [592]: df
Out[592]:
   a  b  c  d
0  R  1  2  0
1  R  2  4  2
2  R  3  6  4
3  R  4  8  6
4  S  0  5  0
5  S  1  4 -1
6  S  2  1 -4
7  S  3  3 -2

只是验证你的 (-: 检查通过。 - piRSquared
df.assign(d=df.c - df.groupby('a').b.transform(lambda d: df.c[d.idxmin()])) 这个怎么样? - piRSquared
在小数据上,时间差不多。只有风格上的区别。 - piRSquared
在我的当前情况下,lambda 版本(即注释)似乎比您 (@piRSquared) 发布的 map 答案和被接受的答案慢了约3倍。 - E.Eisbrenner

5
conditional_c = df.groupby('a').b.idxmin().map(df.c)
df.assign(d=df.c - df.a.map(conditional_c))

   a  b  c  d
0  R  1  2  0
1  R  2  4  2
2  R  3  6  4
3  R  4  8  6
4  S  0  5  0
5  S  1  4 -1
6  S  2  1 -4
7  S  3  3 -2

1
不够高效,但可以工作。
df['d']=df.groupby('a').apply(lambda x : x['c']-x['c'][x['b']==x['b'].min()].values).values
df
Out[1305]: 
   a  b  c  d
0  R  1  2  0
1  R  2  4  2
2  R  3  6  4
3  R  4  8  6
4  S  0  5  0
5  S  1  4 -1
6  S  2  1 -4
7  S  3  3 -2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接